From 38c37be0d6e74361253a9b7e0893d4bf68389669 Mon Sep 17 00:00:00 2001 From: ahabhgk Date: Fri, 24 Nov 2023 14:30:16 +0800 Subject: [PATCH] simplify --- .../module_federation_runtime_plugin.rs | 2 +- .../src/container/ContainerReferencePlugin.ts | 24 ++- .../src/container/ModuleFederationPlugin.ts | 16 +- .../ModuleFederationRuntimePlugin.ts | 21 ++- .../container/RemoteRuntimeSingletonPlugin.ts | 17 --- .../rspack/src/container/remotesLoading.js | 137 +++++++++--------- packages/rspack/src/rspackOptionsApply.ts | 2 - .../sharing/ShareRuntimeSingletonPlugin.ts | 19 --- .../rspack/src/sharing/initializeSharing.js | 124 ++++++++-------- 9 files changed, 182 insertions(+), 180 deletions(-) delete mode 100644 packages/rspack/src/container/RemoteRuntimeSingletonPlugin.ts delete mode 100644 packages/rspack/src/sharing/ShareRuntimeSingletonPlugin.ts diff --git a/crates/rspack_core/src/mf/container/module_federation_runtime_plugin.rs b/crates/rspack_core/src/mf/container/module_federation_runtime_plugin.rs index c39093595132..48bacad6260f 100644 --- a/crates/rspack_core/src/mf/container/module_federation_runtime_plugin.rs +++ b/crates/rspack_core/src/mf/container/module_federation_runtime_plugin.rs @@ -44,7 +44,7 @@ pub struct ModuleFederationRuntimeModule { impl Default for ModuleFederationRuntimeModule { fn default() -> Self { Self { - id: Identifier::from("webpack/runtime/mf_scope"), + id: Identifier::from("webpack/runtime/module_federation_runtime"), chunk: None, } } diff --git a/packages/rspack/src/container/ContainerReferencePlugin.ts b/packages/rspack/src/container/ContainerReferencePlugin.ts index d9af38ac49ce..c9c23d3301bc 100644 --- a/packages/rspack/src/container/ContainerReferencePlugin.ts +++ b/packages/rspack/src/container/ContainerReferencePlugin.ts @@ -7,8 +7,8 @@ import { Compiler } from "../Compiler"; import { ExternalsPlugin } from "../builtin-plugin/ExternalsPlugin"; import { ExternalsType } from "../config"; import { parseOptions } from "./options"; -import { RemoteRuntimeSingletonPlugin } from "./RemoteRuntimeSingletonPlugin"; -import { ShareRuntimeSingletonPlugin } from "../sharing/ShareRuntimeSingletonPlugin"; +import { ModuleFederationRuntimePlugin } from "./ModuleFederationRuntimePlugin"; +import { isNil } from "../util"; export type ContainerReferencePluginOptions = { remoteType: ExternalsType; @@ -30,8 +30,12 @@ export class ContainerReferencePlugin extends RspackBuiltinPlugin { name = BuiltinPluginName.ContainerReferencePlugin; _options: RawContainerReferencePluginOptions; _remotes; + _mfRuntimePlugin: [boolean, ModuleFederationRuntimePlugin]; - constructor(options: ContainerReferencePluginOptions) { + constructor( + options: ContainerReferencePluginOptions, + mfRuntimePlugin?: ModuleFederationRuntimePlugin + ) { super(); this._remotes = parseOptions( options.remotes, @@ -50,6 +54,10 @@ export class ContainerReferencePlugin extends RspackBuiltinPlugin { remoteType: options.remoteType, remotes: this._remotes.map(([key, r]) => ({ key, ...r })) }; + this._mfRuntimePlugin = [ + !isNil(mfRuntimePlugin), + mfRuntimePlugin ?? new ModuleFederationRuntimePlugin() + ]; } raw(compiler: Compiler): BuiltinPlugin { @@ -66,8 +74,14 @@ export class ContainerReferencePlugin extends RspackBuiltinPlugin { } } new ExternalsPlugin(remoteType, remoteExternals).apply(compiler); - new ShareRuntimeSingletonPlugin().apply(compiler); - new RemoteRuntimeSingletonPlugin().apply(compiler); + const [injected, mfRuntimePlugin] = this._mfRuntimePlugin; + mfRuntimePlugin.addPlugin( + require.resolve("../sharing/initializeSharing.js") + ); + mfRuntimePlugin.addPlugin(require.resolve("./remotesLoading.js")); + if (!injected) { + mfRuntimePlugin.apply(compiler); + } return { name: this.name as any, diff --git a/packages/rspack/src/container/ModuleFederationPlugin.ts b/packages/rspack/src/container/ModuleFederationPlugin.ts index a43be2ad0883..88fbd8820c2d 100644 --- a/packages/rspack/src/container/ModuleFederationPlugin.ts +++ b/packages/rspack/src/container/ModuleFederationPlugin.ts @@ -8,6 +8,7 @@ import { import { isValidate } from "../util/validate"; import { ContainerPlugin, Exposes } from "./ContainerPlugin"; import { ContainerReferencePlugin, Remotes } from "./ContainerReferencePlugin"; +import { ModuleFederationRuntimePlugin } from "./ModuleFederationRuntimePlugin"; export interface ModuleFederationPluginOptions { exposes?: Exposes; @@ -38,6 +39,8 @@ export class ModuleFederationPlugin { ) { compiler.options.output.enabledLibraryTypes!.push(library.type); } + const mfRuntimePlugin = new ModuleFederationRuntimePlugin(); + mfRuntimePlugin.apply(compiler); compiler.hooks.afterPlugins.tap("ModuleFederationPlugin", () => { if ( options.exposes && @@ -60,11 +63,14 @@ export class ModuleFederationPlugin { ? options.remotes.length > 0 : Object.keys(options.remotes).length > 0) ) { - new ContainerReferencePlugin({ - remoteType, - shareScope: options.shareScope, - remotes: options.remotes - }).apply(compiler); + new ContainerReferencePlugin( + { + remoteType, + shareScope: options.shareScope, + remotes: options.remotes + }, + mfRuntimePlugin + ).apply(compiler); } // if (options.shared) { // new SharePlugin({ diff --git a/packages/rspack/src/container/ModuleFederationRuntimePlugin.ts b/packages/rspack/src/container/ModuleFederationRuntimePlugin.ts index 8e66ecf06294..440bffdc23ac 100644 --- a/packages/rspack/src/container/ModuleFederationRuntimePlugin.ts +++ b/packages/rspack/src/container/ModuleFederationRuntimePlugin.ts @@ -1,5 +1,6 @@ import { Compiler } from "../Compiler"; import { BuiltinPluginName, create } from "../builtin-plugin/base"; +import { EntryPlugin } from "../builtin-plugin/EntryPlugin"; const ModuleFederationRuntimePlugin2 = create( BuiltinPluginName.ModuleFederationRuntimePlugin, @@ -7,11 +8,25 @@ const ModuleFederationRuntimePlugin2 = create( ); export class ModuleFederationRuntimePlugin { + plugins: string[] = []; + apply(compiler: Compiler) { // TODO: a hack to make sure this runtime is added after ContainerReferencePlugin // remove afterPlugin once we make rust side runtime_requirements_in_tree "tapable" - compiler.hooks.afterPlugins.tap("ModuleFederationRuntimePlugin", () => { - new ModuleFederationRuntimePlugin2().apply(compiler); - }); + compiler.hooks.afterPlugins.tap( + { name: ModuleFederationRuntimePlugin.name, stage: 10 }, + () => { + // TODO: move to rust side so don't depend on dataUrl + const entry = this.plugins.map(p => `import "${p}";`).join("\n"); + new EntryPlugin(compiler.context, `data:text/javascript,${entry}`, { + name: undefined + }).apply(compiler); + new ModuleFederationRuntimePlugin2().apply(compiler); + } + ); + } + + addPlugin(dep: string) { + this.plugins.push(dep); } } diff --git a/packages/rspack/src/container/RemoteRuntimeSingletonPlugin.ts b/packages/rspack/src/container/RemoteRuntimeSingletonPlugin.ts deleted file mode 100644 index 68eb8ddf4f85..000000000000 --- a/packages/rspack/src/container/RemoteRuntimeSingletonPlugin.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Compiler } from "../Compiler"; -import { EntryPlugin } from "../builtin-plugin/EntryPlugin"; - -let added = false; - -export class RemoteRuntimeSingletonPlugin { - apply(compiler: Compiler) { - if (added) return; - added = true; - new EntryPlugin(compiler.context, require.resolve("./remotesLoading.js"), { - name: undefined - }).apply(compiler); - compiler.hooks.done.tap(RemoteRuntimeSingletonPlugin.name, () => { - added = false; - }); - } -} diff --git a/packages/rspack/src/container/remotesLoading.js b/packages/rspack/src/container/remotesLoading.js index af7e7421c1e9..a73d1b3bfaf9 100644 --- a/packages/rspack/src/container/remotesLoading.js +++ b/packages/rspack/src/container/remotesLoading.js @@ -1,72 +1,75 @@ // @ts-nocheck -__webpack_require__.MF.remotes = function (data) { - var chunkId = data.chunkId, - promises = data.promises, - chunkMapping = data.chunkMapping, - idToExternalAndNameMapping = data.idToExternalAndNameMapping; - if (__webpack_require__.o(chunkMapping, chunkId)) { - chunkMapping[chunkId].forEach(function (id) { - var getScope = __webpack_require__.R; - if (!getScope) getScope = []; - var data = idToExternalAndNameMapping[id]; - if (getScope.indexOf(data) >= 0) return; - getScope.push(data); - if (data.p) return promises.push(data.p); - var onError = function (error) { - if (!error) error = new Error("Container missing"); - if (typeof error.message === "string") - error.message += '\nwhile loading "' + data[1] + '" from ' + data[2]; - __webpack_require__.m[id] = function () { - throw error; +if (__webpack_require__.MF) { + __webpack_require__.MF.remotes = function (data) { + var chunkId = data.chunkId, + promises = data.promises, + chunkMapping = data.chunkMapping, + idToExternalAndNameMapping = data.idToExternalAndNameMapping; + if (__webpack_require__.o(chunkMapping, chunkId)) { + chunkMapping[chunkId].forEach(function (id) { + var getScope = __webpack_require__.R; + if (!getScope) getScope = []; + var data = idToExternalAndNameMapping[id]; + if (getScope.indexOf(data) >= 0) return; + getScope.push(data); + if (data.p) return promises.push(data.p); + var onError = function (error) { + if (!error) error = new Error("Container missing"); + if (typeof error.message === "string") + error.message += + '\nwhile loading "' + data[1] + '" from ' + data[2]; + __webpack_require__.m[id] = function () { + throw error; + }; + data.p = 0; }; - data.p = 0; - }; - var handleFunction = function (fn, arg1, arg2, d, next, first) { - try { - var promise = fn(arg1, arg2); - if (promise && promise.then) { - var p = promise.then(function (result) { - return next(result, d); - }, onError); - if (first) promises.push((data.p = p)); - else return p; - } else { - return next(promise, d, first); + var handleFunction = function (fn, arg1, arg2, d, next, first) { + try { + var promise = fn(arg1, arg2); + if (promise && promise.then) { + var p = promise.then(function (result) { + return next(result, d); + }, onError); + if (first) promises.push((data.p = p)); + else return p; + } else { + return next(promise, d, first); + } + } catch (error) { + onError(error); } - } catch (error) { - onError(error); - } - }; - var onExternal = function (external, _, first) { - return external - ? handleFunction( - __webpack_require__.I, - data[0], - 0, - external, - onInitialized, - first - ) - : onError(); - }; - var onInitialized = function (_, external, first) { - return handleFunction( - external.get, - data[1], - getScope, - 0, - onFactory, - first - ); - }; - var onFactory = function (factory) { - data.p = 1; - __webpack_require__.m[id] = function (module) { - module.exports = factory(); }; - }; - handleFunction(__webpack_require__, data[2], 0, 0, onExternal, 1); - }); - } -}; + var onExternal = function (external, _, first) { + return external + ? handleFunction( + __webpack_require__.I, + data[0], + 0, + external, + onInitialized, + first + ) + : onError(); + }; + var onInitialized = function (_, external, first) { + return handleFunction( + external.get, + data[1], + getScope, + 0, + onFactory, + first + ); + }; + var onFactory = function (factory) { + data.p = 1; + __webpack_require__.m[id] = function (module) { + module.exports = factory(); + }; + }; + handleFunction(__webpack_require__, data[2], 0, 0, onExternal, 1); + }); + } + }; +} diff --git a/packages/rspack/src/rspackOptionsApply.ts b/packages/rspack/src/rspackOptionsApply.ts index f61153bff3b7..7300e2e71ede 100644 --- a/packages/rspack/src/rspackOptionsApply.ts +++ b/packages/rspack/src/rspackOptionsApply.ts @@ -174,8 +174,6 @@ export class RspackOptionsApply { ); compiler.hooks.entryOption.call(options.context, options.entry); - new ModuleFederationRuntimePlugin().apply(compiler); - const { minimize, minimizer } = options.optimization; if (minimize && minimizer) { for (const item of minimizer) { diff --git a/packages/rspack/src/sharing/ShareRuntimeSingletonPlugin.ts b/packages/rspack/src/sharing/ShareRuntimeSingletonPlugin.ts deleted file mode 100644 index 8b6a129164ce..000000000000 --- a/packages/rspack/src/sharing/ShareRuntimeSingletonPlugin.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Compiler } from "../Compiler"; -import { EntryPlugin } from "../builtin-plugin/EntryPlugin"; - -let added = false; - -export class ShareRuntimeSingletonPlugin { - apply(compiler: Compiler) { - if (added) return; - added = true; - new EntryPlugin( - compiler.context, - require.resolve("./initializeSharing.js"), - { name: undefined } - ).apply(compiler); - compiler.hooks.done.tap(ShareRuntimeSingletonPlugin.name, () => { - added = false; - }); - } -} diff --git a/packages/rspack/src/sharing/initializeSharing.js b/packages/rspack/src/sharing/initializeSharing.js index 519c1ef9f813..94031a09a5cb 100644 --- a/packages/rspack/src/sharing/initializeSharing.js +++ b/packages/rspack/src/sharing/initializeSharing.js @@ -1,66 +1,68 @@ // @ts-nocheck -__webpack_require__.MF.initializeSharing = function (data) { - var name = data.name, - initScope = data.initScope, - initPerScope = data.initPerScope, - initTokens = data.initTokens, - initPromises = data.initPromises; - if (!initScope) initScope = []; - // handling circular init calls - var initToken = initTokens[name]; - if (!initToken) initToken = initTokens[name] = {}; - if (initScope.indexOf(initToken) >= 0) return; - initScope.push(initToken); - // only runs once - if (initPromises[name]) return initPromises[name]; - // creates a new share scope if needed - if (!__webpack_require__.o(__webpack_require__.S, name)) - __webpack_require__.S[name] = {}; - // runs all init snippets from all modules reachable - var scope = __webpack_require__.S[name]; - var warn = function (msg) { - if (typeof console !== "undefined" && console.warn) console.warn(msg); - }; - var uniqueName = "app"; - var register = function (name, version, factory, eager) { - var versions = (scope[name] = scope[name] || {}); - var activeVersion = versions[version]; - if ( - !activeVersion || - (!activeVersion.loaded && - (!eager != !activeVersion.eager - ? eager - : uniqueName > activeVersion.from)) - ) - versions[version] = { get: factory, from: uniqueName, eager: !!eager }; - }; - var initExternal = function (id) { - var handleError = function (err) { - warn("Initialization of sharing external failed: " + err); +if (__webpack_require__.MF) { + __webpack_require__.MF.initializeSharing = function (data) { + var name = data.name, + initScope = data.initScope, + initPerScope = data.initPerScope, + initTokens = data.initTokens, + initPromises = data.initPromises; + if (!initScope) initScope = []; + // handling circular init calls + var initToken = initTokens[name]; + if (!initToken) initToken = initTokens[name] = {}; + if (initScope.indexOf(initToken) >= 0) return; + initScope.push(initToken); + // only runs once + if (initPromises[name]) return initPromises[name]; + // creates a new share scope if needed + if (!__webpack_require__.o(__webpack_require__.S, name)) + __webpack_require__.S[name] = {}; + // runs all init snippets from all modules reachable + var scope = __webpack_require__.S[name]; + var warn = function (msg) { + if (typeof console !== "undefined" && console.warn) console.warn(msg); }; - try { - var module = __webpack_require__(id); - if (!module) return; - var initFn = function (module) { - return ( - module && - module.init && - module.init(__webpack_require__.S[name], initScope) - ); + var uniqueName = "app"; + var register = function (name, version, factory, eager) { + var versions = (scope[name] = scope[name] || {}); + var activeVersion = versions[version]; + if ( + !activeVersion || + (!activeVersion.loaded && + (!eager != !activeVersion.eager + ? eager + : uniqueName > activeVersion.from)) + ) + versions[version] = { get: factory, from: uniqueName, eager: !!eager }; + }; + var initExternal = function (id) { + var handleError = function (err) { + warn("Initialization of sharing external failed: " + err); }; - if (module.then) return promises.push(module.then(initFn, handleError)); - var initResult = initFn(module); - if (initResult && initResult.then) - return promises.push(initResult["catch"](handleError)); - } catch (err) { - handleError(err); - } + try { + var module = __webpack_require__(id); + if (!module) return; + var initFn = function (module) { + return ( + module && + module.init && + module.init(__webpack_require__.S[name], initScope) + ); + }; + if (module.then) return promises.push(module.then(initFn, handleError)); + var initResult = initFn(module); + if (initResult && initResult.then) + return promises.push(initResult["catch"](handleError)); + } catch (err) { + handleError(err); + } + }; + var promises = []; + initPerScope(name, register, initExternal); + if (!promises.length) return (initPromises[name] = 1); + return (initPromises[name] = Promise.all(promises).then(function () { + return (initPromises[name] = 1); + })); }; - var promises = []; - initPerScope(name, register, initExternal); - if (!promises.length) return (initPromises[name] = 1); - return (initPromises[name] = Promise.all(promises).then(function () { - return (initPromises[name] = 1); - })); -}; +}