@module-federation/nextjs-mf 5.3.0 → 5.3.2
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.
- package/lib/ModuleFederationPlugin.js +80 -0
- package/lib/NextFederationPlugin.js +1554 -1
- package/lib/include-defaults.js +1 -3
- package/lib/internal.js +241 -0
- package/lib/loaders/UrlNode.js +1 -7
- package/lib/loaders/helpers.js +3 -10
- package/lib/loaders/nextPageMapLoader.js +5 -19
- package/lib/plugins/DevHmrFixInvalidPongPlugin.js +1 -6
- package/lib/utils.js +7 -0
- package/node-plugin/README.md +27 -0
- package/node-plugin/package.json +4 -0
- package/node-plugin/streaming/CommonJsChunkLoadingPlugin.js +89 -0
- package/node-plugin/streaming/LoadFileChunkLoadingRuntimeModule.js +410 -0
- package/node-plugin/streaming/NodeRuntime.js +245 -0
- package/node-plugin/streaming/index.js +42 -0
- package/node-plugin/streaming/loadScript.js +51 -0
- package/package.json +3 -3
- package/lib/NextFederationPlugin2.js +0 -536
- package/lib/_virtual/UrlNode.js +0 -8
- package/lib/_virtual/_commonjsHelpers.js +0 -26
- package/lib/_virtual/helpers.js +0 -7
- package/lib/_virtual/nextPageMapLoader.js +0 -7
package/lib/include-defaults.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
// __webpack_init_sharing__('default');
|
|
3
|
-
// }
|
|
1
|
+
// this is needed to ensure webpack does not attempt to tree shake unused modules. Since these should always come from host
|
|
4
2
|
require('react');
|
|
5
3
|
require('react-dom');
|
|
6
4
|
require('next/link');
|
package/lib/internal.js
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { parseOptions } from 'webpack/lib/container/options';
|
|
2
|
+
import { isRequiredVersion } from 'webpack/lib/sharing/utils';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
// the share scope we attach by default
|
|
6
|
+
// in hosts we re-key them to prevent webpack moving the modules into their own chunks (cause eager error)
|
|
7
|
+
// in remote these are marked as import:false as we always expect the host to prove them
|
|
8
|
+
export const DEFAULT_SHARE_SCOPE = {
|
|
9
|
+
react: {
|
|
10
|
+
singleton: true,
|
|
11
|
+
requiredVersion: false,
|
|
12
|
+
},
|
|
13
|
+
'react/jsx-runtime': {
|
|
14
|
+
singleton: true,
|
|
15
|
+
requiredVersion: false,
|
|
16
|
+
},
|
|
17
|
+
'react-dom': {
|
|
18
|
+
singleton: true,
|
|
19
|
+
requiredVersion: false,
|
|
20
|
+
},
|
|
21
|
+
'next/dynamic': {
|
|
22
|
+
requiredVersion: false,
|
|
23
|
+
singleton: true,
|
|
24
|
+
},
|
|
25
|
+
'styled-jsx': {
|
|
26
|
+
requiredVersion: false,
|
|
27
|
+
singleton: true,
|
|
28
|
+
},
|
|
29
|
+
'next/link': {
|
|
30
|
+
requiredVersion: false,
|
|
31
|
+
singleton: true,
|
|
32
|
+
},
|
|
33
|
+
'next/router': {
|
|
34
|
+
requiredVersion: false,
|
|
35
|
+
singleton: true,
|
|
36
|
+
},
|
|
37
|
+
'next/script': {
|
|
38
|
+
requiredVersion: false,
|
|
39
|
+
singleton: true,
|
|
40
|
+
},
|
|
41
|
+
'next/head': {
|
|
42
|
+
requiredVersion: false,
|
|
43
|
+
singleton: true,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
// put host infront of any shared module key, so "hostreact"
|
|
47
|
+
export const reKeyHostShared = (options) => {
|
|
48
|
+
return Object.entries({
|
|
49
|
+
...(options || {}),
|
|
50
|
+
...DEFAULT_SHARE_SCOPE,
|
|
51
|
+
}).reduce((acc, item) => {
|
|
52
|
+
const [itemKey, shareOptions] = item;
|
|
53
|
+
|
|
54
|
+
const shareKey = 'host' + (item.shareKey || itemKey);
|
|
55
|
+
acc[shareKey] = shareOptions;
|
|
56
|
+
if (!shareOptions.import) {
|
|
57
|
+
acc[shareKey].import = itemKey;
|
|
58
|
+
}
|
|
59
|
+
if (!shareOptions.shareKey) {
|
|
60
|
+
acc[shareKey].shareKey = itemKey;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (DEFAULT_SHARE_SCOPE[itemKey]) {
|
|
64
|
+
acc[shareKey].packageName = itemKey;
|
|
65
|
+
}
|
|
66
|
+
return acc;
|
|
67
|
+
}, {});
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// split the @ syntax into url and global
|
|
71
|
+
export const extractUrlAndGlobal = (urlAndGlobal) => {
|
|
72
|
+
const index = urlAndGlobal.indexOf('@');
|
|
73
|
+
if (index <= 0 || index === urlAndGlobal.length - 1) {
|
|
74
|
+
throw new Error(`Invalid request "${urlAndGlobal}"`);
|
|
75
|
+
}
|
|
76
|
+
return [urlAndGlobal.substring(index + 1), urlAndGlobal.substring(0, index)];
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// browser template to convert remote into promise new promise and use require.loadChunk to load the chunk
|
|
80
|
+
export const generateRemoteTemplate = (url, global) => {
|
|
81
|
+
return `promise new Promise(function (resolve, reject) {
|
|
82
|
+
var __webpack_error__ = new Error();
|
|
83
|
+
if (typeof ${global} !== 'undefined') return resolve();
|
|
84
|
+
__webpack_require__.l(
|
|
85
|
+
${JSON.stringify(url)},
|
|
86
|
+
function (event) {
|
|
87
|
+
if (typeof ${global} !== 'undefined') return resolve();
|
|
88
|
+
var errorType = event && (event.type === 'load' ? 'missing' : event.type);
|
|
89
|
+
var realSrc = event && event.target && event.target.src;
|
|
90
|
+
__webpack_error__.message =
|
|
91
|
+
'Loading script failed.\\n(' + errorType + ': ' + realSrc + ')';
|
|
92
|
+
__webpack_error__.name = 'ScriptExternalLoadError';
|
|
93
|
+
__webpack_error__.type = errorType;
|
|
94
|
+
__webpack_error__.request = realSrc;
|
|
95
|
+
reject(__webpack_error__);
|
|
96
|
+
},
|
|
97
|
+
${JSON.stringify(global)},
|
|
98
|
+
);
|
|
99
|
+
}).then(function () {
|
|
100
|
+
const proxy = {
|
|
101
|
+
get: ${global}.get,
|
|
102
|
+
init: function(shareScope) {
|
|
103
|
+
const handler = {
|
|
104
|
+
get(target, prop) {
|
|
105
|
+
if (target[prop]) {
|
|
106
|
+
Object.values(target[prop]).forEach(function(o) {
|
|
107
|
+
if(o.from === '_N_E') {
|
|
108
|
+
o.loaded = 1
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
return target[prop]
|
|
113
|
+
},
|
|
114
|
+
set(target, property, value, receiver) {
|
|
115
|
+
if (target[property]) {
|
|
116
|
+
return target[property]
|
|
117
|
+
}
|
|
118
|
+
target[property] = value
|
|
119
|
+
return true
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
${global}.init(new Proxy(shareScope, handler))
|
|
124
|
+
} catch (e) {
|
|
125
|
+
|
|
126
|
+
}
|
|
127
|
+
${global}.__initialized = true
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (!${global}.__initialized) {
|
|
131
|
+
proxy.init()
|
|
132
|
+
}
|
|
133
|
+
return proxy
|
|
134
|
+
})`;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const parseShareOptions = (options) => {
|
|
138
|
+
const sharedOptions = parseOptions(
|
|
139
|
+
options.shared,
|
|
140
|
+
(item, key) => {
|
|
141
|
+
if (typeof item !== 'string')
|
|
142
|
+
throw new Error('Unexpected array in shared');
|
|
143
|
+
/** @type {SharedConfig} */
|
|
144
|
+
const config =
|
|
145
|
+
item === key || !isRequiredVersion(item)
|
|
146
|
+
? {
|
|
147
|
+
import: item,
|
|
148
|
+
}
|
|
149
|
+
: {
|
|
150
|
+
import: key,
|
|
151
|
+
requiredVersion: item,
|
|
152
|
+
};
|
|
153
|
+
return config;
|
|
154
|
+
},
|
|
155
|
+
(item) => item
|
|
156
|
+
);
|
|
157
|
+
return sharedOptions.reduce((acc, [key, options]) => {
|
|
158
|
+
acc[key] = {
|
|
159
|
+
import: options.import,
|
|
160
|
+
shareKey: options.shareKey || key,
|
|
161
|
+
shareScope: options.shareScope,
|
|
162
|
+
requiredVersion: options.requiredVersion,
|
|
163
|
+
strictVersion: options.strictVersion,
|
|
164
|
+
singleton: options.singleton,
|
|
165
|
+
packageName: options.packageName,
|
|
166
|
+
eager: options.eager,
|
|
167
|
+
};
|
|
168
|
+
return acc;
|
|
169
|
+
}, {});
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// shared packages must be compiled into webpack bundle, not require() pass through
|
|
173
|
+
export const internalizeSharedPackages = (options, compiler) => {
|
|
174
|
+
//TODO: should use this util for other areas where we read MF options from userland
|
|
175
|
+
if (!options.shared) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const sharedOptions = parseShareOptions(options);
|
|
179
|
+
// get share keys from user, filter out ones that need to be external
|
|
180
|
+
const internalizableKeys = Object.keys(sharedOptions).filter((key) => {
|
|
181
|
+
if (!DEFAULT_SHARE_SCOPE[key]) {
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
if (!DEFAULT_SHARE_SCOPE[sharedOptions[key].import]) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
// take original externals regex
|
|
189
|
+
const backupExternals = compiler.options.externals[0];
|
|
190
|
+
// if externals is a function (like when you're not running in serverless mode or creating a single build)
|
|
191
|
+
if (typeof backupExternals === 'function') {
|
|
192
|
+
// replace externals function with short-circuit, or fall back to original algo
|
|
193
|
+
compiler.options.externals[0] = (mod, callback) => {
|
|
194
|
+
if (!internalizableKeys.some((v) => mod.request.includes(v))) {
|
|
195
|
+
return backupExternals(mod, callback);
|
|
196
|
+
}
|
|
197
|
+
// bundle it
|
|
198
|
+
return Promise.resolve();
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
export const externalizedShares = Object.entries(DEFAULT_SHARE_SCOPE).reduce(
|
|
204
|
+
(acc, item) => {
|
|
205
|
+
const [key, value] = item;
|
|
206
|
+
acc[key] = { ...value, import: false };
|
|
207
|
+
if (key === 'react/jsx-runtime') {
|
|
208
|
+
delete acc[key].import;
|
|
209
|
+
}
|
|
210
|
+
return acc;
|
|
211
|
+
},
|
|
212
|
+
{}
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
// determine output base path, derives .next folder location
|
|
216
|
+
export const getOutputPath = (compiler) => {
|
|
217
|
+
const isServer = compiler.options.target !== 'client';
|
|
218
|
+
let outputPath = compiler.options.output.path.split(path.sep);
|
|
219
|
+
const foundIndex = outputPath.findIndex((i) => {
|
|
220
|
+
return i === (isServer ? 'server' : 'static');
|
|
221
|
+
});
|
|
222
|
+
outputPath = outputPath
|
|
223
|
+
.slice(0, foundIndex > 0 ? foundIndex : outputPath.length)
|
|
224
|
+
.join(path.sep);
|
|
225
|
+
|
|
226
|
+
return outputPath;
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export const removePlugins = [
|
|
230
|
+
'NextJsRequireCacheHotReloader',
|
|
231
|
+
'BuildManifestPlugin',
|
|
232
|
+
'WellKnownErrorsPlugin',
|
|
233
|
+
'WebpackBuildEventsPlugin',
|
|
234
|
+
'HotModuleReplacementPlugin',
|
|
235
|
+
'NextMiniCssExtractPlugin',
|
|
236
|
+
'NextFederationPlugin',
|
|
237
|
+
'CopyFilePlugin',
|
|
238
|
+
'ProfilingPlugin',
|
|
239
|
+
'DropClientPage',
|
|
240
|
+
'ReactFreshWebpackPlugin',
|
|
241
|
+
];
|
package/lib/loaders/UrlNode.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
1
|
/**
|
|
6
2
|
* 🛑🛑🛑 Attention! 🛑🛑🛑
|
|
7
3
|
* Do not add type definitions to this file!!
|
|
@@ -19,7 +15,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
19
15
|
* It was copied from
|
|
20
16
|
* @see https://github.com/vercel/next.js/blob/canary/packages/next/shared/lib/router/utils/sorted-routes.ts
|
|
21
17
|
*/
|
|
22
|
-
class UrlNode {
|
|
18
|
+
export class UrlNode {
|
|
23
19
|
placeholder = true;
|
|
24
20
|
children = new Map();
|
|
25
21
|
slugName = null;
|
|
@@ -211,5 +207,3 @@ class UrlNode {
|
|
|
211
207
|
._insert(urlPaths.slice(1), slugNames, isCatchAll);
|
|
212
208
|
}
|
|
213
209
|
}
|
|
214
|
-
|
|
215
|
-
exports.UrlNode = UrlNode;
|
package/lib/loaders/helpers.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var helpers = require('../_virtual/helpers.js');
|
|
4
|
-
|
|
5
1
|
/**
|
|
6
2
|
* Inject a loader into the current module rule.
|
|
7
3
|
* This function mutates `rule` argument!
|
|
8
4
|
*/
|
|
9
|
-
|
|
10
|
-
helpers.__exports.injectRuleLoader = function injectRuleLoader(rule, loader) {
|
|
5
|
+
module.exports.injectRuleLoader = function injectRuleLoader(rule, loader) {
|
|
11
6
|
if (rule.loader) {
|
|
12
7
|
rule.use = [loader, { loader: rule.loader, options: rule.options }];
|
|
13
8
|
delete rule.loader;
|
|
@@ -20,7 +15,7 @@ helpers.__exports.injectRuleLoader = function injectRuleLoader(rule, loader) {
|
|
|
20
15
|
/**
|
|
21
16
|
* Check that current module rule has a loader with the provided name.
|
|
22
17
|
*/
|
|
23
|
-
|
|
18
|
+
module.exports.hasLoader = function hasLoader(rule, loaderName) {
|
|
24
19
|
if (rule.loader === loaderName) {
|
|
25
20
|
return true;
|
|
26
21
|
} else if (rule.use) {
|
|
@@ -39,7 +34,7 @@ helpers.__exports.hasLoader = function hasLoader(rule, loaderName) {
|
|
|
39
34
|
return false;
|
|
40
35
|
};
|
|
41
36
|
|
|
42
|
-
|
|
37
|
+
module.exports.toDisplayErrors = function toDisplayErrors(err) {
|
|
43
38
|
return err
|
|
44
39
|
.map((error) => {
|
|
45
40
|
let message = error.message;
|
|
@@ -50,5 +45,3 @@ helpers.__exports.toDisplayErrors = function toDisplayErrors(err) {
|
|
|
50
45
|
})
|
|
51
46
|
.join('\n');
|
|
52
47
|
};
|
|
53
|
-
|
|
54
|
-
module.exports = helpers.__exports;
|
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var nextPageMapLoader$1 = require('../_virtual/nextPageMapLoader.js');
|
|
4
|
-
var require$$0 = require('fast-glob');
|
|
5
|
-
var require$$1 = require('fs');
|
|
6
|
-
var UrlNode$1 = require('../_virtual/UrlNode.js');
|
|
7
|
-
|
|
8
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
|
-
|
|
10
|
-
var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
|
|
11
|
-
var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1);
|
|
12
|
-
|
|
13
|
-
const fg = require$$0__default["default"];
|
|
14
|
-
const fs = require$$1__default["default"];
|
|
1
|
+
const fg = require('fast-glob');
|
|
2
|
+
const fs = require('fs');
|
|
15
3
|
|
|
16
4
|
// TODO: import UrlNode from ./client folder when whole project migrates on TypeScript (but right now using JS copy of this class)
|
|
17
5
|
// const UrlNode = require('../client/UrlNode').UrlNode;
|
|
18
|
-
const UrlNode = UrlNode
|
|
6
|
+
const UrlNode = require('./UrlNode').UrlNode;
|
|
19
7
|
|
|
20
8
|
/**
|
|
21
9
|
* Webpack loader which prepares MF map for NextJS pages
|
|
@@ -187,7 +175,5 @@ function preparePageMapV2(pages) {
|
|
|
187
175
|
return result;
|
|
188
176
|
}
|
|
189
177
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
module.exports = nextPageMapLoader$1.nextPageMapLoader.exports;
|
|
178
|
+
module.exports = nextPageMapLoader;
|
|
179
|
+
module.exports.exposeNextjsPages = exposeNextjsPages;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* If HMR through websocket received {"invalid":true, "event":"pong"} event
|
|
5
3
|
* then pages reloads. But for federated page this is unwanted behavior.
|
|
6
4
|
*
|
|
7
5
|
* So this plugin in DEV mode disables page.reload() in HMR for federated pages.
|
|
8
6
|
*/
|
|
9
|
-
|
|
10
7
|
class DevHmrFixInvalidPongPlugin {
|
|
11
8
|
/**
|
|
12
9
|
* Apply the plugin
|
|
@@ -60,6 +57,4 @@ function escapeRegExp(string) {
|
|
|
60
57
|
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
61
58
|
}
|
|
62
59
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
module.exports = DevHmrFixInvalidPongPlugin_1;
|
|
60
|
+
module.exports = DevHmrFixInvalidPongPlugin;
|
package/lib/utils.js
CHANGED
|
@@ -7,11 +7,18 @@ const remoteVars = process.env.REMOTES || {};
|
|
|
7
7
|
const runtimeRemotes = Object.entries(remoteVars).reduce(function (acc, item) {
|
|
8
8
|
const [key, value] = item;
|
|
9
9
|
if (typeof value === 'object' && typeof value.then === 'function') {
|
|
10
|
+
// if its an object with a thennable (eagerly executing function)
|
|
10
11
|
acc[key] = { asyncContainer: value };
|
|
12
|
+
} else if (typeof value === 'function') {
|
|
13
|
+
// if its a function that must be called (lazily executing function)
|
|
14
|
+
acc[key] = { asyncContainer: value() };
|
|
11
15
|
} else if (typeof value === 'string') {
|
|
16
|
+
// if its just a string (global@url)
|
|
12
17
|
const [global, url] = value.split('@');
|
|
13
18
|
acc[key] = { global, url };
|
|
14
19
|
} else {
|
|
20
|
+
// we dont know or currently support this type
|
|
21
|
+
console.log('remotes process', process.env.REMOTES);
|
|
15
22
|
throw new Error(`[mf] Invalid value received for runtime_remote "${key}"`);
|
|
16
23
|
}
|
|
17
24
|
return acc;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# node
|
|
2
|
+
|
|
3
|
+
Software streaming to enable node.js support for browser-like chunk loading
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
const StreamingRuntime = require('../node/streaming');
|
|
7
|
+
const NodeFederation = require('../node/streaming/NodeRuntime');
|
|
8
|
+
|
|
9
|
+
plugins: [
|
|
10
|
+
new StreamingRuntime({
|
|
11
|
+
name: 'website2',
|
|
12
|
+
library: { type: 'commonjs' },
|
|
13
|
+
filename: 'remoteEntry.js',
|
|
14
|
+
exposes: {
|
|
15
|
+
'./SharedComponent': './remoteServer/SharedComponent',
|
|
16
|
+
},
|
|
17
|
+
}),
|
|
18
|
+
new NodeFederation({
|
|
19
|
+
name: 'website2',
|
|
20
|
+
library: { type: 'commonjs' },
|
|
21
|
+
filename: 'remoteEntry.js',
|
|
22
|
+
exposes: {
|
|
23
|
+
'./SharedComponent': './remoteServer/SharedComponent',
|
|
24
|
+
},
|
|
25
|
+
}),
|
|
26
|
+
];
|
|
27
|
+
```
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const RuntimeGlobals = require('webpack/lib/RuntimeGlobals');
|
|
2
|
+
const StartupChunkDependenciesPlugin = require('webpack/lib/runtime/StartupChunkDependenciesPlugin');
|
|
3
|
+
import ChunkLoadingRuntimeModule from './LoadFileChunkLoadingRuntimeModule';
|
|
4
|
+
// const ChunkLoadingRuntimeModule = require('webpack/lib/node/ReadFileChunkLoadingRuntimeModule')
|
|
5
|
+
class CommonJsChunkLoadingPlugin {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.options = options || {};
|
|
8
|
+
this._asyncChunkLoading = this.options.asyncChunkLoading;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Apply the plugin
|
|
13
|
+
* @param {Compiler} compiler the compiler instance
|
|
14
|
+
* @returns {void}
|
|
15
|
+
*/
|
|
16
|
+
apply(compiler) {
|
|
17
|
+
const chunkLoadingValue = this._asyncChunkLoading
|
|
18
|
+
? 'async-node'
|
|
19
|
+
: 'require';
|
|
20
|
+
new StartupChunkDependenciesPlugin({
|
|
21
|
+
chunkLoading: chunkLoadingValue,
|
|
22
|
+
asyncChunkLoading: this._asyncChunkLoading,
|
|
23
|
+
}).apply(compiler);
|
|
24
|
+
compiler.hooks.thisCompilation.tap(
|
|
25
|
+
'CommonJsChunkLoadingPlugin',
|
|
26
|
+
(compilation) => {
|
|
27
|
+
// Always enabled
|
|
28
|
+
const isEnabledForChunk = () => true;
|
|
29
|
+
const onceForChunkSet = new WeakSet();
|
|
30
|
+
const handler = (chunk, set) => {
|
|
31
|
+
if (onceForChunkSet.has(chunk)) return;
|
|
32
|
+
onceForChunkSet.add(chunk);
|
|
33
|
+
if (!isEnabledForChunk(chunk)) return;
|
|
34
|
+
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
|
|
35
|
+
set.add(RuntimeGlobals.hasOwnProperty);
|
|
36
|
+
compilation.addRuntimeModule(
|
|
37
|
+
chunk,
|
|
38
|
+
new ChunkLoadingRuntimeModule(set, this.options, {
|
|
39
|
+
webpack: compiler.webpack,
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
compilation.hooks.runtimeRequirementInTree
|
|
45
|
+
.for(RuntimeGlobals.ensureChunkHandlers)
|
|
46
|
+
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
47
|
+
compilation.hooks.runtimeRequirementInTree
|
|
48
|
+
.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
|
|
49
|
+
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
50
|
+
compilation.hooks.runtimeRequirementInTree
|
|
51
|
+
.for(RuntimeGlobals.hmrDownloadManifest)
|
|
52
|
+
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
53
|
+
compilation.hooks.runtimeRequirementInTree
|
|
54
|
+
.for(RuntimeGlobals.baseURI)
|
|
55
|
+
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
56
|
+
compilation.hooks.runtimeRequirementInTree
|
|
57
|
+
.for(RuntimeGlobals.externalInstallChunk)
|
|
58
|
+
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
59
|
+
compilation.hooks.runtimeRequirementInTree
|
|
60
|
+
.for(RuntimeGlobals.onChunksLoaded)
|
|
61
|
+
.tap('CommonJsChunkLoadingPlugin', handler);
|
|
62
|
+
|
|
63
|
+
compilation.hooks.runtimeRequirementInTree
|
|
64
|
+
.for(RuntimeGlobals.ensureChunkHandlers)
|
|
65
|
+
.tap('CommonJsChunkLoadingPlugin', (chunk, set) => {
|
|
66
|
+
if (!isEnabledForChunk(chunk)) return;
|
|
67
|
+
set.add(RuntimeGlobals.getChunkScriptFilename);
|
|
68
|
+
});
|
|
69
|
+
compilation.hooks.runtimeRequirementInTree
|
|
70
|
+
.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
|
|
71
|
+
.tap('CommonJsChunkLoadingPlugin', (chunk, set) => {
|
|
72
|
+
if (!isEnabledForChunk(chunk)) return;
|
|
73
|
+
set.add(RuntimeGlobals.getChunkUpdateScriptFilename);
|
|
74
|
+
set.add(RuntimeGlobals.moduleCache);
|
|
75
|
+
set.add(RuntimeGlobals.hmrModuleData);
|
|
76
|
+
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
|
|
77
|
+
});
|
|
78
|
+
compilation.hooks.runtimeRequirementInTree
|
|
79
|
+
.for(RuntimeGlobals.hmrDownloadManifest)
|
|
80
|
+
.tap('CommonJsChunkLoadingPlugin', (chunk, set) => {
|
|
81
|
+
if (!isEnabledForChunk(chunk)) return;
|
|
82
|
+
set.add(RuntimeGlobals.getUpdateManifestFilename);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default CommonJsChunkLoadingPlugin;
|