feat: refactoring project

This commit is contained in:
Carlos
2024-11-23 14:56:07 -05:00
parent f0c2a50c18
commit 1c6db5818d
2351 changed files with 39323 additions and 60326 deletions

View File

@@ -8,6 +8,7 @@
const { OriginalSource, RawSource } = require("webpack-sources");
const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
const Module = require("../Module");
const { JS_TYPES } = require("../ModuleSourceTypesConstants");
const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("../ModuleTypeConstants");
const RuntimeGlobals = require("../RuntimeGlobals");
const Template = require("../Template");
@@ -41,8 +42,6 @@ const ContainerExposedDependency = require("./ContainerExposedDependency");
/** @typedef {[string, ExposeOptions][]} ExposesList */
const SOURCE_TYPES = new Set(["javascript"]);
class ContainerEntryModule extends Module {
/**
* @param {string} name container entry name
@@ -60,7 +59,7 @@ class ContainerEntryModule extends Module {
* @returns {SourceTypes} types available (do not mutate)
*/
getSourceTypes() {
return SOURCE_TYPES;
return JS_TYPES;
}
/**
@@ -77,7 +76,7 @@ class ContainerEntryModule extends Module {
* @returns {string} a user readable identifier of the module
*/
readableIdentifier(requestShortener) {
return `container entry`;
return "container entry";
}
/**
@@ -205,7 +204,7 @@ class ContainerEntryModule extends Module {
}
const source = Template.asString([
`var moduleMap = {`,
"var moduleMap = {",
Template.indent(getters.join(",\n")),
"};",
`var get = ${runtimeTemplate.basicFunction("module, getScope", [
@@ -230,7 +229,7 @@ class ContainerEntryModule extends Module {
`if (!${RuntimeGlobals.shareScopeMap}) return;`,
`var name = ${JSON.stringify(this._shareScope)}`,
`var oldScope = ${RuntimeGlobals.shareScopeMap}[name];`,
`if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");`,
'if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");',
`${RuntimeGlobals.shareScopeMap}[name] = shareScope;`,
`return ${RuntimeGlobals.initializeSharing}(name, initScope);`
])};`,

View File

@@ -6,6 +6,7 @@
"use strict";
const createSchemaValidation = require("../util/create-schema-validation");
const memoize = require("../util/memoize");
const ContainerEntryDependency = require("./ContainerEntryDependency");
const ContainerEntryModuleFactory = require("./ContainerEntryModuleFactory");
const ContainerExposedDependency = require("./ContainerExposedDependency");
@@ -16,6 +17,10 @@ const { parseOptions } = require("./options");
/** @typedef {import("./ContainerEntryModule").ExposeOptions} ExposeOptions */
/** @typedef {import("./ContainerEntryModule").ExposesList} ExposesList */
const getModuleFederationPlugin = memoize(() =>
require("./ModuleFederationPlugin")
);
const validate = createSchemaValidation(
require("../../schemas/plugins/container/ContainerPlugin.check.js"),
() => require("../../schemas/plugins/container/ContainerPlugin.json"),
@@ -73,10 +78,12 @@ class ContainerPlugin {
}
compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => {
const hooks =
getModuleFederationPlugin().getCompilationHooks(compilation);
const dep = new ContainerEntryDependency(name, exposes, shareScope);
dep.loc = { name };
compilation.addEntry(
compilation.options.context,
/** @type {string} */ (compilation.options.context),
dep,
{
name,
@@ -86,6 +93,7 @@ class ContainerPlugin {
},
error => {
if (error) return callback(error);
hooks.addContainerEntryDependency.call(dep);
callback();
}
);

View File

@@ -7,6 +7,7 @@
const { RawSource } = require("webpack-sources");
const Module = require("../Module");
const { JS_TYPES } = require("../ModuleSourceTypesConstants");
const { WEBPACK_MODULE_TYPE_FALLBACK } = require("../ModuleTypeConstants");
const RuntimeGlobals = require("../RuntimeGlobals");
const Template = require("../Template");
@@ -31,7 +32,6 @@ const FallbackItemDependency = require("./FallbackItemDependency");
/** @typedef {import("../util/Hash")} Hash */
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
const TYPES = new Set(["javascript"]);
const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
class FallbackModule extends Module {
@@ -120,7 +120,7 @@ class FallbackModule extends Module {
* @returns {SourceTypes} types available (do not mutate)
*/
getSourceTypes() {
return TYPES;
return JS_TYPES;
}
/**

View File

@@ -5,16 +5,26 @@
"use strict";
const { SyncHook } = require("tapable");
const isValidExternalsType = require("../../schemas/plugins/container/ExternalsType.check.js");
const Compilation = require("../Compilation");
const SharePlugin = require("../sharing/SharePlugin");
const createSchemaValidation = require("../util/create-schema-validation");
const ContainerPlugin = require("./ContainerPlugin");
const ContainerReferencePlugin = require("./ContainerReferencePlugin");
const HoistContainerReferences = require("./HoistContainerReferencesPlugin");
/** @typedef {import("../../declarations/plugins/container/ModuleFederationPlugin").ExternalsType} ExternalsType */
/** @typedef {import("../../declarations/plugins/container/ModuleFederationPlugin").ModuleFederationPluginOptions} ModuleFederationPluginOptions */
/** @typedef {import("../../declarations/plugins/container/ModuleFederationPlugin").Shared} Shared */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Dependency")} Dependency */
/**
* @typedef {object} CompilationHooks
* @property {SyncHook<Dependency>} addContainerEntryDependency
* @property {SyncHook<Dependency>} addFederationRuntimeDependency
*/
const validate = createSchemaValidation(
require("../../schemas/plugins/container/ModuleFederationPlugin.check.js"),
@@ -24,6 +34,10 @@ const validate = createSchemaValidation(
baseDataPath: "options"
}
);
/** @type {WeakMap<Compilation, CompilationHooks>} */
const compilationHooksMap = new WeakMap();
class ModuleFederationPlugin {
/**
* @param {ModuleFederationPluginOptions} options options
@@ -34,6 +48,28 @@ class ModuleFederationPlugin {
this._options = options;
}
/**
* Get the compilation hooks associated with this plugin.
* @param {Compilation} compilation The compilation instance.
* @returns {CompilationHooks} The hooks for the compilation.
*/
static getCompilationHooks(compilation) {
if (!(compilation instanceof Compilation)) {
throw new TypeError(
"The 'compilation' argument must be an instance of Compilation"
);
}
let hooks = compilationHooksMap.get(compilation);
if (!hooks) {
hooks = {
addContainerEntryDependency: new SyncHook(["dependency"]),
addFederationRuntimeDependency: new SyncHook(["dependency"])
};
compilationHooksMap.set(compilation, hooks);
}
return hooks;
}
/**
* Apply the plugin
* @param {Compiler} compiler the compiler instance
@@ -61,7 +97,7 @@ class ModuleFederationPlugin {
: Object.keys(options.exposes).length > 0)
) {
new ContainerPlugin({
name: options.name,
name: /** @type {string} */ (options.name),
library,
filename: options.filename,
runtime: options.runtime,
@@ -87,6 +123,7 @@ class ModuleFederationPlugin {
shareScope: options.shareScope
}).apply(compiler);
}
new HoistContainerReferences().apply(compiler);
});
}
}

View File

@@ -7,6 +7,9 @@
const { RawSource } = require("webpack-sources");
const Module = require("../Module");
const {
REMOTE_AND_SHARE_INIT_TYPES
} = require("../ModuleSourceTypesConstants");
const { WEBPACK_MODULE_TYPE_REMOTE } = require("../ModuleTypeConstants");
const RuntimeGlobals = require("../RuntimeGlobals");
const makeSerializable = require("../util/makeSerializable");
@@ -30,7 +33,6 @@ const RemoteToExternalDependency = require("./RemoteToExternalDependency");
/** @typedef {import("../util/Hash")} Hash */
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
const TYPES = new Set(["remote", "share-init"]);
const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
class RemoteModule extends Module {
@@ -123,7 +125,7 @@ class RemoteModule extends Module {
* @returns {SourceTypes} types available (do not mutate)
*/
getSourceTypes() {
return TYPES;
return REMOTE_AND_SHARE_INIT_TYPES;
}
/**

View File

@@ -12,6 +12,7 @@ const Template = require("../Template");
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Chunk").ChunkId} ChunkId */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("./RemoteModule")} RemoteModule */
@@ -29,27 +30,31 @@ class RemoteRuntimeModule extends RuntimeModule {
const { runtimeTemplate, moduleGraph } = compilation;
/** @type {Record<ChunkId, (string | number)[]>} */
const chunkToRemotesMapping = {};
/** @type {Record<string | number, [string, string, string | number | null]>} */
/** @type {Record<ModuleId, [string, string, string | number | null]>} */
const idToExternalAndNameMapping = {};
for (const chunk of /** @type {Chunk} */ (this.chunk).getAllAsyncChunks()) {
for (const chunk of /** @type {Chunk} */ (
this.chunk
).getAllReferencedChunks()) {
const modules = chunkGraph.getChunkModulesIterableBySourceType(
chunk,
"remote"
);
if (!modules) continue;
/** @type {(string | number)[]} */
/** @type {ModuleId[]} */
const remotes = (chunkToRemotesMapping[
/** @type {ChunkId} */ (chunk.id)
/** @type {ChunkId} */
(chunk.id)
] = []);
for (const m of modules) {
const module = /** @type {RemoteModule} */ (m);
const name = module.internalRequest;
const id = chunkGraph.getModuleId(module);
const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
const shareScope = module.shareScope;
const dep = module.dependencies[0];
const externalModule = moduleGraph.getModule(dep);
const externalModuleId =
externalModule && chunkGraph.getModuleId(externalModule);
/** @type {ModuleId} */
(externalModule && chunkGraph.getModuleId(externalModule));
remotes.push(id);
idToExternalAndNameMapping[id] = [shareScope, name, externalModuleId];
}
@@ -76,12 +81,12 @@ class RemoteRuntimeModule extends RuntimeModule {
"var data = idToExternalAndNameMapping[id];",
"if(getScope.indexOf(data) >= 0) return;",
"getScope.push(data);",
`if(data.p) return promises.push(data.p);`,
"if(data.p) return promises.push(data.p);",
`var onError = ${runtimeTemplate.basicFunction("error", [
'if(!error) error = new Error("Container missing");',
'if(typeof error.message === "string")',
Template.indent(
`error.message += '\\nwhile loading "' + data[1] + '" from ' + data[2];`
"error.message += '\\nwhile loading \"' + data[1] + '\" from ' + data[2];"
),
`${
RuntimeGlobals.moduleFactories
@@ -100,7 +105,7 @@ class RemoteRuntimeModule extends RuntimeModule {
"next(result, d)",
"result"
)}, onError);`,
`if(first) promises.push(data.p = p); else return p;`
"if(first) promises.push(data.p = p); else return p;"
]),
"} else {",
Template.indent(["return next(promise, d, first);"]),
@@ -116,7 +121,7 @@ class RemoteRuntimeModule extends RuntimeModule {
"external, _, first"
)};`,
`var onInitialized = ${runtimeTemplate.returningFunction(
`handleFunction(external.get, data[1], getScope, 0, onFactory, first)`,
"handleFunction(external.get, data[1], getScope, 0, onFactory, first)",
"_, external, first"
)};`,
`var onFactory = ${runtimeTemplate.basicFunction("factory", [

View File

@@ -5,7 +5,15 @@
"use strict";
/** @template T @typedef {(string | Record<string, string | string[] | T>)[] | Record<string, string | string[] | T>} ContainerOptionsFormat */
/**
* @template T
* @typedef {Record<string, string | string[] | T>} Item
*/
/**
* @template T
* @typedef {(string | Item<T>)[] | Item<T>} ContainerOptionsFormat
*/
/**
* @template T
@@ -17,6 +25,9 @@
* @returns {void}
*/
const process = (options, normalizeSimple, normalizeOptions, fn) => {
/**
* @param {(string | Item<T>)[]} items items
*/
const array = items => {
for (const item of items) {
if (typeof item === "string") {
@@ -28,6 +39,9 @@ const process = (options, normalizeSimple, normalizeOptions, fn) => {
}
}
};
/**
* @param {Item<T>} obj an object
*/
const object = obj => {
for (const [key, value] of Object.entries(obj)) {
if (typeof value === "string" || Array.isArray(value)) {
@@ -38,7 +52,7 @@ const process = (options, normalizeSimple, normalizeOptions, fn) => {
}
};
if (!options) {
return;
// Do nothing
} else if (Array.isArray(options)) {
array(options);
} else if (typeof options === "object") {
@@ -87,5 +101,5 @@ const scope = (scope, options) => {
return obj;
};
exports.parseOptions = parseOptions;
exports.scope = scope;
module.exports.parseOptions = parseOptions;
module.exports.scope = scope;