@module-federation/node 0.0.0-chore-bump-node-22-20260710161714

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +235 -0
  3. package/dist/_virtual/_rolldown/runtime.js +31 -0
  4. package/dist/_virtual/_rolldown/runtime.mjs +8 -0
  5. package/dist/plugins/ChunkCorrelationPlugin.js +308 -0
  6. package/dist/plugins/ChunkCorrelationPlugin.js.map +1 -0
  7. package/dist/plugins/ChunkCorrelationPlugin.mjs +305 -0
  8. package/dist/plugins/ChunkCorrelationPlugin.mjs.map +1 -0
  9. package/dist/src/filesystem/stratagies.d.mts +21 -0
  10. package/dist/src/filesystem/stratagies.d.ts +21 -0
  11. package/dist/src/filesystem/stratagies.js +105 -0
  12. package/dist/src/filesystem/stratagies.js.map +1 -0
  13. package/dist/src/filesystem/stratagies.mjs +103 -0
  14. package/dist/src/filesystem/stratagies.mjs.map +1 -0
  15. package/dist/src/index.d.mts +8 -0
  16. package/dist/src/index.d.ts +8 -0
  17. package/dist/src/index.js +16 -0
  18. package/dist/src/index.mjs +9 -0
  19. package/dist/src/plugins/AutomaticPublicPathPlugin.d.mts +12 -0
  20. package/dist/src/plugins/AutomaticPublicPathPlugin.d.ts +11 -0
  21. package/dist/src/plugins/AutomaticPublicPathPlugin.js +29 -0
  22. package/dist/src/plugins/AutomaticPublicPathPlugin.js.map +1 -0
  23. package/dist/src/plugins/AutomaticPublicPathPlugin.mjs +28 -0
  24. package/dist/src/plugins/AutomaticPublicPathPlugin.mjs.map +1 -0
  25. package/dist/src/plugins/ChunkCorrelationPlugin.d.mts +5 -0
  26. package/dist/src/plugins/ChunkCorrelationPlugin.d.ts +4 -0
  27. package/dist/src/plugins/ChunkCorrelationPlugin.js +9 -0
  28. package/dist/src/plugins/ChunkCorrelationPlugin.js.map +1 -0
  29. package/dist/src/plugins/ChunkCorrelationPlugin.mjs +8 -0
  30. package/dist/src/plugins/ChunkCorrelationPlugin.mjs.map +1 -0
  31. package/dist/src/plugins/CommonJsChunkLoadingPlugin.d.mts +21 -0
  32. package/dist/src/plugins/CommonJsChunkLoadingPlugin.d.ts +20 -0
  33. package/dist/src/plugins/CommonJsChunkLoadingPlugin.js +71 -0
  34. package/dist/src/plugins/CommonJsChunkLoadingPlugin.js.map +1 -0
  35. package/dist/src/plugins/CommonJsChunkLoadingPlugin.mjs +70 -0
  36. package/dist/src/plugins/CommonJsChunkLoadingPlugin.mjs.map +1 -0
  37. package/dist/src/plugins/DynamicFilesystemChunkLoadingRuntimeModule.d.mts +46 -0
  38. package/dist/src/plugins/DynamicFilesystemChunkLoadingRuntimeModule.d.ts +45 -0
  39. package/dist/src/plugins/DynamicFilesystemChunkLoadingRuntimeModule.js +112 -0
  40. package/dist/src/plugins/DynamicFilesystemChunkLoadingRuntimeModule.js.map +1 -0
  41. package/dist/src/plugins/DynamicFilesystemChunkLoadingRuntimeModule.mjs +111 -0
  42. package/dist/src/plugins/DynamicFilesystemChunkLoadingRuntimeModule.mjs.map +1 -0
  43. package/dist/src/plugins/EntryChunkTrackerPlugin.d.mts +17 -0
  44. package/dist/src/plugins/EntryChunkTrackerPlugin.d.ts +17 -0
  45. package/dist/src/plugins/EntryChunkTrackerPlugin.js +39 -0
  46. package/dist/src/plugins/EntryChunkTrackerPlugin.js.map +1 -0
  47. package/dist/src/plugins/EntryChunkTrackerPlugin.mjs +38 -0
  48. package/dist/src/plugins/EntryChunkTrackerPlugin.mjs.map +1 -0
  49. package/dist/src/plugins/NodeFederationPlugin.d.mts +54 -0
  50. package/dist/src/plugins/NodeFederationPlugin.d.ts +53 -0
  51. package/dist/src/plugins/NodeFederationPlugin.js +76 -0
  52. package/dist/src/plugins/NodeFederationPlugin.js.map +1 -0
  53. package/dist/src/plugins/NodeFederationPlugin.mjs +73 -0
  54. package/dist/src/plugins/NodeFederationPlugin.mjs.map +1 -0
  55. package/dist/src/plugins/RemotePublicPathRuntimeModule.d.mts +15 -0
  56. package/dist/src/plugins/RemotePublicPathRuntimeModule.d.ts +14 -0
  57. package/dist/src/plugins/RemotePublicPathRuntimeModule.js +133 -0
  58. package/dist/src/plugins/RemotePublicPathRuntimeModule.js.map +1 -0
  59. package/dist/src/plugins/RemotePublicPathRuntimeModule.mjs +132 -0
  60. package/dist/src/plugins/RemotePublicPathRuntimeModule.mjs.map +1 -0
  61. package/dist/src/plugins/StreamingTargetPlugin.d.mts +32 -0
  62. package/dist/src/plugins/StreamingTargetPlugin.d.ts +31 -0
  63. package/dist/src/plugins/StreamingTargetPlugin.js +46 -0
  64. package/dist/src/plugins/StreamingTargetPlugin.js.map +1 -0
  65. package/dist/src/plugins/StreamingTargetPlugin.mjs +46 -0
  66. package/dist/src/plugins/StreamingTargetPlugin.mjs.map +1 -0
  67. package/dist/src/plugins/UniversalFederationPlugin.d.mts +49 -0
  68. package/dist/src/plugins/UniversalFederationPlugin.d.ts +48 -0
  69. package/dist/src/plugins/UniversalFederationPlugin.js +66 -0
  70. package/dist/src/plugins/UniversalFederationPlugin.js.map +1 -0
  71. package/dist/src/plugins/UniversalFederationPlugin.mjs +65 -0
  72. package/dist/src/plugins/UniversalFederationPlugin.mjs.map +1 -0
  73. package/dist/src/plugins/UniverseEntryChunkTrackerPlugin.d.mts +9 -0
  74. package/dist/src/plugins/UniverseEntryChunkTrackerPlugin.d.ts +8 -0
  75. package/dist/src/plugins/UniverseEntryChunkTrackerPlugin.js +25 -0
  76. package/dist/src/plugins/UniverseEntryChunkTrackerPlugin.js.map +1 -0
  77. package/dist/src/plugins/UniverseEntryChunkTrackerPlugin.mjs +23 -0
  78. package/dist/src/plugins/UniverseEntryChunkTrackerPlugin.mjs.map +1 -0
  79. package/dist/src/plugins/webpackChunkUtilities.d.mts +55 -0
  80. package/dist/src/plugins/webpackChunkUtilities.d.ts +55 -0
  81. package/dist/src/plugins/webpackChunkUtilities.js +242 -0
  82. package/dist/src/plugins/webpackChunkUtilities.js.map +1 -0
  83. package/dist/src/plugins/webpackChunkUtilities.mjs +234 -0
  84. package/dist/src/plugins/webpackChunkUtilities.mjs.map +1 -0
  85. package/dist/src/recordDynamicRemoteEntryHashPlugin.d.mts +7 -0
  86. package/dist/src/recordDynamicRemoteEntryHashPlugin.d.ts +6 -0
  87. package/dist/src/recordDynamicRemoteEntryHashPlugin.js +28 -0
  88. package/dist/src/recordDynamicRemoteEntryHashPlugin.js.map +1 -0
  89. package/dist/src/recordDynamicRemoteEntryHashPlugin.mjs +26 -0
  90. package/dist/src/recordDynamicRemoteEntryHashPlugin.mjs.map +1 -0
  91. package/dist/src/runtimePlugin.d.mts +27 -0
  92. package/dist/src/runtimePlugin.d.ts +27 -0
  93. package/dist/src/runtimePlugin.js +242 -0
  94. package/dist/src/runtimePlugin.js.map +1 -0
  95. package/dist/src/runtimePlugin.mjs +226 -0
  96. package/dist/src/runtimePlugin.mjs.map +1 -0
  97. package/dist/src/types/index.d.mts +8 -0
  98. package/dist/src/types/index.d.ts +8 -0
  99. package/dist/src/types/index.js +1 -0
  100. package/dist/src/types/index.mjs +1 -0
  101. package/dist/src/utils/flush-chunks.d.mts +15 -0
  102. package/dist/src/utils/flush-chunks.d.ts +15 -0
  103. package/dist/src/utils/flush-chunks.js +106 -0
  104. package/dist/src/utils/flush-chunks.js.map +1 -0
  105. package/dist/src/utils/flush-chunks.mjs +102 -0
  106. package/dist/src/utils/flush-chunks.mjs.map +1 -0
  107. package/dist/src/utils/hot-reload.d.mts +16 -0
  108. package/dist/src/utils/hot-reload.d.ts +16 -0
  109. package/dist/src/utils/hot-reload.js +206 -0
  110. package/dist/src/utils/hot-reload.js.map +1 -0
  111. package/dist/src/utils/hot-reload.mjs +195 -0
  112. package/dist/src/utils/hot-reload.mjs.map +1 -0
  113. package/dist/src/utils/index.d.mts +3 -0
  114. package/dist/src/utils/index.d.ts +3 -0
  115. package/dist/src/utils/index.js +15 -0
  116. package/dist/src/utils/index.mjs +4 -0
  117. package/package.json +135 -0
