webpack 5.18.0 → 5.20.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.
Potentially problematic release.
This version of webpack might be problematic. Click here for more details.
- package/README.md +10 -47
- package/bin/webpack.js +0 -0
- package/lib/CleanPlugin.js +357 -0
- package/lib/CodeGenerationResults.js +28 -26
- package/lib/Compilation.js +192 -12
- package/lib/Dependency.js +1 -1
- package/lib/FlagDependencyUsagePlugin.js +8 -4
- package/lib/Generator.js +1 -0
- package/lib/ModuleGraph.js +8 -0
- package/lib/ModuleGraphConnection.js +3 -3
- package/lib/ModuleProfile.js +31 -4
- package/lib/NormalModule.js +17 -3
- package/lib/ProgressPlugin.js +12 -10
- package/lib/RuntimeGlobals.js +14 -0
- package/lib/RuntimePlugin.js +8 -0
- package/lib/RuntimeTemplate.js +1 -1
- package/lib/WebpackOptionsApply.js +16 -7
- package/lib/asset/AssetGenerator.js +10 -1
- package/lib/asset/AssetModulesPlugin.js +14 -5
- package/lib/async-modules/AwaitDependenciesInitFragment.js +12 -2
- package/lib/cache/IdleFileCachePlugin.js +9 -3
- package/lib/config/defaults.js +13 -2
- package/lib/config/normalization.js +1 -0
- package/lib/container/ContainerEntryModule.js +4 -1
- package/lib/container/ContainerPlugin.js +4 -2
- package/lib/dependencies/HarmonyCompatibilityDependency.js +5 -4
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +1 -1
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +1 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +13 -5
- package/lib/dependencies/URLDependency.js +9 -4
- package/lib/hmr/LazyCompilationPlugin.js +29 -3
- package/lib/hmr/lazyCompilationBackend.js +2 -3
- package/lib/index.js +4 -0
- package/lib/javascript/JavascriptModulesPlugin.js +2 -2
- package/lib/optimize/InnerGraph.js +28 -0
- package/lib/runtime/AsyncModuleRuntimeModule.js +137 -0
- package/lib/serialization/BinaryMiddleware.js +10 -2
- package/lib/sharing/ShareRuntimeModule.js +1 -1
- package/lib/util/ArrayQueue.js +103 -0
- package/lib/util/AsyncQueue.js +58 -27
- package/lib/util/ParallelismFactorCalculator.js +59 -0
- package/lib/util/fs.js +3 -0
- package/lib/util/runtime.js +135 -24
- package/lib/validateSchema.js +2 -2
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +24 -22
- package/package.json +2 -3
- package/schemas/WebpackOptions.json +65 -0
- package/schemas/_container.json +4 -0
- package/schemas/plugins/container/ContainerPlugin.json +4 -0
- package/schemas/plugins/container/ModuleFederationPlugin.json +4 -0
- package/types.d.ts +111 -19
@@ -7,6 +7,7 @@
|
|
7
7
|
|
8
8
|
const InitFragment = require("../InitFragment");
|
9
9
|
const RuntimeGlobals = require("../RuntimeGlobals");
|
10
|
+
const Template = require("../Template");
|
10
11
|
|
11
12
|
/** @typedef {import("webpack-sources").Source} Source */
|
12
13
|
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
|
@@ -45,11 +46,20 @@ class AwaitDependenciesInitFragment extends InitFragment {
|
|
45
46
|
}
|
46
47
|
if (promises.size === 1) {
|
47
48
|
for (const p of promises) {
|
48
|
-
return
|
49
|
+
return Template.asString([
|
50
|
+
`var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${p}]);`,
|
51
|
+
`${p} = (__webpack_async_dependencies__.then ? await __webpack_async_dependencies__ : __webpack_async_dependencies__)[0];`,
|
52
|
+
""
|
53
|
+
]);
|
49
54
|
}
|
50
55
|
}
|
51
56
|
const sepPromises = Array.from(promises).join(", ");
|
52
|
-
|
57
|
+
// TODO check if destructuring is supported
|
58
|
+
return Template.asString([
|
59
|
+
`var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${sepPromises}]);`,
|
60
|
+
`([${sepPromises}] = __webpack_async_dependencies__.then ? await __webpack_async_dependencies__ : __webpack_async_dependencies__);`,
|
61
|
+
""
|
62
|
+
]);
|
53
63
|
}
|
54
64
|
}
|
55
65
|
|
@@ -127,9 +127,15 @@ class IdleFileCachePlugin {
|
|
127
127
|
});
|
128
128
|
return;
|
129
129
|
}
|
130
|
-
currentIdlePromise = currentIdlePromise
|
131
|
-
strategy.afterAllStored()
|
132
|
-
|
130
|
+
currentIdlePromise = currentIdlePromise
|
131
|
+
.then(() => strategy.afterAllStored())
|
132
|
+
.catch(err => {
|
133
|
+
const logger = compiler.getInfrastructureLogger(
|
134
|
+
"IdleFileCachePlugin"
|
135
|
+
);
|
136
|
+
logger.warn(`Background tasks during idle failed: ${err.message}`);
|
137
|
+
logger.debug(err.stack);
|
138
|
+
});
|
133
139
|
isInitialStore = false;
|
134
140
|
}
|
135
141
|
};
|
package/lib/config/defaults.js
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
const fs = require("fs");
|
8
9
|
const path = require("path");
|
9
10
|
const Template = require("../Template");
|
10
11
|
const { cleverMerge } = require("../util/cleverMerge");
|
@@ -262,9 +263,19 @@ const applyCacheDefaults = (cache, { name, mode }) => {
|
|
262
263
|
F(cache, "name", () => name + "-" + mode);
|
263
264
|
D(cache, "version", "");
|
264
265
|
F(cache, "cacheDirectory", () => {
|
265
|
-
const pkgDir = require("pkg-dir");
|
266
266
|
const cwd = process.cwd();
|
267
|
-
|
267
|
+
let dir = cwd;
|
268
|
+
for (;;) {
|
269
|
+
try {
|
270
|
+
if (fs.statSync(path.join(dir, "package.json")).isFile()) break;
|
271
|
+
// eslint-disable-next-line no-empty
|
272
|
+
} catch (e) {}
|
273
|
+
const parent = path.dirname(dir);
|
274
|
+
if (dir === parent) {
|
275
|
+
dir = undefined;
|
276
|
+
break;
|
277
|
+
}
|
278
|
+
}
|
268
279
|
if (!dir) {
|
269
280
|
return path.resolve(cwd, ".cache/webpack");
|
270
281
|
} else if (process.versions.pnp === "1") {
|
@@ -277,6 +277,7 @@ const getNormalizedWebpackOptions = config => {
|
|
277
277
|
chunkLoading: output.chunkLoading,
|
278
278
|
chunkLoadingGlobal: output.chunkLoadingGlobal,
|
279
279
|
chunkLoadTimeout: output.chunkLoadTimeout,
|
280
|
+
clean: output.clean,
|
280
281
|
compareBeforeEmit: output.compareBeforeEmit,
|
281
282
|
crossOriginLoading: output.crossOriginLoading,
|
282
283
|
devtoolFallbackModuleFilenameTemplate:
|
@@ -31,6 +31,7 @@ const ContainerExposedDependency = require("./ContainerExposedDependency");
|
|
31
31
|
/**
|
32
32
|
* @typedef {Object} ExposeOptions
|
33
33
|
* @property {string[]} import requests to exposed modules (last one is exported)
|
34
|
+
* @property {string} name custom chunk name for the exposed module
|
34
35
|
*/
|
35
36
|
|
36
37
|
const SOURCE_TYPES = new Set(["javascript"]);
|
@@ -107,7 +108,9 @@ class ContainerEntryModule extends Module {
|
|
107
108
|
|
108
109
|
for (const [name, options] of this._exposes) {
|
109
110
|
const block = new AsyncDependenciesBlock(
|
110
|
-
|
111
|
+
{
|
112
|
+
name: options.name
|
113
|
+
},
|
111
114
|
{ name },
|
112
115
|
options.import[options.import.length - 1]
|
113
116
|
);
|
@@ -35,10 +35,12 @@ class ContainerPlugin {
|
|
35
35
|
exposes: parseOptions(
|
36
36
|
options.exposes,
|
37
37
|
item => ({
|
38
|
-
import: Array.isArray(item) ? item : [item]
|
38
|
+
import: Array.isArray(item) ? item : [item],
|
39
|
+
name: undefined
|
39
40
|
}),
|
40
41
|
item => ({
|
41
|
-
import: Array.isArray(item.import) ? item.import : [item.import]
|
42
|
+
import: Array.isArray(item.import) ? item.import : [item.import],
|
43
|
+
name: item.name || undefined
|
42
44
|
})
|
43
45
|
)
|
44
46
|
};
|
@@ -70,15 +70,16 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
|
|
70
70
|
}
|
71
71
|
if (moduleGraph.isAsync(module)) {
|
72
72
|
runtimeRequirements.add(RuntimeGlobals.module);
|
73
|
-
|
74
|
-
if (used) runtimeRequirements.add(RuntimeGlobals.exports);
|
73
|
+
runtimeRequirements.add(RuntimeGlobals.asyncModule);
|
75
74
|
initFragments.push(
|
76
75
|
new InitFragment(
|
77
|
-
`${module.moduleArgument}
|
76
|
+
`${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async (__webpack_handle_async_dependencies__) => {\n`,
|
78
77
|
InitFragment.STAGE_ASYNC_BOUNDARY,
|
79
78
|
0,
|
80
79
|
undefined,
|
81
|
-
|
80
|
+
module.buildMeta.async
|
81
|
+
? `\n__webpack_handle_async_dependencies__();\n}, 1);`
|
82
|
+
: "\n});"
|
82
83
|
)
|
83
84
|
);
|
84
85
|
}
|
@@ -361,7 +361,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|
361
361
|
|
362
362
|
/**
|
363
363
|
* @param {ModuleGraph} moduleGraph module graph
|
364
|
-
* @returns {function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
|
364
|
+
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
|
365
365
|
*/
|
366
366
|
getCondition(moduleGraph) {
|
367
367
|
return (connection, runtime) => {
|
@@ -30,7 +30,7 @@ class HarmonyImportSideEffectDependency extends HarmonyImportDependency {
|
|
30
30
|
|
31
31
|
/**
|
32
32
|
* @param {ModuleGraph} moduleGraph module graph
|
33
|
-
* @returns {function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
|
33
|
+
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
|
34
34
|
*/
|
35
35
|
getCondition(moduleGraph) {
|
36
36
|
return connection => {
|
@@ -6,7 +6,9 @@
|
|
6
6
|
"use strict";
|
7
7
|
|
8
8
|
const Dependency = require("../Dependency");
|
9
|
-
const {
|
9
|
+
const {
|
10
|
+
getDependencyUsedByExportsCondition
|
11
|
+
} = require("../optimize/InnerGraph");
|
10
12
|
const makeSerializable = require("../util/makeSerializable");
|
11
13
|
const propertyAccess = require("../util/propertyAccess");
|
12
14
|
const HarmonyImportDependency = require("./HarmonyImportDependency");
|
@@ -66,7 +68,10 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
|
66
68
|
* @returns {string[]} the imported ids
|
67
69
|
*/
|
68
70
|
getIds(moduleGraph) {
|
69
|
-
|
71
|
+
const meta = moduleGraph.getMetaIfExisting(this);
|
72
|
+
if (meta === undefined) return this.ids;
|
73
|
+
const ids = meta[idsSymbol];
|
74
|
+
return ids !== undefined ? ids : this.ids;
|
70
75
|
}
|
71
76
|
|
72
77
|
/**
|
@@ -80,11 +85,14 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
|
80
85
|
|
81
86
|
/**
|
82
87
|
* @param {ModuleGraph} moduleGraph module graph
|
83
|
-
* @returns {function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
|
88
|
+
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
|
84
89
|
*/
|
85
90
|
getCondition(moduleGraph) {
|
86
|
-
return (
|
87
|
-
|
91
|
+
return getDependencyUsedByExportsCondition(
|
92
|
+
this,
|
93
|
+
this.usedByExports,
|
94
|
+
moduleGraph
|
95
|
+
);
|
88
96
|
}
|
89
97
|
|
90
98
|
/**
|
@@ -6,7 +6,9 @@
|
|
6
6
|
"use strict";
|
7
7
|
|
8
8
|
const RuntimeGlobals = require("../RuntimeGlobals");
|
9
|
-
const {
|
9
|
+
const {
|
10
|
+
getDependencyUsedByExportsCondition
|
11
|
+
} = require("../optimize/InnerGraph");
|
10
12
|
const makeSerializable = require("../util/makeSerializable");
|
11
13
|
const ModuleDependency = require("./ModuleDependency");
|
12
14
|
|
@@ -45,11 +47,14 @@ class URLDependency extends ModuleDependency {
|
|
45
47
|
|
46
48
|
/**
|
47
49
|
* @param {ModuleGraph} moduleGraph module graph
|
48
|
-
* @returns {function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
|
50
|
+
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
|
49
51
|
*/
|
50
52
|
getCondition(moduleGraph) {
|
51
|
-
return (
|
52
|
-
|
53
|
+
return getDependencyUsedByExportsCondition(
|
54
|
+
this,
|
55
|
+
this.usedByExports,
|
56
|
+
moduleGraph
|
57
|
+
);
|
53
58
|
}
|
54
59
|
|
55
60
|
serialize(context) {
|
@@ -32,6 +32,27 @@ const { registerNotSerializable } = require("../util/serialization");
|
|
32
32
|
/** @typedef {import("../util/Hash")} Hash */
|
33
33
|
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
34
34
|
|
35
|
+
/**
|
36
|
+
* @param {undefined|string|RegExp|Function} test test option
|
37
|
+
* @param {Module} module the module
|
38
|
+
* @returns {boolean} true, if the module should be selected
|
39
|
+
*/
|
40
|
+
const checkTest = (test, module) => {
|
41
|
+
if (test === undefined) return true;
|
42
|
+
if (typeof test === "function") {
|
43
|
+
return test(module);
|
44
|
+
}
|
45
|
+
if (typeof test === "string") {
|
46
|
+
const name = module.nameForCondition();
|
47
|
+
return name && name.startsWith(test);
|
48
|
+
}
|
49
|
+
if (test instanceof RegExp) {
|
50
|
+
const name = module.nameForCondition();
|
51
|
+
return name && test.test(name);
|
52
|
+
}
|
53
|
+
return false;
|
54
|
+
};
|
55
|
+
|
35
56
|
const TYPES = new Set(["javascript"]);
|
36
57
|
|
37
58
|
class LazyCompilationDependency extends Dependency {
|
@@ -272,11 +293,15 @@ class LazyCompilationPlugin {
|
|
272
293
|
* @param {(function(Compiler, string, function(Error?, any?): void): void) | function(Compiler, string): Promise<any>} options.backend the backend
|
273
294
|
* @param {string} options.client the client reference
|
274
295
|
* @param {boolean} options.entries true, when entries are lazy compiled
|
296
|
+
* @param {boolean} options.imports true, when import() modules are lazy compiled
|
297
|
+
* @param {RegExp | string | (function(Module): boolean)} options.test additional filter for lazy compiled entrypoint modules
|
275
298
|
*/
|
276
|
-
constructor({ backend, client, entries }) {
|
299
|
+
constructor({ backend, client, entries, imports, test }) {
|
277
300
|
this.backend = backend;
|
278
301
|
this.client = client;
|
279
302
|
this.entries = entries;
|
303
|
+
this.imports = imports;
|
304
|
+
this.test = test;
|
280
305
|
}
|
281
306
|
/**
|
282
307
|
* Apply the plugin
|
@@ -311,12 +336,13 @@ class LazyCompilationPlugin {
|
|
311
336
|
if (
|
312
337
|
resolveData.dependencies.every(
|
313
338
|
dep =>
|
314
|
-
dep.type === "import()" ||
|
339
|
+
(this.imports && dep.type === "import()") ||
|
315
340
|
(this.entries && dep.type === "entry")
|
316
341
|
) &&
|
317
342
|
!/webpack[/\\]hot[/\\]|webpack-dev-server[/\\]client/.test(
|
318
343
|
resolveData.request
|
319
|
-
)
|
344
|
+
) &&
|
345
|
+
checkTest(this.test, originalModule)
|
320
346
|
) {
|
321
347
|
const moduleInfo = backend.module(originalModule);
|
322
348
|
if (!moduleInfo) return;
|
@@ -19,6 +19,7 @@ module.exports = (compiler, client, callback) => {
|
|
19
19
|
const logger = compiler.getInfrastructureLogger("LazyCompilationBackend");
|
20
20
|
const activeModules = new Map();
|
21
21
|
const prefix = "/lazy-compilation-using-";
|
22
|
+
|
22
23
|
const server = http.createServer((req, res) => {
|
23
24
|
const keys = req.url.slice(prefix.length).split("@");
|
24
25
|
req.socket.on("close", () => {
|
@@ -74,9 +75,7 @@ module.exports = (compiler, client, callback) => {
|
|
74
75
|
).replace(/%(2F|3A|24|26|2B|2C|3B|3D|3A)/g, decodeURIComponent)}`;
|
75
76
|
const active = activeModules.get(key) > 0;
|
76
77
|
return {
|
77
|
-
client:
|
78
|
-
compiler.options.externalsPresets.node ? "node" : "web"
|
79
|
-
}.js?${encodeURIComponent(urlBase + prefix)}`,
|
78
|
+
client: `${client}?${encodeURIComponent(urlBase + prefix)}`,
|
80
79
|
data: key,
|
81
80
|
active
|
82
81
|
};
|
package/lib/index.js
CHANGED
@@ -10,6 +10,7 @@ const memoize = require("./util/memoize");
|
|
10
10
|
|
11
11
|
/** @typedef {import("../declarations/WebpackOptions").Entry} Entry */
|
12
12
|
/** @typedef {import("../declarations/WebpackOptions").EntryNormalized} EntryNormalized */
|
13
|
+
/** @typedef {import("../declarations/WebpackOptions").EntryObject} EntryObject */
|
13
14
|
/** @typedef {import("../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
|
14
15
|
/** @typedef {import("../declarations/WebpackOptions").ModuleOptions} ModuleOptions */
|
15
16
|
/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
|
@@ -109,6 +110,9 @@ module.exports = mergeExports(fn, {
|
|
109
110
|
get ChunkGraph() {
|
110
111
|
return require("./ChunkGraph");
|
111
112
|
},
|
113
|
+
get CleanPlugin() {
|
114
|
+
return require("./CleanPlugin");
|
115
|
+
},
|
112
116
|
get Compilation() {
|
113
117
|
return require("./Compilation");
|
114
118
|
},
|
@@ -965,7 +965,7 @@ class JavascriptModulesPlugin {
|
|
965
965
|
buf.push(
|
966
966
|
"// the startup function",
|
967
967
|
"// It's empty as no entry modules are in this chunk",
|
968
|
-
`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()}
|
968
|
+
`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`,
|
969
969
|
""
|
970
970
|
);
|
971
971
|
}
|
@@ -978,7 +978,7 @@ class JavascriptModulesPlugin {
|
|
978
978
|
buf.push(
|
979
979
|
"// the startup function",
|
980
980
|
"// It's empty as some runtime module handles the default behavior",
|
981
|
-
`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()}
|
981
|
+
`${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};`
|
982
982
|
);
|
983
983
|
startup.push("// run startup");
|
984
984
|
startup.push(`${maybeReturn}${RuntimeGlobals.startup}();`);
|
@@ -10,6 +10,8 @@ const { UsageState } = require("../ExportsInfo");
|
|
10
10
|
/** @typedef {import("estree").Node} AnyNode */
|
11
11
|
/** @typedef {import("../Dependency")} Dependency */
|
12
12
|
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
13
|
+
/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
|
14
|
+
/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
|
13
15
|
/** @typedef {import("../Parser").ParserState} ParserState */
|
14
16
|
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
|
15
17
|
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
@@ -286,6 +288,32 @@ exports.isDependencyUsedByExports = (
|
|
286
288
|
return true;
|
287
289
|
};
|
288
290
|
|
291
|
+
/**
|
292
|
+
* @param {Dependency} dependency the dependency
|
293
|
+
* @param {Set<string> | boolean} usedByExports usedByExports info
|
294
|
+
* @param {ModuleGraph} moduleGraph moduleGraph
|
295
|
+
* @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
|
296
|
+
*/
|
297
|
+
exports.getDependencyUsedByExportsCondition = (
|
298
|
+
dependency,
|
299
|
+
usedByExports,
|
300
|
+
moduleGraph
|
301
|
+
) => {
|
302
|
+
if (usedByExports === false) return false;
|
303
|
+
if (usedByExports !== true && usedByExports !== undefined) {
|
304
|
+
const selfModule = moduleGraph.getParentModule(dependency);
|
305
|
+
const exportsInfo = moduleGraph.getExportsInfo(selfModule);
|
306
|
+
return (connections, runtime) => {
|
307
|
+
for (const exportName of usedByExports) {
|
308
|
+
if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused)
|
309
|
+
return true;
|
310
|
+
}
|
311
|
+
return false;
|
312
|
+
};
|
313
|
+
}
|
314
|
+
return null;
|
315
|
+
};
|
316
|
+
|
289
317
|
class TopLevelSymbol {
|
290
318
|
/**
|
291
319
|
* @param {string} name name of the variable
|
@@ -0,0 +1,137 @@
|
|
1
|
+
/*
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
3
|
+
*/
|
4
|
+
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
const RuntimeGlobals = require("../RuntimeGlobals");
|
8
|
+
const Template = require("../Template");
|
9
|
+
const HelperRuntimeModule = require("./HelperRuntimeModule");
|
10
|
+
|
11
|
+
class AsyncModuleRuntimeModule extends HelperRuntimeModule {
|
12
|
+
constructor() {
|
13
|
+
super("async module");
|
14
|
+
}
|
15
|
+
|
16
|
+
/**
|
17
|
+
* @returns {string} runtime code
|
18
|
+
*/
|
19
|
+
generate() {
|
20
|
+
const { runtimeTemplate } = this.compilation;
|
21
|
+
const fn = RuntimeGlobals.asyncModule;
|
22
|
+
return Template.asString([
|
23
|
+
'var webpackThen = typeof Symbol === "function" ? Symbol("webpack then") : "__webpack_then__";',
|
24
|
+
'var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__";',
|
25
|
+
`var completeQueue = ${runtimeTemplate.basicFunction("queue", [
|
26
|
+
"if(queue) {",
|
27
|
+
Template.indent(
|
28
|
+
runtimeTemplate.supportsArrowFunction()
|
29
|
+
? [
|
30
|
+
"queue.forEach(fn => fn.r--);",
|
31
|
+
"queue.forEach(fn => fn.r-- ? fn.r++ : fn());"
|
32
|
+
]
|
33
|
+
: [
|
34
|
+
"queue.forEach(function(fn) { fn.r--; });",
|
35
|
+
"queue.forEach(function(fn) { fn.r-- ? fn.r++ : fn(); });"
|
36
|
+
]
|
37
|
+
),
|
38
|
+
"}"
|
39
|
+
])}`,
|
40
|
+
`var completeFunction = ${
|
41
|
+
runtimeTemplate.supportsArrowFunction()
|
42
|
+
? "fn => !--fn.r && fn()"
|
43
|
+
: "function(fn) { !--fn.r && fn(); }"
|
44
|
+
};`,
|
45
|
+
`var queueFunction = ${
|
46
|
+
runtimeTemplate.supportsArrowFunction()
|
47
|
+
? "(queue, fn) => queue ? queue.push(fn) : completeFunction(fn)"
|
48
|
+
: "function(queue, fn) { queue ? queue.push(fn) : completeFunction(fn); }"
|
49
|
+
};`,
|
50
|
+
`var wrapDeps = ${runtimeTemplate.returningFunction(
|
51
|
+
`deps.map(${runtimeTemplate.basicFunction("dep", [
|
52
|
+
'if(dep !== null && typeof dep === "object") {',
|
53
|
+
Template.indent([
|
54
|
+
"if(dep[webpackThen]) return dep;",
|
55
|
+
"if(dep.then) {",
|
56
|
+
Template.indent([
|
57
|
+
"var queue = [], result;",
|
58
|
+
`dep.then(${runtimeTemplate.basicFunction("r", [
|
59
|
+
"obj[webpackExports] = r;",
|
60
|
+
"completeQueue(queue);",
|
61
|
+
"queue = 0;"
|
62
|
+
])});`,
|
63
|
+
"var obj = { [webpackThen]: (fn, reject) => { queueFunction(queue, fn); dep.catch(reject); } };",
|
64
|
+
"return obj;"
|
65
|
+
]),
|
66
|
+
"}"
|
67
|
+
]),
|
68
|
+
"}",
|
69
|
+
"return { [webpackThen]: (fn) => { completeFunction(fn); }, [webpackExports]: dep };"
|
70
|
+
])})`,
|
71
|
+
"deps"
|
72
|
+
)};`,
|
73
|
+
`${fn} = ${runtimeTemplate.basicFunction("module, body, hasAwait", [
|
74
|
+
"var queue = hasAwait && [];",
|
75
|
+
"var exports = module.exports;",
|
76
|
+
"var currentDeps;",
|
77
|
+
"var outerResolve;",
|
78
|
+
"var reject;",
|
79
|
+
"var isEvaluating = true;",
|
80
|
+
"var nested = false;",
|
81
|
+
`var whenAll = ${runtimeTemplate.basicFunction(
|
82
|
+
"deps, onResolve, onReject",
|
83
|
+
[
|
84
|
+
"if (nested) return;",
|
85
|
+
"nested = true;",
|
86
|
+
"onResolve.r += deps.length;",
|
87
|
+
`deps.map(${runtimeTemplate.basicFunction("dep, i", [
|
88
|
+
"dep[webpackThen](onResolve, onReject);"
|
89
|
+
])});`,
|
90
|
+
"nested = false;"
|
91
|
+
]
|
92
|
+
)};`,
|
93
|
+
`var promise = new Promise(${runtimeTemplate.basicFunction(
|
94
|
+
"resolve, rej",
|
95
|
+
[
|
96
|
+
"reject = rej;",
|
97
|
+
`outerResolve = ${runtimeTemplate.basicFunction("", [
|
98
|
+
"resolve(exports);",
|
99
|
+
"completeQueue(queue);",
|
100
|
+
"queue = 0;"
|
101
|
+
])};`
|
102
|
+
]
|
103
|
+
)});`,
|
104
|
+
"promise[webpackExports] = exports;",
|
105
|
+
`promise[webpackThen] = ${runtimeTemplate.basicFunction(
|
106
|
+
"fn, rejectFn",
|
107
|
+
[
|
108
|
+
"if (isEvaluating) { return completeFunction(fn); }",
|
109
|
+
"if (currentDeps) whenAll(currentDeps, fn, rejectFn);",
|
110
|
+
"queueFunction(queue, fn);",
|
111
|
+
"promise.catch(rejectFn);"
|
112
|
+
]
|
113
|
+
)};`,
|
114
|
+
"module.exports = promise;",
|
115
|
+
`body(${runtimeTemplate.basicFunction("deps", [
|
116
|
+
"if(!deps) return outerResolve();",
|
117
|
+
"currentDeps = wrapDeps(deps);",
|
118
|
+
"var fn, result;",
|
119
|
+
`var promise = new Promise(${runtimeTemplate.basicFunction(
|
120
|
+
"resolve, reject",
|
121
|
+
[
|
122
|
+
`fn = ${runtimeTemplate.returningFunction(
|
123
|
+
"resolve(result = currentDeps.map(d => d[webpackExports]))"
|
124
|
+
)}`,
|
125
|
+
"fn.r = 0;",
|
126
|
+
"whenAll(currentDeps, fn, reject);"
|
127
|
+
]
|
128
|
+
)});`,
|
129
|
+
"return fn.r ? promise : result;"
|
130
|
+
])}).then(outerResolve, reject);`,
|
131
|
+
"isEvaluating = false;"
|
132
|
+
])};`
|
133
|
+
]);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
module.exports = AsyncModuleRuntimeModule;
|
@@ -379,13 +379,21 @@ class BinaryMiddleware extends SerializerMiddleware {
|
|
379
379
|
writeU8(BOOLEANS_HEADER);
|
380
380
|
writeU8((1 << count) | lastByte);
|
381
381
|
} else if (count <= 133) {
|
382
|
-
allocate(
|
382
|
+
allocate(
|
383
|
+
HEADER_SIZE + I8_SIZE + I8_SIZE * bytes.length + I8_SIZE
|
384
|
+
);
|
383
385
|
writeU8(BOOLEANS_HEADER);
|
384
386
|
writeU8(0x80 | (count - 7));
|
385
387
|
for (const byte of bytes) writeU8(byte);
|
386
388
|
writeU8(lastByte);
|
387
389
|
} else {
|
388
|
-
allocate(
|
390
|
+
allocate(
|
391
|
+
HEADER_SIZE +
|
392
|
+
I8_SIZE +
|
393
|
+
I32_SIZE +
|
394
|
+
I8_SIZE * bytes.length +
|
395
|
+
I8_SIZE
|
396
|
+
);
|
389
397
|
writeU8(BOOLEANS_HEADER);
|
390
398
|
writeU8(0xff);
|
391
399
|
writeU32(count);
|
@@ -78,7 +78,7 @@ class ShareRuntimeModule extends RuntimeModule {
|
|
78
78
|
"// runs all init snippets from all modules reachable",
|
79
79
|
`var scope = ${RuntimeGlobals.shareScopeMap}[name];`,
|
80
80
|
`var warn = ${runtimeTemplate.returningFunction(
|
81
|
-
'typeof console !== "undefined" && console.warn && console.warn(msg)
|
81
|
+
'typeof console !== "undefined" && console.warn && console.warn(msg)',
|
82
82
|
"msg"
|
83
83
|
)};`,
|
84
84
|
`var uniqueName = ${JSON.stringify(uniqueName || undefined)};`,
|
@@ -0,0 +1,103 @@
|
|
1
|
+
/*
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
3
|
+
Author Tobias Koppers @sokra
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @template T
|
10
|
+
*/
|
11
|
+
class ArrayQueue {
|
12
|
+
/**
|
13
|
+
* @param {Iterable<T>=} items The initial elements.
|
14
|
+
*/
|
15
|
+
constructor(items) {
|
16
|
+
/** @private @type {T[]} */
|
17
|
+
this._list = items ? Array.from(items) : [];
|
18
|
+
/** @private @type {T[]} */
|
19
|
+
this._listReversed = [];
|
20
|
+
}
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Returns the number of elements in this queue.
|
24
|
+
* @returns {number} The number of elements in this queue.
|
25
|
+
*/
|
26
|
+
get length() {
|
27
|
+
return this._list.length + this._listReversed.length;
|
28
|
+
}
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Appends the specified element to this queue.
|
32
|
+
* @param {T} item The element to add.
|
33
|
+
* @returns {void}
|
34
|
+
*/
|
35
|
+
enqueue(item) {
|
36
|
+
this._list.push(item);
|
37
|
+
}
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Retrieves and removes the head of this queue.
|
41
|
+
* @returns {T | undefined} The head of the queue of `undefined` if this queue is empty.
|
42
|
+
*/
|
43
|
+
dequeue() {
|
44
|
+
if (this._listReversed.length === 0) {
|
45
|
+
if (this._list.length === 0) return undefined;
|
46
|
+
if (this._list.length === 1) return this._list.pop();
|
47
|
+
if (this._list.length < 16) return this._list.shift();
|
48
|
+
const temp = this._listReversed;
|
49
|
+
this._listReversed = this._list;
|
50
|
+
this._listReversed.reverse();
|
51
|
+
this._list = temp;
|
52
|
+
}
|
53
|
+
return this._listReversed.pop();
|
54
|
+
}
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Finds and removes an item
|
58
|
+
* @param {T} item the item
|
59
|
+
* @returns {void}
|
60
|
+
*/
|
61
|
+
delete(item) {
|
62
|
+
const i = this._list.indexOf(item);
|
63
|
+
if (i >= 0) {
|
64
|
+
this._list.splice(i, 1);
|
65
|
+
} else {
|
66
|
+
const i = this._listReversed.indexOf(item);
|
67
|
+
if (i >= 0) this._listReversed.splice(i, 1);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
[Symbol.iterator]() {
|
72
|
+
let i = -1;
|
73
|
+
let reversed = false;
|
74
|
+
return {
|
75
|
+
next: () => {
|
76
|
+
if (!reversed) {
|
77
|
+
i++;
|
78
|
+
if (i < this._list.length) {
|
79
|
+
return {
|
80
|
+
done: false,
|
81
|
+
value: this._list[i]
|
82
|
+
};
|
83
|
+
}
|
84
|
+
reversed = true;
|
85
|
+
i = this._listReversed.length;
|
86
|
+
}
|
87
|
+
i--;
|
88
|
+
if (i < 0) {
|
89
|
+
return {
|
90
|
+
done: true,
|
91
|
+
value: undefined
|
92
|
+
};
|
93
|
+
}
|
94
|
+
return {
|
95
|
+
done: false,
|
96
|
+
value: this._listReversed[i]
|
97
|
+
};
|
98
|
+
}
|
99
|
+
};
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
module.exports = ArrayQueue;
|