@@ -0,0 +1,234 @@
1
+ import { __require } from "../../_virtual/_rolldown/runtime.mjs";
2
+ import { normalizeWebpackPath } from "@module-federation/sdk/normalize-webpack-path";
3
+
4
+ //#region src/plugins/webpackChunkUtilities.ts
5
+ const { RuntimeGlobals, Template } = __require(normalizeWebpackPath("webpack"));
6
+ /**
7
+ * Generates the hot module replacement (HMR) code.
8
+ * @param {boolean} withHmr - Flag indicating whether HMR is enabled.
9
+ * @param {string} rootOutputDir - The root output directory.
10
+ * @returns {string} - The generated HMR code.
11
+ */
12
+ function generateHmrCode(withHmr, rootOutputDir) {
13
+ if (!withHmr) return "// no HMR";
14
+ return Template.asString([
15
+ "function loadUpdateChunk(chunkId, updatedModulesList) {",
16
+ Template.indent([
17
+ "return new Promise(function(resolve, reject) {",
18
+ Template.indent([
19
+ `var filename = require('path').join(__dirname, ${JSON.stringify(rootOutputDir)} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId));`,
20
+ "require('fs').readFile(filename, 'utf-8', function(err, content) {",
21
+ Template.indent([
22
+ "if(err) return reject(err);",
23
+ "var update = {};",
24
+ "require('vm').runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\n})', filename)(update, require, require('path').dirname(filename), filename);",
25
+ "var updatedModules = update.modules;",
26
+ "var runtime = update.runtime;",
27
+ "for(var moduleId in updatedModules) {",
28
+ Template.indent([
29
+ `if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`,
30
+ Template.indent([`currentUpdate[moduleId] = updatedModules[moduleId];`, "if(updatedModulesList) updatedModulesList.push(moduleId);"]),
31
+ "}"
32
+ ]),
33
+ "}",
34
+ "if(runtime) currentUpdateRuntime.push(runtime);",
35
+ "resolve();"
36
+ ]),
37
+ "});"
38
+ ]),
39
+ "});"
40
+ ]),
41
+ "}",
42
+ "",
43
+ Template.getFunctionContent(__require("webpack/lib/hmr/JavascriptHotModuleReplacement.runtime.js")).replace(/\$key\$/g, "readFileVm").replace(/\$installedChunks\$/g, "installedChunks").replace(/\$loadUpdateChunk\$/g, "loadUpdateChunk").replace(/\$moduleCache\$/g, RuntimeGlobals.moduleCache).replace(/\$moduleFactories\$/g, RuntimeGlobals.moduleFactories).replace(/\$ensureChunkHandlers\$/g, RuntimeGlobals.ensureChunkHandlers).replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty).replace(/\$hmrModuleData\$/g, RuntimeGlobals.hmrModuleData).replace(/\$hmrDownloadUpdateHandlers\$/g, RuntimeGlobals.hmrDownloadUpdateHandlers).replace(/\$hmrInvalidateModuleHandlers\$/g, RuntimeGlobals.hmrInvalidateModuleHandlers)
44
+ ]);
45
+ }
46
+ /**
47
+ * Retrieves the initial chunk IDs.
48
+ * @param {Chunk} chunk - The chunk object.
49
+ * @param {ChunkGraph} chunkGraph - The chunk graph object.
50
+ * @param {any} chunkHasJs - Function to check if a chunk has JavaScript.
51
+ * @returns {Set} - The set of initial chunk IDs.
52
+ */
53
+ function getInitialChunkIds(chunk, chunkGraph, chunkHasJs) {
54
+ const initialChunkIds = new Set(chunk.ids);
55
+ for (const c of chunk.getAllInitialChunks()) {
56
+ if (c === chunk || chunkHasJs(c, chunkGraph)) continue;
57
+ if (c.ids) for (const id of c.ids) initialChunkIds.add(id);
58
+ for (const c of chunk.getAllAsyncChunks()) {
59
+ if (c === chunk || chunkHasJs(c, chunkGraph)) continue;
60
+ if (c.ids) for (const id of c.ids) initialChunkIds.add(id);
61
+ }
62
+ }
63
+ return initialChunkIds;
64
+ }
65
+ /**
66
+ * Generates the loading code for chunks.
67
+ * @param {boolean} withLoading - Flag indicating whether chunk loading is enabled.
68
+ * @param {string} fn - The function name.
69
+ * @param {any} hasJsMatcher - Function to check if a chunk has JavaScript.
70
+ * @param {string} rootOutputDir - The root output directory.
71
+ * @param {Record<string, string>} remotes - The remotes object.
72
+ * @param {string | undefined} name - The name of the chunk.
73
+ * @returns {string} - The generated loading code.
74
+ */
75
+ function generateLoadingCode(withLoading, fn, hasJsMatcher, rootOutputDir, remotes, name) {
76
+ if (!withLoading) return "// no chunk loading";
77
+ return Template.asString([
78
+ "// Dynamic filesystem chunk loading for javascript",
79
+ `${fn}.readFileVm = function(chunkId, promises) {`,
80
+ hasJsMatcher !== false ? Template.indent([
81
+ "var installedChunkData = installedChunks[chunkId];",
82
+ "if(installedChunkData !== 0) { // 0 means \"already installed\".",
83
+ Template.indent([
84
+ "// array of [resolve, reject, promise] means \"currently loading\"",
85
+ "if(installedChunkData) {",
86
+ Template.indent(["promises.push(installedChunkData[2]);"]),
87
+ "} else {",
88
+ Template.indent([
89
+ hasJsMatcher === true ? "if(true) { // all chunks have JS" : `if(${hasJsMatcher("chunkId")}) {`,
90
+ Template.indent([
91
+ "// load the chunk and return promise to it",
92
+ "var promise = new Promise(async function(resolve, reject) {",
93
+ Template.indent([
94
+ "installedChunkData = installedChunks[chunkId] = [resolve, reject];",
95
+ "function installChunkCallback(error,chunk){",
96
+ Template.indent(["if(error) return reject(error);", "installChunk(chunk);"]),
97
+ "}",
98
+ "var fs = typeof process !== \"undefined\" ? require('fs') : false;",
99
+ `var filename = typeof process !== "undefined" ? require('path').join(__dirname, ${JSON.stringify(rootOutputDir)} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId)) : false;`,
100
+ "if(fs && fs.existsSync(filename)) {",
101
+ Template.indent([`loadChunkStrategy('filesystem', chunkId, ${JSON.stringify(rootOutputDir)}, remotes, installChunkCallback);`]),
102
+ "} else { ",
103
+ Template.indent([
104
+ `var remotes = ${JSON.stringify(Object.values(remotes).reduce((acc, remote) => {
105
+ const [global, url] = remote.split("@");
106
+ acc[global] = url;
107
+ return acc;
108
+ }, {}))};`,
109
+ `var chunkName = ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`,
110
+ "const loadingStrategy = typeof process !== 'undefined' ? 'http-vm' : 'http-eval';",
111
+ `loadChunkStrategy(loadingStrategy, chunkName,${RuntimeGlobals.require}.federation.initOptions.name, ${RuntimeGlobals.require}.federation.initOptions.remotes, installChunkCallback);`
112
+ ]),
113
+ "}"
114
+ ]),
115
+ "});",
116
+ "promises.push(installedChunkData[2] = promise);"
117
+ ]),
118
+ "} else installedChunks[chunkId] = 0;"
119
+ ]),
120
+ "}"
121
+ ]),
122
+ "}"
123
+ ]) : Template.indent(["installedChunks[chunkId] = 0;"]),
124
+ "};"
125
+ ]);
126
+ }
127
+ /**
128
+ * Generates the HMR manifest code.
129
+ * @param {boolean} withHmrManifest - Flag indicating whether HMR manifest is enabled.
130
+ * @param {string} rootOutputDir - The root output directory.
131
+ * @returns {string} - The generated HMR manifest code.
132
+ */
133
+ function generateHmrManifestCode(withHmrManifest, rootOutputDir) {
134
+ if (!withHmrManifest) return "// no HMR manifest";
135
+ return Template.asString([
136
+ `${RuntimeGlobals.hmrDownloadManifest} = function() {`,
137
+ Template.indent([
138
+ "return new Promise(function(resolve, reject) {",
139
+ Template.indent([
140
+ `var filename = require('path').join(__dirname, ${JSON.stringify(rootOutputDir)} + ${RuntimeGlobals.getUpdateManifestFilename}());`,
141
+ "require('fs').readFile(filename, 'utf-8', function(err, content) {",
142
+ Template.indent([
143
+ "if(err) {",
144
+ Template.indent(["if(err.code === \"ENOENT\") return resolve();", "return reject(err);"]),
145
+ "}",
146
+ "try { resolve(JSON.parse(content)); }",
147
+ "catch(e) { reject(e); }"
148
+ ]),
149
+ "});"
150
+ ]),
151
+ "});"
152
+ ]),
153
+ "}"
154
+ ]);
155
+ }
156
+ /**
157
+ * Handles the on chunk load event.
158
+ * @param {boolean} withOnChunkLoad - Flag indicating whether on chunk load event is enabled.
159
+ * @param {any} runtimeTemplate - The runtime template.
160
+ * @returns {string} - The generated on chunk load event handler.
161
+ */
162
+ function handleOnChunkLoad(withOnChunkLoad, runtimeTemplate) {
163
+ if (withOnChunkLoad) return `${RuntimeGlobals.onChunksLoaded}.readFileVm = ${runtimeTemplate.returningFunction("installedChunks[chunkId] === 0", "chunkId")};`;
164
+ else return "// no on chunks loaded";
165
+ }
166
+ /**
167
+ * Generates the load script for server-side execution. This function creates a script that loads a remote module
168
+ * and executes it in the current context. It supports both browser and Node.js environments.
169
+ * @param {any} runtimeTemplate - The runtime template used to generate the load script.
170
+ * @returns {string} - The generated load script.
171
+ */
172
+ function generateLoadScript(runtimeTemplate) {
173
+ return Template.asString(["// load script equivalent for server side", `${RuntimeGlobals.loadScript} = ${runtimeTemplate.basicFunction("url, callback, chunkId", [Template.indent([`async function executeLoad(url, callback, name) {
174
+ if (!name) {
175
+ throw new Error('__webpack_require__.l name is required for ' + url);
176
+ }
177
+ const usesInternalRef = name.startsWith('__webpack_require__')
178
+ if (usesInternalRef) {
179
+ const regex = /__webpack_require__\\.federation\\.instance\\.moduleCache\\.get\\(([^)]+)\\)/;
180
+ const match = name.match(regex);
181
+ if (match) {
182
+ name = match[1].replace(/["']/g, '');
183
+ }
184
+ }
185
+ try {
186
+ const federation = ${RuntimeGlobals.require}.federation;
187
+ const res = await ${RuntimeGlobals.require}.federation.runtime.loadScriptNode(url, { attrs: {} });
188
+ const enhancedRemote = federation.instance.initRawContainer(name, url, res);
189
+ // use normal global assignment
190
+ if(!usesInternalRef && !globalThis[name]) {
191
+ globalThis[name] = enhancedRemote
192
+ }
193
+ callback(enhancedRemote);
194
+ } catch (error) {
195
+ callback(error);
196
+ }
197
+
198
+ }`, `executeLoad(url, callback, chunkId);`])])}`]);
199
+ }
200
+ function generateInstallChunk(runtimeTemplate, withOnChunkLoad) {
201
+ return `var installChunk = ${runtimeTemplate.basicFunction("chunk", [
202
+ "var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;",
203
+ "for(var moduleId in moreModules) {",
204
+ Template.indent([
205
+ `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
206
+ Template.indent([`${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`]),
207
+ "}"
208
+ ]),
209
+ "}",
210
+ "if(runtime) runtime(__webpack_require__);",
211
+ "for(var i = 0; i < chunkIds.length; i++) {",
212
+ Template.indent([
213
+ "if(installedChunks[chunkIds[i]]) {",
214
+ Template.indent(["installedChunks[chunkIds[i]][0]();"]),
215
+ "}",
216
+ "installedChunks[chunkIds[i]] = 0;"
217
+ ]),
218
+ "}",
219
+ withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : ""
220
+ ])};`;
221
+ }
222
+ function generateExternalInstallChunkCode(withExternalInstallChunk, debug) {
223
+ if (!withExternalInstallChunk) return "// no external install chunk";
224
+ return Template.asString([
225
+ "module.exports = __webpack_require__;",
226
+ `${RuntimeGlobals.externalInstallChunk} = function(){`,
227
+ debug ? `console.debug('node: webpack installing to install chunk id:', arguments['0'].id);` : "",
228
+ `return installChunk.apply(this, arguments)};`
229
+ ]);
230
+ }
231
+
232
+ //#endregion
233
+ export { generateExternalInstallChunkCode, generateHmrCode, generateHmrManifestCode, generateInstallChunk, generateLoadScript, generateLoadingCode, getInitialChunkIds, handleOnChunkLoad };
234
+ //# sourceMappingURL=webpackChunkUtilities.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webpackChunkUtilities.mjs","names":[],"sources":["../../../src/plugins/webpackChunkUtilities.ts"],"sourcesContent":["import { normalizeWebpackPath } from '@module-federation/sdk/normalize-webpack-path';\nconst { RuntimeGlobals, Template } = require(\n normalizeWebpackPath('webpack'),\n) as typeof import('webpack');\nimport type { Chunk, ChunkGraph } from 'webpack';\n\n/**\n * Generates the hot module replacement (HMR) code.\n * @param {boolean} withHmr - Flag indicating whether HMR is enabled.\n * @param {string} rootOutputDir - The root output directory.\n * @returns {string} - The generated HMR code.\n */\nexport function generateHmrCode(\n withHmr: boolean,\n rootOutputDir: string,\n): string {\n if (!withHmr) {\n return '// no HMR';\n }\n\n return Template.asString([\n // Function to load updated chunk\n 'function loadUpdateChunk(chunkId, updatedModulesList) {',\n Template.indent([\n 'return new Promise(function(resolve, reject) {',\n Template.indent([\n // Construct filename for the updated chunk\n `var filename = require('path').join(__dirname, ${JSON.stringify(\n rootOutputDir,\n )} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId));`,\n // Read the updated chunk file\n \"require('fs').readFile(filename, 'utf-8', function(err, content) {\",\n Template.indent([\n 'if(err) return reject(err);',\n 'var update = {};',\n // Execute the updated chunk in the current context\n \"require('vm').runInThisContext('(function(exports, require, __dirname, __filename) {' + content + '\\\\n})', filename)\" +\n \"(update, require, require('path').dirname(filename), filename);\",\n 'var updatedModules = update.modules;',\n 'var runtime = update.runtime;',\n // Iterate over the updated modules\n 'for(var moduleId in updatedModules) {',\n Template.indent([\n `if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`,\n Template.indent([\n `currentUpdate[moduleId] = updatedModules[moduleId];`,\n 'if(updatedModulesList) updatedModulesList.push(moduleId);',\n ]),\n '}',\n ]),\n '}',\n 'if(runtime) currentUpdateRuntime.push(runtime);',\n 'resolve();',\n ]),\n '});',\n ]),\n '});',\n ]),\n '}',\n '',\n // Replace placeholders in the HMR runtime code\n Template.getFunctionContent(\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n require('webpack/lib/hmr/JavascriptHotModuleReplacement.runtime.js'),\n )\n .replace(/\\$key\\$/g, 'readFileVm')\n .replace(/\\$installedChunks\\$/g, 'installedChunks')\n .replace(/\\$loadUpdateChunk\\$/g, 'loadUpdateChunk')\n .replace(/\\$moduleCache\\$/g, RuntimeGlobals.moduleCache)\n .replace(/\\$moduleFactories\\$/g, RuntimeGlobals.moduleFactories)\n .replace(/\\$ensureChunkHandlers\\$/g, RuntimeGlobals.ensureChunkHandlers)\n .replace(/\\$hasOwnProperty\\$/g, RuntimeGlobals.hasOwnProperty)\n .replace(/\\$hmrModuleData\\$/g, RuntimeGlobals.hmrModuleData)\n .replace(\n /\\$hmrDownloadUpdateHandlers\\$/g,\n RuntimeGlobals.hmrDownloadUpdateHandlers,\n )\n .replace(\n /\\$hmrInvalidateModuleHandlers\\$/g,\n RuntimeGlobals.hmrInvalidateModuleHandlers,\n ),\n ]);\n}\n/**\n * Retrieves the initial chunk IDs.\n * @param {Chunk} chunk - The chunk object.\n * @param {ChunkGraph} chunkGraph - The chunk graph object.\n * @param {any} chunkHasJs - Function to check if a chunk has JavaScript.\n * @returns {Set} - The set of initial chunk IDs.\n */\nexport function getInitialChunkIds(\n chunk: Chunk,\n chunkGraph: ChunkGraph,\n chunkHasJs: any,\n) {\n const initialChunkIds = new Set(chunk.ids);\n for (const c of chunk.getAllInitialChunks()) {\n if (c === chunk || chunkHasJs(c, chunkGraph)) continue;\n if (c.ids) {\n for (const id of c.ids) initialChunkIds.add(id);\n }\n for (const c of chunk.getAllAsyncChunks()) {\n if (c === chunk || chunkHasJs(c, chunkGraph)) continue;\n if (c.ids) {\n for (const id of c.ids) initialChunkIds.add(id);\n }\n }\n }\n return initialChunkIds;\n}\n/**\n * Generates the loading code for chunks.\n * @param {boolean} withLoading - Flag indicating whether chunk loading is enabled.\n * @param {string} fn - The function name.\n * @param {any} hasJsMatcher - Function to check if a chunk has JavaScript.\n * @param {string} rootOutputDir - The root output directory.\n * @param {Record<string, string>} remotes - The remotes object.\n * @param {string | undefined} name - The name of the chunk.\n * @returns {string} - The generated loading code.\n */\nexport function generateLoadingCode(\n withLoading: boolean,\n fn: string,\n hasJsMatcher: any,\n rootOutputDir: string,\n remotes: Record<string, string>,\n name: string | undefined,\n): string {\n if (!withLoading) {\n return '// no chunk loading';\n }\n\n return Template.asString([\n '// Dynamic filesystem chunk loading for javascript',\n `${fn}.readFileVm = function(chunkId, promises) {`,\n hasJsMatcher !== false\n ? Template.indent([\n 'var installedChunkData = installedChunks[chunkId];',\n 'if(installedChunkData !== 0) { // 0 means \"already installed\".',\n Template.indent([\n '// array of [resolve, reject, promise] means \"currently loading\"',\n 'if(installedChunkData) {',\n Template.indent(['promises.push(installedChunkData[2]);']),\n '} else {',\n Template.indent([\n hasJsMatcher === true\n ? 'if(true) { // all chunks have JS'\n : `if(${hasJsMatcher('chunkId')}) {`,\n Template.indent([\n '// load the chunk and return promise to it',\n 'var promise = new Promise(async function(resolve, reject) {',\n Template.indent([\n 'installedChunkData = installedChunks[chunkId] = [resolve, reject];',\n 'function installChunkCallback(error,chunk){',\n Template.indent([\n 'if(error) return reject(error);',\n 'installChunk(chunk);',\n ]),\n '}',\n 'var fs = typeof process !== \"undefined\" ? require(\\'fs\\') : false;',\n `var filename = typeof process !== \"undefined\" ? require('path').join(__dirname, ${JSON.stringify(\n rootOutputDir,\n )} + ${\n RuntimeGlobals.getChunkScriptFilename\n }(chunkId)) : false;`,\n\n 'if(fs && fs.existsSync(filename)) {',\n Template.indent([\n `loadChunkStrategy('filesystem', chunkId, ${JSON.stringify(\n rootOutputDir,\n )}, remotes, installChunkCallback);`,\n ]),\n '} else { ',\n Template.indent([\n `var remotes = ${JSON.stringify(\n Object.values(remotes).reduce(\n (acc, remote) => {\n const [global, url] = remote.split('@');\n acc[global] = url;\n return acc;\n },\n {} as Record<string, string>,\n ),\n )};`,\n\n `var chunkName = ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`,\n \"const loadingStrategy = typeof process !== 'undefined' ? 'http-vm' : 'http-eval';\",\n `loadChunkStrategy(loadingStrategy, chunkName,${RuntimeGlobals.require}.federation.initOptions.name, ${RuntimeGlobals.require}.federation.initOptions.remotes, installChunkCallback);`,\n ]),\n '}',\n ]),\n '});',\n 'promises.push(installedChunkData[2] = promise);',\n ]),\n '} else installedChunks[chunkId] = 0;',\n ]),\n '}',\n ]),\n '}',\n ])\n : Template.indent(['installedChunks[chunkId] = 0;']),\n '};',\n ]);\n}\n/**\n * Generates the HMR manifest code.\n * @param {boolean} withHmrManifest - Flag indicating whether HMR manifest is enabled.\n * @param {string} rootOutputDir - The root output directory.\n * @returns {string} - The generated HMR manifest code.\n */\nexport function generateHmrManifestCode(\n withHmrManifest: boolean,\n rootOutputDir: string,\n): string {\n if (!withHmrManifest) {\n return '// no HMR manifest';\n }\n\n return Template.asString([\n `${RuntimeGlobals.hmrDownloadManifest} = function() {`,\n Template.indent([\n 'return new Promise(function(resolve, reject) {',\n Template.indent([\n `var filename = require('path').join(__dirname, ${JSON.stringify(\n rootOutputDir,\n )} + ${RuntimeGlobals.getUpdateManifestFilename}());`,\n \"require('fs').readFile(filename, 'utf-8', function(err, content) {\",\n Template.indent([\n 'if(err) {',\n Template.indent([\n 'if(err.code === \"ENOENT\") return resolve();',\n 'return reject(err);',\n ]),\n '}',\n 'try { resolve(JSON.parse(content)); }',\n 'catch(e) { reject(e); }',\n ]),\n '});',\n ]),\n '});',\n ]),\n '}',\n ]);\n}\n/**\n * Handles the on chunk load event.\n * @param {boolean} withOnChunkLoad - Flag indicating whether on chunk load event is enabled.\n * @param {any} runtimeTemplate - The runtime template.\n * @returns {string} - The generated on chunk load event handler.\n */\nexport function handleOnChunkLoad(\n withOnChunkLoad: boolean,\n runtimeTemplate: any,\n): string {\n if (withOnChunkLoad) {\n return `${\n RuntimeGlobals.onChunksLoaded\n }.readFileVm = ${runtimeTemplate.returningFunction(\n 'installedChunks[chunkId] === 0',\n 'chunkId',\n )};`;\n } else {\n return '// no on chunks loaded';\n }\n}\n/**\n * Generates the load script for server-side execution. This function creates a script that loads a remote module\n * and executes it in the current context. It supports both browser and Node.js environments.\n * @param {any} runtimeTemplate - The runtime template used to generate the load script.\n * @returns {string} - The generated load script.\n */\nexport function generateLoadScript(runtimeTemplate: any): string {\n return Template.asString([\n '// load script equivalent for server side',\n `${RuntimeGlobals.loadScript} = ${runtimeTemplate.basicFunction(\n 'url, callback, chunkId',\n [\n Template.indent([\n `async function executeLoad(url, callback, name) {\n if (!name) {\n throw new Error('__webpack_require__.l name is required for ' + url);\n }\n const usesInternalRef = name.startsWith('__webpack_require__')\n if (usesInternalRef) {\n const regex = /__webpack_require__\\\\.federation\\\\.instance\\\\.moduleCache\\\\.get\\\\(([^)]+)\\\\)/;\n const match = name.match(regex);\n if (match) {\n name = match[1].replace(/[\"']/g, '');\n }\n }\n try {\n const federation = ${RuntimeGlobals.require}.federation;\n const res = await ${RuntimeGlobals.require}.federation.runtime.loadScriptNode(url, { attrs: {} });\n const enhancedRemote = federation.instance.initRawContainer(name, url, res);\n // use normal global assignment\n if(!usesInternalRef && !globalThis[name]) {\n globalThis[name] = enhancedRemote\n }\n callback(enhancedRemote);\n } catch (error) {\n callback(error);\n }\n\n }`,\n `executeLoad(url, callback, chunkId);`,\n ]),\n ],\n )}`,\n ]);\n}\nexport function generateInstallChunk(\n runtimeTemplate: any,\n withOnChunkLoad: boolean,\n): string {\n return `var installChunk = ${runtimeTemplate.basicFunction('chunk', [\n 'var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;',\n 'for(var moduleId in moreModules) {',\n Template.indent([\n `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,\n Template.indent([\n `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`,\n ]),\n '}',\n ]),\n '}',\n 'if(runtime) runtime(__webpack_require__);',\n 'for(var i = 0; i < chunkIds.length; i++) {',\n Template.indent([\n 'if(installedChunks[chunkIds[i]]) {',\n Template.indent(['installedChunks[chunkIds[i]][0]();']),\n '}',\n 'installedChunks[chunkIds[i]] = 0;',\n ]),\n '}',\n withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : '',\n ])};`;\n}\nexport function generateExternalInstallChunkCode(\n withExternalInstallChunk: boolean,\n debug: boolean | undefined,\n): string {\n if (!withExternalInstallChunk) {\n return '// no external install chunk';\n }\n\n return Template.asString([\n 'module.exports = __webpack_require__;',\n `${RuntimeGlobals.externalInstallChunk} = function(){`,\n debug\n ? `console.debug('node: webpack installing to install chunk id:', arguments['0'].id);`\n : '',\n `return installChunk.apply(this, arguments)};`,\n ]);\n}\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { ModuleFederationRuntimePlugin } from "@module-federation/runtime";
2
+
3
+ //#region src/recordDynamicRemoteEntryHashPlugin.d.ts
4
+ declare const recordDynamicRemoteEntryHashPlugin: () => ModuleFederationRuntimePlugin;
5
+ //#endregion
6
+ export { recordDynamicRemoteEntryHashPlugin as default };
7
+ //# sourceMappingURL=recordDynamicRemoteEntryHashPlugin.d.mts.map
@@ -0,0 +1,6 @@
1
+ import { ModuleFederationRuntimePlugin } from "@module-federation/runtime";
2
+
3
+ //#region src/recordDynamicRemoteEntryHashPlugin.d.ts
4
+ declare const recordDynamicRemoteEntryHashPlugin: () => ModuleFederationRuntimePlugin;
5
+ export = recordDynamicRemoteEntryHashPlugin;
6
+ //# sourceMappingURL=recordDynamicRemoteEntryHashPlugin.d.ts.map
@@ -0,0 +1,28 @@
1
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
2
+
3
+ //#region src/recordDynamicRemoteEntryHashPlugin.ts
4
+ const recordDynamicRemoteEntryHashPlugin = () => ({
5
+ name: "record-dynamic-remote-entry-hash-plugin",
6
+ beforeInit(args) {
7
+ if (!globalThis.mfHashMap) globalThis.mfHashMap = {};
8
+ return args;
9
+ },
10
+ async onLoad(args) {
11
+ const { moduleInstance } = args;
12
+ if (!moduleInstance.remoteInfo) return args;
13
+ const hashmap = globalThis.mfHashMap;
14
+ if (!hashmap) return args;
15
+ const { name, entry } = moduleInstance.remoteInfo;
16
+ if (!hashmap[name]) {
17
+ const hotReloadUtils = await Promise.resolve().then(() => require("./utils/hot-reload.js"));
18
+ await hotReloadUtils.createFetcher(entry, hotReloadUtils.getFetchModule(), name, (hash) => {
19
+ hashmap[name] = hash;
20
+ });
21
+ }
22
+ return args;
23
+ }
24
+ });
25
+
26
+ //#endregion
27
+ exports.default = recordDynamicRemoteEntryHashPlugin;
28
+ //# sourceMappingURL=recordDynamicRemoteEntryHashPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordDynamicRemoteEntryHashPlugin.js","names":[],"sources":["../../src/recordDynamicRemoteEntryHashPlugin.ts"],"sourcesContent":["import type { ModuleFederationRuntimePlugin } from '@module-federation/runtime';\n\nconst recordDynamicRemoteEntryHashPlugin: () => ModuleFederationRuntimePlugin =\n () => ({\n name: 'record-dynamic-remote-entry-hash-plugin',\n beforeInit(args) {\n if (!globalThis.mfHashMap) {\n globalThis.mfHashMap = {};\n }\n\n return args;\n },\n async onLoad(args) {\n const { moduleInstance } = args;\n\n if (!moduleInstance.remoteInfo) {\n return args;\n }\n const hashmap = globalThis.mfHashMap;\n\n if (!hashmap) {\n return args;\n }\n\n const { name, entry } = moduleInstance.remoteInfo;\n\n if (!hashmap[name]) {\n const hotReloadUtils = await import('./utils/hot-reload');\n const fetcher = hotReloadUtils.createFetcher(\n entry,\n hotReloadUtils.getFetchModule(),\n name,\n (hash) => {\n hashmap[name] = hash;\n },\n );\n await fetcher;\n }\n\n return args;\n },\n });\nexport default recordDynamicRemoteEntryHashPlugin;\n"],"mappings":";;;AAEA,MAAM,4CACG;CACL,MAAM;CACN,WAAW,MAAM;AACf,MAAI,CAAC,WAAW,UACd,YAAW,YAAY,EAAE;AAG3B,SAAO;;CAET,MAAM,OAAO,MAAM;EACjB,MAAM,EAAE,mBAAmB;AAE3B,MAAI,CAAC,eAAe,WAClB,QAAO;EAET,MAAM,UAAU,WAAW;AAE3B,MAAI,CAAC,QACH,QAAO;EAGT,MAAM,EAAE,MAAM,UAAU,eAAe;AAEvC,MAAI,CAAC,QAAQ,OAAO;GAClB,MAAM,iBAAiB,2CAAM;AAS7B,SARgB,eAAe,cAC7B,OACA,eAAe,gBAAgB,EAC/B,OACC,SAAS;AACR,YAAQ,QAAQ;KAEnB;;AAIH,SAAO;;CAEV"}
@@ -0,0 +1,26 @@
1
+ //#region src/recordDynamicRemoteEntryHashPlugin.ts
2
+ const recordDynamicRemoteEntryHashPlugin = () => ({
3
+ name: "record-dynamic-remote-entry-hash-plugin",
4
+ beforeInit(args) {
5
+ if (!globalThis.mfHashMap) globalThis.mfHashMap = {};
6
+ return args;
7
+ },
8
+ async onLoad(args) {
9
+ const { moduleInstance } = args;
10
+ if (!moduleInstance.remoteInfo) return args;
11
+ const hashmap = globalThis.mfHashMap;
12
+ if (!hashmap) return args;
13
+ const { name, entry } = moduleInstance.remoteInfo;
14
+ if (!hashmap[name]) {
15
+ const hotReloadUtils = await import("./utils/hot-reload.mjs");
16
+ await hotReloadUtils.createFetcher(entry, hotReloadUtils.getFetchModule(), name, (hash) => {
17
+ hashmap[name] = hash;
18
+ });
19
+ }
20
+ return args;
21
+ }
22
+ });
23
+
24
+ //#endregion
25
+ export { recordDynamicRemoteEntryHashPlugin as default };
26
+ //# sourceMappingURL=recordDynamicRemoteEntryHashPlugin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordDynamicRemoteEntryHashPlugin.mjs","names":[],"sources":["../../src/recordDynamicRemoteEntryHashPlugin.ts"],"sourcesContent":["import type { ModuleFederationRuntimePlugin } from '@module-federation/runtime';\n\nconst recordDynamicRemoteEntryHashPlugin: () => ModuleFederationRuntimePlugin =\n () => ({\n name: 'record-dynamic-remote-entry-hash-plugin',\n beforeInit(args) {\n if (!globalThis.mfHashMap) {\n globalThis.mfHashMap = {};\n }\n\n return args;\n },\n async onLoad(args) {\n const { moduleInstance } = args;\n\n if (!moduleInstance.remoteInfo) {\n return args;\n }\n const hashmap = globalThis.mfHashMap;\n\n if (!hashmap) {\n return args;\n }\n\n const { name, entry } = moduleInstance.remoteInfo;\n\n if (!hashmap[name]) {\n const hotReloadUtils = await import('./utils/hot-reload');\n const fetcher = hotReloadUtils.createFetcher(\n entry,\n hotReloadUtils.getFetchModule(),\n name,\n (hash) => {\n hashmap[name] = hash;\n },\n );\n await fetcher;\n }\n\n return args;\n },\n });\nexport default recordDynamicRemoteEntryHashPlugin;\n"],"mappings":";AAEA,MAAM,4CACG;CACL,MAAM;CACN,WAAW,MAAM;AACf,MAAI,CAAC,WAAW,UACd,YAAW,YAAY,EAAE;AAG3B,SAAO;;CAET,MAAM,OAAO,MAAM;EACjB,MAAM,EAAE,mBAAmB;AAE3B,MAAI,CAAC,eAAe,WAClB,QAAO;EAET,MAAM,UAAU,WAAW;AAE3B,MAAI,CAAC,QACH,QAAO;EAGT,MAAM,EAAE,MAAM,UAAU,eAAe;AAEvC,MAAI,CAAC,QAAQ,OAAO;GAClB,MAAM,iBAAiB,MAAM,OAAO;AASpC,SARgB,eAAe,cAC7B,OACA,eAAe,gBAAgB,EAC/B,OACC,SAAS;AACR,YAAQ,QAAQ;KAEnB;;AAIH,SAAO;;CAEV"}
@@ -0,0 +1,27 @@
1
+ import { ModuleFederationRuntimePlugin } from "@module-federation/runtime";
2
+
3
+ //#region src/runtimePlugin.d.ts
4
+ declare const nodeRuntimeImportCache: Map<string, Promise<any>>;
5
+ declare function importNodeModule<T>(name: string): Promise<T>;
6
+ declare const resolveFile: (rootOutputDir: string, chunkId: string) => string;
7
+ declare const returnFromCache: (remoteName: string) => string | null;
8
+ declare const returnFromGlobalInstances: (remoteName: string) => string | null;
9
+ declare const loadFromFs: (filename: string, callback: (err: Error | null, chunk: any) => void) => void;
10
+ declare const fetchAndRun: (url: URL, chunkName: string, callback: (err: Error | null, chunk: any) => void, args: any) => void;
11
+ declare const resolveUrl: (remoteName: string, chunkName: string) => URL | null;
12
+ declare const loadChunk: (strategy: string, chunkId: string, rootOutputDir: string, callback: (err: Error | null, chunk: any) => void, args: any) => void;
13
+ declare const installChunk: (chunk: any, installedChunks: {
14
+ [key: string]: any;
15
+ }) => void;
16
+ declare const deleteChunk: (chunkId: string, installedChunks: {
17
+ [key: string]: any;
18
+ }) => boolean;
19
+ declare const setupScriptLoader: () => void;
20
+ declare const setupChunkHandler: (installedChunks: {
21
+ [key: string]: any;
22
+ }, args: any) => ((chunkId: string, promises: any[]) => void);
23
+ declare const setupWebpackRequirePatching: (handle: (chunkId: string, promises: any[]) => void) => void;
24
+ declare function export_default(): ModuleFederationRuntimePlugin;
25
+ //#endregion
26
+ export { export_default as default, deleteChunk, fetchAndRun, importNodeModule, installChunk, loadChunk, loadFromFs, nodeRuntimeImportCache, resolveFile, resolveUrl, returnFromCache, returnFromGlobalInstances, setupChunkHandler, setupScriptLoader, setupWebpackRequirePatching };
27
+ //# sourceMappingURL=runtimePlugin.d.mts.map
@@ -0,0 +1,27 @@
1
+ import { ModuleFederationRuntimePlugin } from "@module-federation/runtime";
2
+
3
+ //#region src/runtimePlugin.d.ts
4
+ declare const nodeRuntimeImportCache: Map<string, Promise<any>>;
5
+ declare function importNodeModule<T>(name: string): Promise<T>;
6
+ declare const resolveFile: (rootOutputDir: string, chunkId: string) => string;
7
+ declare const returnFromCache: (remoteName: string) => string | null;
8
+ declare const returnFromGlobalInstances: (remoteName: string) => string | null;
9
+ declare const loadFromFs: (filename: string, callback: (err: Error | null, chunk: any) => void) => void;
10
+ declare const fetchAndRun: (url: URL, chunkName: string, callback: (err: Error | null, chunk: any) => void, args: any) => void;
11
+ declare const resolveUrl: (remoteName: string, chunkName: string) => URL | null;
12
+ declare const loadChunk: (strategy: string, chunkId: string, rootOutputDir: string, callback: (err: Error | null, chunk: any) => void, args: any) => void;
13
+ declare const installChunk: (chunk: any, installedChunks: {
14
+ [key: string]: any;
15
+ }) => void;
16
+ declare const deleteChunk: (chunkId: string, installedChunks: {
17
+ [key: string]: any;
18
+ }) => boolean;
19
+ declare const setupScriptLoader: () => void;
20
+ declare const setupChunkHandler: (installedChunks: {
21
+ [key: string]: any;
22
+ }, args: any) => ((chunkId: string, promises: any[]) => void);
23
+ declare const setupWebpackRequirePatching: (handle: (chunkId: string, promises: any[]) => void) => void;
24
+ declare function export_default(): ModuleFederationRuntimePlugin;
25
+ //#endregion
26
+ export { export_default as default, deleteChunk, fetchAndRun, importNodeModule, installChunk, loadChunk, loadFromFs, nodeRuntimeImportCache, resolveFile, resolveUrl, returnFromCache, returnFromGlobalInstances, setupChunkHandler, setupScriptLoader, setupWebpackRequirePatching };
27
+ //# sourceMappingURL=runtimePlugin.d.ts.map
@@ -0,0 +1,242 @@
1
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
2
+
3
+ //#region src/runtimePlugin.ts
4
+ const nodeRuntimeImportCache = /* @__PURE__ */ new Map();
5
+ const CHUNK_PREVIEW_LENGTH = 240;
6
+ const getChunkPreview = (content) => content.slice(0, CHUNK_PREVIEW_LENGTH).replace(/\s+/g, " ").trim();
7
+ const enrichChunkExecutionError = (error, options) => {
8
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
9
+ const preview = getChunkPreview(options.content);
10
+ const details = [
11
+ `Federated chunk execution failed.`,
12
+ `chunk: ${options.chunkName}`,
13
+ `source: ${options.source}`,
14
+ `location: ${options.location}`
15
+ ];
16
+ if (options.hostName) details.push(`host: ${options.hostName}`);
17
+ if (options.resolution) {
18
+ details.push(`resolved-from: ${options.resolution.resolvedFrom}`);
19
+ if (options.resolution.remoteName) details.push(`remote: ${options.resolution.remoteName}`);
20
+ if (options.resolution.publicPath) details.push(`public-path: ${options.resolution.publicPath}`);
21
+ if (options.resolution.rootOutputDir) details.push(`root-output-dir: ${options.resolution.rootOutputDir}`);
22
+ if (options.resolution.remoteEntryUrl) details.push(`remote-entry: ${options.resolution.remoteEntryUrl}`);
23
+ }
24
+ if (preview) details.push(`preview: ${preview}`);
25
+ normalizedError.message = `${normalizedError.message}\n${details.join("\n")}`;
26
+ Object.assign(normalizedError, {
27
+ chunkName: options.chunkName,
28
+ chunkLocation: options.location,
29
+ chunkSource: options.source,
30
+ chunkPreview: preview,
31
+ chunkHostName: options.hostName,
32
+ chunkResolution: options.resolution
33
+ });
34
+ return normalizedError;
35
+ };
36
+ function importNodeModule(name) {
37
+ if (!name) throw new Error("import specifier is required");
38
+ if (nodeRuntimeImportCache.has(name)) return nodeRuntimeImportCache.get(name);
39
+ const promise = new Function("name", `return import(name)`)(name).then((res) => res.default).catch((error) => {
40
+ console.error(`Error importing module ${name}:`, error);
41
+ nodeRuntimeImportCache.delete(name);
42
+ throw error;
43
+ });
44
+ nodeRuntimeImportCache.set(name, promise);
45
+ return promise;
46
+ }
47
+ const resolveFile = (rootOutputDir, chunkId) => {
48
+ return __non_webpack_require__("path").join(__dirname, rootOutputDir + __webpack_require__.u(chunkId));
49
+ };
50
+ const returnFromCache = (remoteName) => {
51
+ const federationInstances = new Function("return globalThis")()["__FEDERATION__"]["__INSTANCES__"];
52
+ for (const instance of federationInstances) {
53
+ const moduleContainer = instance.moduleCache.get(remoteName);
54
+ if (moduleContainer?.remoteInfo) return moduleContainer.remoteInfo.entry;
55
+ }
56
+ return null;
57
+ };
58
+ const returnFromGlobalInstances = (remoteName) => {
59
+ const federationInstances = new Function("return globalThis")()["__FEDERATION__"]["__INSTANCES__"];
60
+ for (const instance of federationInstances) for (const remote of instance.options.remotes) if (remote.name === remoteName || remote.alias === remoteName) {
61
+ console.log("Backup remote entry found:", remote.entry);
62
+ return remote.entry;
63
+ }
64
+ return null;
65
+ };
66
+ const loadFromFs = (filename, callback) => {
67
+ const fs = __non_webpack_require__("fs");
68
+ const path = __non_webpack_require__("path");
69
+ const vm = __non_webpack_require__("vm");
70
+ if (fs.existsSync(filename)) fs.readFile(filename, "utf-8", (err, content) => {
71
+ if (err) return callback(err, null);
72
+ const chunk = {};
73
+ try {
74
+ new vm.Script(`(function(exports, require, __dirname, __filename) {${content}\n})`, {
75
+ filename,
76
+ importModuleDynamically: vm.constants?.USE_MAIN_CONTEXT_DEFAULT_LOADER ?? importNodeModule
77
+ }).runInThisContext()(chunk, __non_webpack_require__, path.dirname(filename), filename);
78
+ callback(null, chunk);
79
+ } catch (e) {
80
+ callback(enrichChunkExecutionError(e, {
81
+ chunkName: path.basename(filename),
82
+ location: filename,
83
+ source: "filesystem",
84
+ content
85
+ }), null);
86
+ }
87
+ });
88
+ else callback(/* @__PURE__ */ new Error(`File ${filename} does not exist`), null);
89
+ };
90
+ const fetchAndRun = (url, chunkName, callback, args) => {
91
+ (typeof fetch === "undefined" ? importNodeModule("node-fetch").then((mod) => mod.default) : Promise.resolve(fetch)).then((fetchFunction) => {
92
+ return args.origin.loaderHook.lifecycle.fetch.emit(url.href, {}).then((res) => {
93
+ if (!res || !(res instanceof Response)) return fetchFunction(url.href).then((response) => response.text());
94
+ return res.text();
95
+ });
96
+ }).then((data) => {
97
+ const chunk = {};
98
+ const hostName = args?.origin?.options?.name || args?.origin?.name;
99
+ const resolution = url.mfMetadata;
100
+ try {
101
+ eval(`(function(exports, require, __dirname, __filename) {${data}\n})`)(chunk, __non_webpack_require__, url.pathname.split("/").slice(0, -1).join("/"), chunkName);
102
+ callback(null, chunk);
103
+ } catch (e) {
104
+ callback(enrichChunkExecutionError(e, {
105
+ chunkName,
106
+ location: url.href,
107
+ source: "remote-url",
108
+ content: data,
109
+ hostName,
110
+ resolution
111
+ }), null);
112
+ }
113
+ }).catch((err) => callback(err, null));
114
+ };
115
+ const resolveUrl = (remoteName, chunkName) => {
116
+ try {
117
+ return Object.assign(new URL(chunkName, __webpack_require__.p), { mfMetadata: {
118
+ chunkName,
119
+ publicPath: __webpack_require__.p,
120
+ remoteName,
121
+ rootOutputDir: __webpack_require__.federation.rootOutputDir || "",
122
+ resolvedFrom: "public-path"
123
+ } });
124
+ } catch {
125
+ const entryUrl = returnFromCache(remoteName) || returnFromGlobalInstances(remoteName);
126
+ if (!entryUrl) return null;
127
+ const url = new URL(entryUrl);
128
+ const path = __non_webpack_require__("path");
129
+ const urlPath = url.pathname;
130
+ const lastSlashIndex = urlPath.lastIndexOf("/");
131
+ const directoryPath = lastSlashIndex >= 0 ? urlPath.substring(0, lastSlashIndex + 1) : "/";
132
+ const rootDir = __webpack_require__.federation.rootOutputDir || "";
133
+ const combinedPath = path.join(directoryPath, rootDir, chunkName).replace(/\\/g, "/");
134
+ return Object.assign(new URL(combinedPath, url.origin), { mfMetadata: {
135
+ chunkName,
136
+ publicPath: __webpack_require__.p,
137
+ remoteName,
138
+ rootOutputDir: rootDir,
139
+ resolvedFrom: "remote-entry-fallback",
140
+ remoteEntryUrl: entryUrl
141
+ } });
142
+ }
143
+ };
144
+ const loadChunk = (strategy, chunkId, rootOutputDir, callback, args) => {
145
+ if (strategy === "filesystem") return loadFromFs(resolveFile(rootOutputDir, chunkId), callback);
146
+ const url = resolveUrl(rootOutputDir, chunkId);
147
+ if (!url) return callback(null, {
148
+ modules: {},
149
+ ids: [],
150
+ runtime: null
151
+ });
152
+ fetchAndRun(url, chunkId, callback, args);
153
+ };
154
+ const installChunk = (chunk, installedChunks) => {
155
+ for (const moduleId in chunk.modules) __webpack_require__.m[moduleId] = chunk.modules[moduleId];
156
+ if (chunk.runtime) chunk.runtime(__webpack_require__);
157
+ for (const chunkId of chunk.ids) {
158
+ if (installedChunks[chunkId]) installedChunks[chunkId][0]();
159
+ installedChunks[chunkId] = 0;
160
+ }
161
+ };
162
+ const deleteChunk = (chunkId, installedChunks) => {
163
+ delete installedChunks[chunkId];
164
+ return true;
165
+ };
166
+ const setupScriptLoader = () => {
167
+ __webpack_require__.l = (url, done, key, chunkId) => {
168
+ if (!key || chunkId) throw new Error(`__webpack_require__.l name is required for ${url}`);
169
+ __webpack_require__.federation.runtime.loadScriptNode(url, { attrs: { globalName: key } }).then((res) => {
170
+ const enhancedRemote = __webpack_require__.federation.instance.initRawContainer(key, url, res);
171
+ new Function("return globalThis")()[key] = enhancedRemote;
172
+ done(enhancedRemote);
173
+ }).catch(done);
174
+ };
175
+ };
176
+ const setupChunkHandler = (installedChunks, args) => {
177
+ return (chunkId, promises) => {
178
+ let installedChunkData = installedChunks[chunkId];
179
+ if (installedChunkData !== 0) if (installedChunkData) promises.push(installedChunkData[2]);
180
+ else if (__webpack_require__.federation.chunkMatcher ? __webpack_require__.federation.chunkMatcher(chunkId) : true) {
181
+ const promise = new Promise((resolve, reject) => {
182
+ installedChunkData = installedChunks[chunkId] = [resolve, reject];
183
+ const fs = typeof process !== "undefined" ? __non_webpack_require__("fs") : false;
184
+ const filename = typeof process !== "undefined" ? resolveFile(__webpack_require__.federation.rootOutputDir || "", chunkId) : false;
185
+ if (fs && fs.existsSync(filename)) loadChunk("filesystem", chunkId, __webpack_require__.federation.rootOutputDir || "", (err, chunk) => {
186
+ if (err) return deleteChunk(chunkId, installedChunks) && reject(err);
187
+ if (chunk) installChunk(chunk, installedChunks);
188
+ resolve(chunk);
189
+ }, args);
190
+ else {
191
+ const chunkName = __webpack_require__.u(chunkId);
192
+ loadChunk(typeof process === "undefined" ? "http-eval" : "http-vm", chunkName, __webpack_require__.federation.initOptions.name, (err, chunk) => {
193
+ if (err) return deleteChunk(chunkId, installedChunks) && reject(err);
194
+ if (chunk) installChunk(chunk, installedChunks);
195
+ resolve(chunk);
196
+ }, args);
197
+ }
198
+ });
199
+ promises.push(installedChunkData[2] = promise);
200
+ } else installedChunks[chunkId] = 0;
201
+ };
202
+ };
203
+ const setupWebpackRequirePatching = (handle) => {
204
+ if (__webpack_require__.f) {
205
+ if (__webpack_require__.f.require) {
206
+ console.warn("\x1B[33m%s\x1B[0m", "CAUTION: build target is not set to \"async-node\", attempting to patch additional chunk handlers. This may not work");
207
+ __webpack_require__.f.require = handle;
208
+ }
209
+ if (__webpack_require__.f.readFileVm) __webpack_require__.f.readFileVm = handle;
210
+ }
211
+ };
212
+ function runtimePlugin_default() {
213
+ return {
214
+ name: "node-federation-plugin",
215
+ beforeInit(args) {
216
+ (() => {
217
+ const installedChunks = {};
218
+ setupScriptLoader();
219
+ setupWebpackRequirePatching(setupChunkHandler(installedChunks, args));
220
+ })();
221
+ return args;
222
+ }
223
+ };
224
+ }
225
+
226
+ //#endregion
227
+ exports.default = runtimePlugin_default;
228
+ exports.deleteChunk = deleteChunk;
229
+ exports.fetchAndRun = fetchAndRun;
230
+ exports.importNodeModule = importNodeModule;
231
+ exports.installChunk = installChunk;
232
+ exports.loadChunk = loadChunk;
233
+ exports.loadFromFs = loadFromFs;
234
+ exports.nodeRuntimeImportCache = nodeRuntimeImportCache;
235
+ exports.resolveFile = resolveFile;
236
+ exports.resolveUrl = resolveUrl;
237
+ exports.returnFromCache = returnFromCache;
238
+ exports.returnFromGlobalInstances = returnFromGlobalInstances;
239
+ exports.setupChunkHandler = setupChunkHandler;
240
+ exports.setupScriptLoader = setupScriptLoader;
241
+ exports.setupWebpackRequirePatching = setupWebpackRequirePatching;
242
+ //# sourceMappingURL=runtimePlugin.js.map