webpack 5.2.1 → 5.3.0
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/lib/ChunkGraph.js +19 -0
- package/lib/Compilation.js +25 -4
- package/lib/ConditionalInitFragment.js +109 -0
- package/lib/Dependency.js +1 -0
- package/lib/RuntimeGlobals.js +5 -0
- package/lib/RuntimePlugin.js +8 -0
- package/lib/RuntimeTemplate.js +37 -0
- package/lib/WebpackOptionsApply.js +3 -1
- package/lib/config/defaults.js +1 -1
- package/lib/dependencies/HarmonyAcceptDependency.js +33 -5
- package/lib/dependencies/HarmonyImportDependency.js +70 -28
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +2 -2
- package/lib/dependencies/PureExpressionDependency.js +30 -6
- package/lib/dependencies/WorkerPlugin.js +8 -3
- package/lib/optimize/ConcatenatedModule.js +85 -18
- package/lib/optimize/ModuleConcatenationPlugin.js +71 -6
- package/lib/optimize/SideEffectsFlagPlugin.js +112 -100
- package/lib/runtime/RuntimeIdRuntimeModule.js +29 -0
- package/lib/util/compileBooleanMatcher.js +13 -1
- package/lib/util/runtime.js +62 -0
- package/package.json +1 -1
- package/schemas/WebpackOptions.json +9 -2
- package/types.d.ts +34 -3
package/lib/ChunkGraph.js
CHANGED
@@ -200,6 +200,8 @@ class ChunkGraph {
|
|
200
200
|
this._chunks = new WeakMap();
|
201
201
|
/** @private @type {WeakMap<AsyncDependenciesBlock, ChunkGroup>} */
|
202
202
|
this._blockChunkGroups = new WeakMap();
|
203
|
+
/** @private @type {Map<string, string | number>} */
|
204
|
+
this._runtimeIds = new Map();
|
203
205
|
/** @type {ModuleGraph} */
|
204
206
|
this.moduleGraph = moduleGraph;
|
205
207
|
|
@@ -1144,6 +1146,23 @@ class ChunkGraph {
|
|
1144
1146
|
cgm.id = id;
|
1145
1147
|
}
|
1146
1148
|
|
1149
|
+
/**
|
1150
|
+
* @param {string} runtime runtime
|
1151
|
+
* @returns {string | number} the id of the runtime
|
1152
|
+
*/
|
1153
|
+
getRuntimeId(runtime) {
|
1154
|
+
return this._runtimeIds.get(runtime);
|
1155
|
+
}
|
1156
|
+
|
1157
|
+
/**
|
1158
|
+
* @param {string} runtime runtime
|
1159
|
+
* @param {string | number} id the id of the runtime
|
1160
|
+
* @returns {void}
|
1161
|
+
*/
|
1162
|
+
setRuntimeId(runtime, id) {
|
1163
|
+
this._runtimeIds.set(runtime, id);
|
1164
|
+
}
|
1165
|
+
|
1147
1166
|
/**
|
1148
1167
|
* @param {Module} module the module
|
1149
1168
|
* @param {RuntimeSpec} runtime the runtime
|
package/lib/Compilation.js
CHANGED
@@ -1939,6 +1939,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
1939
1939
|
this.hooks.optimizeChunkIds.call(this.chunks);
|
1940
1940
|
this.hooks.afterOptimizeChunkIds.call(this.chunks);
|
1941
1941
|
|
1942
|
+
this.assignRuntimeIds();
|
1943
|
+
|
1942
1944
|
this.sortItemsWithChunkIds();
|
1943
1945
|
|
1944
1946
|
if (shouldRecord) {
|
@@ -2556,6 +2558,21 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2556
2558
|
}
|
2557
2559
|
}
|
2558
2560
|
|
2561
|
+
assignRuntimeIds() {
|
2562
|
+
const { chunkGraph } = this;
|
2563
|
+
const processEntrypoint = ep => {
|
2564
|
+
const runtime = ep.options.runtime || ep.name;
|
2565
|
+
const chunk = ep.getRuntimeChunk();
|
2566
|
+
chunkGraph.setRuntimeId(runtime, chunk.id);
|
2567
|
+
};
|
2568
|
+
for (const ep of this.entrypoints.values()) {
|
2569
|
+
processEntrypoint(ep);
|
2570
|
+
}
|
2571
|
+
for (const ep of this.asyncEntrypoints) {
|
2572
|
+
processEntrypoint(ep);
|
2573
|
+
}
|
2574
|
+
}
|
2575
|
+
|
2559
2576
|
sortItemsWithChunkIds() {
|
2560
2577
|
for (const chunkGroup of this.chunkGroups) {
|
2561
2578
|
chunkGroup.sortItems();
|
@@ -2592,7 +2609,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2592
2609
|
|
2593
2610
|
createModuleHashes() {
|
2594
2611
|
let statModulesHashed = 0;
|
2595
|
-
const chunkGraph = this
|
2612
|
+
const { chunkGraph, runtimeTemplate } = this;
|
2596
2613
|
const { hashFunction, hashDigest, hashDigestLength } = this.outputOptions;
|
2597
2614
|
for (const module of this.modules) {
|
2598
2615
|
for (const runtime of chunkGraph.getModuleRuntimes(module)) {
|
@@ -2600,7 +2617,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2600
2617
|
const moduleHash = createHash(hashFunction);
|
2601
2618
|
module.updateHash(moduleHash, {
|
2602
2619
|
chunkGraph,
|
2603
|
-
runtime
|
2620
|
+
runtime,
|
2621
|
+
runtimeTemplate
|
2604
2622
|
});
|
2605
2623
|
const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
|
2606
2624
|
hashDigest
|
@@ -2623,6 +2641,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2623
2641
|
createHash() {
|
2624
2642
|
this.logger.time("hashing: initialize hash");
|
2625
2643
|
const chunkGraph = this.chunkGraph;
|
2644
|
+
const runtimeTemplate = this.runtimeTemplate;
|
2626
2645
|
const outputOptions = this.outputOptions;
|
2627
2646
|
const hashFunction = outputOptions.hashFunction;
|
2628
2647
|
const hashDigest = outputOptions.hashDigest;
|
@@ -2707,7 +2726,8 @@ This prevents using hashes of each other and should be avoided.`
|
|
2707
2726
|
const moduleHash = createHash(hashFunction);
|
2708
2727
|
module.updateHash(moduleHash, {
|
2709
2728
|
chunkGraph,
|
2710
|
-
runtime: chunk.runtime
|
2729
|
+
runtime: chunk.runtime,
|
2730
|
+
runtimeTemplate
|
2711
2731
|
});
|
2712
2732
|
const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
|
2713
2733
|
hashDigest
|
@@ -2769,7 +2789,8 @@ This prevents using hashes of each other and should be avoided.`
|
|
2769
2789
|
const moduleHash = createHash(hashFunction);
|
2770
2790
|
module.updateHash(moduleHash, {
|
2771
2791
|
chunkGraph,
|
2772
|
-
runtime: chunk.runtime
|
2792
|
+
runtime: chunk.runtime,
|
2793
|
+
runtimeTemplate
|
2773
2794
|
});
|
2774
2795
|
const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
|
2775
2796
|
hashDigest
|
@@ -0,0 +1,109 @@
|
|
1
|
+
/*
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
3
|
+
Author Tobias Koppers @sokra
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
const { ConcatSource, PrefixSource } = require("webpack-sources");
|
9
|
+
const InitFragment = require("./InitFragment");
|
10
|
+
const Template = require("./Template");
|
11
|
+
const { mergeRuntime } = require("./util/runtime");
|
12
|
+
|
13
|
+
/** @typedef {import("webpack-sources").Source} Source */
|
14
|
+
/** @typedef {import("./Generator").GenerateContext} GenerateContext */
|
15
|
+
/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
|
16
|
+
|
17
|
+
const wrapInCondition = (condition, source) => {
|
18
|
+
if (typeof source === "string") {
|
19
|
+
return Template.asString([
|
20
|
+
`if (${condition}) {`,
|
21
|
+
Template.indent(source),
|
22
|
+
"}",
|
23
|
+
""
|
24
|
+
]);
|
25
|
+
} else {
|
26
|
+
return new ConcatSource(
|
27
|
+
`if (${condition}) {\n`,
|
28
|
+
new PrefixSource("\t", source),
|
29
|
+
"}\n"
|
30
|
+
);
|
31
|
+
}
|
32
|
+
};
|
33
|
+
|
34
|
+
class ConditionalInitFragment extends InitFragment {
|
35
|
+
/**
|
36
|
+
* @param {string|Source} content the source code that will be included as initialization code
|
37
|
+
* @param {number} stage category of initialization code (contribute to order)
|
38
|
+
* @param {number} position position in the category (contribute to order)
|
39
|
+
* @param {string} key unique key to avoid emitting the same initialization code twice
|
40
|
+
* @param {RuntimeSpec | boolean} runtimeCondition in which runtime this fragment should be executed
|
41
|
+
* @param {string|Source=} endContent the source code that will be included at the end of the module
|
42
|
+
*/
|
43
|
+
constructor(
|
44
|
+
content,
|
45
|
+
stage,
|
46
|
+
position,
|
47
|
+
key,
|
48
|
+
runtimeCondition = true,
|
49
|
+
endContent
|
50
|
+
) {
|
51
|
+
super(content, stage, position, key, endContent);
|
52
|
+
this.runtimeCondition = runtimeCondition;
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* @param {GenerateContext} generateContext context for generate
|
57
|
+
* @returns {string|Source} the source code that will be included as initialization code
|
58
|
+
*/
|
59
|
+
getContent(generateContext) {
|
60
|
+
if (this.runtimeCondition === false || !this.content) return "";
|
61
|
+
if (this.runtimeCondition === true) return this.content;
|
62
|
+
const expr = generateContext.runtimeTemplate.runtimeConditionExpression({
|
63
|
+
chunkGraph: generateContext.chunkGraph,
|
64
|
+
runtimeRequirements: generateContext.runtimeRequirements,
|
65
|
+
runtime: generateContext.runtime,
|
66
|
+
runtimeCondition: this.runtimeCondition
|
67
|
+
});
|
68
|
+
if (expr === "true") return this.content;
|
69
|
+
return wrapInCondition(expr, this.content);
|
70
|
+
}
|
71
|
+
|
72
|
+
/**
|
73
|
+
* @param {GenerateContext} generateContext context for generate
|
74
|
+
* @returns {string|Source=} the source code that will be included at the end of the module
|
75
|
+
*/
|
76
|
+
getEndContent(generateContext) {
|
77
|
+
if (this.runtimeCondition === false || !this.endContent) return "";
|
78
|
+
if (this.runtimeCondition === true) return this.endContent;
|
79
|
+
const expr = generateContext.runtimeTemplate.runtimeConditionExpression({
|
80
|
+
chunkGraph: generateContext.chunkGraph,
|
81
|
+
runtimeRequirements: generateContext.runtimeRequirements,
|
82
|
+
runtime: generateContext.runtime,
|
83
|
+
runtimeCondition: this.runtimeCondition
|
84
|
+
});
|
85
|
+
if (expr === "true") return this.endContent;
|
86
|
+
return wrapInCondition(expr, this.endContent);
|
87
|
+
}
|
88
|
+
|
89
|
+
merge(other) {
|
90
|
+
if (this.runtimeCondition === true) return this;
|
91
|
+
if (other.runtimeCondition === true) return other;
|
92
|
+
if (this.runtimeCondition === false) return other;
|
93
|
+
if (other.runtimeCondition === false) return this;
|
94
|
+
const runtimeCondition = mergeRuntime(
|
95
|
+
this.runtimeCondition,
|
96
|
+
other.runtimeCondition
|
97
|
+
);
|
98
|
+
return new ConditionalInitFragment(
|
99
|
+
this.content,
|
100
|
+
this.stage,
|
101
|
+
this.position,
|
102
|
+
this.key,
|
103
|
+
runtimeCondition,
|
104
|
+
this.endContent
|
105
|
+
);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
module.exports = ConditionalInitFragment;
|
package/lib/Dependency.js
CHANGED
package/lib/RuntimeGlobals.js
CHANGED
@@ -173,6 +173,11 @@ exports.loadScript = "__webpack_require__.l";
|
|
173
173
|
*/
|
174
174
|
exports.chunkName = "__webpack_require__.cn";
|
175
175
|
|
176
|
+
/**
|
177
|
+
* the runtime id of the current runtime
|
178
|
+
*/
|
179
|
+
exports.runtimeId = "__webpack_require__.j";
|
180
|
+
|
176
181
|
/**
|
177
182
|
* the filename of the script part of the chunk
|
178
183
|
*/
|
package/lib/RuntimePlugin.js
CHANGED
@@ -21,6 +21,7 @@ const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModu
|
|
21
21
|
const LoadScriptRuntimeModule = require("./runtime/LoadScriptRuntimeModule");
|
22
22
|
const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule");
|
23
23
|
const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule");
|
24
|
+
const RuntimeIdRuntimeModule = require("./runtime/RuntimeIdRuntimeModule");
|
24
25
|
const SystemContextRuntimeModule = require("./runtime/SystemContextRuntimeModule");
|
25
26
|
const ShareRuntimeModule = require("./sharing/ShareRuntimeModule");
|
26
27
|
const StringXor = require("./util/StringXor");
|
@@ -31,6 +32,7 @@ const StringXor = require("./util/StringXor");
|
|
31
32
|
|
32
33
|
const GLOBALS_ON_REQUIRE = [
|
33
34
|
RuntimeGlobals.chunkName,
|
35
|
+
RuntimeGlobals.runtimeId,
|
34
36
|
RuntimeGlobals.compatGetDefaultExport,
|
35
37
|
RuntimeGlobals.createFakeNamespaceObject,
|
36
38
|
RuntimeGlobals.definePropertyGetters,
|
@@ -156,6 +158,12 @@ class RuntimePlugin {
|
|
156
158
|
);
|
157
159
|
return true;
|
158
160
|
});
|
161
|
+
compilation.hooks.runtimeRequirementInTree
|
162
|
+
.for(RuntimeGlobals.runtimeId)
|
163
|
+
.tap("RuntimePlugin", chunk => {
|
164
|
+
compilation.addRuntimeModule(chunk, new RuntimeIdRuntimeModule());
|
165
|
+
return true;
|
166
|
+
});
|
159
167
|
compilation.hooks.runtimeRequirementInTree
|
160
168
|
.for(RuntimeGlobals.publicPath)
|
161
169
|
.tap("RuntimePlugin", (chunk, set) => {
|
package/lib/RuntimeTemplate.js
CHANGED
@@ -9,7 +9,9 @@ const InitFragment = require("./InitFragment");
|
|
9
9
|
const RuntimeGlobals = require("./RuntimeGlobals");
|
10
10
|
const Template = require("./Template");
|
11
11
|
const { equals } = require("./util/ArrayHelpers");
|
12
|
+
const compileBooleanMatcher = require("./util/compileBooleanMatcher");
|
12
13
|
const propertyAccess = require("./util/propertyAccess");
|
14
|
+
const { forEachRuntime, subtractRuntime } = require("./util/runtime");
|
13
15
|
|
14
16
|
/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
|
15
17
|
/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
|
@@ -562,6 +564,39 @@ class RuntimeTemplate {
|
|
562
564
|
return `${promise || "Promise.resolve()"}${appending}`;
|
563
565
|
}
|
564
566
|
|
567
|
+
/**
|
568
|
+
* @param {Object} options options object
|
569
|
+
* @param {ChunkGraph} options.chunkGraph the chunk graph
|
570
|
+
* @param {RuntimeSpec=} options.runtime runtime for which this code will be generated
|
571
|
+
* @param {RuntimeSpec | boolean=} options.runtimeCondition only execute the statement in some runtimes
|
572
|
+
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
|
573
|
+
* @returns {string} expression
|
574
|
+
*/
|
575
|
+
runtimeConditionExpression({
|
576
|
+
chunkGraph,
|
577
|
+
runtimeCondition,
|
578
|
+
runtime,
|
579
|
+
runtimeRequirements
|
580
|
+
}) {
|
581
|
+
if (runtimeCondition === undefined) return "true";
|
582
|
+
if (typeof runtimeCondition === "boolean") return `${runtimeCondition}`;
|
583
|
+
/** @type {Set<string>} */
|
584
|
+
const positiveRuntimeIds = new Set();
|
585
|
+
forEachRuntime(runtimeCondition, runtime =>
|
586
|
+
positiveRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`)
|
587
|
+
);
|
588
|
+
/** @type {Set<string>} */
|
589
|
+
const negativeRuntimeIds = new Set();
|
590
|
+
forEachRuntime(subtractRuntime(runtime, runtimeCondition), runtime =>
|
591
|
+
negativeRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`)
|
592
|
+
);
|
593
|
+
runtimeRequirements.add(RuntimeGlobals.runtimeId);
|
594
|
+
return compileBooleanMatcher.fromLists(
|
595
|
+
Array.from(positiveRuntimeIds),
|
596
|
+
Array.from(negativeRuntimeIds)
|
597
|
+
)(RuntimeGlobals.runtimeId);
|
598
|
+
}
|
599
|
+
|
565
600
|
/**
|
566
601
|
*
|
567
602
|
* @param {Object} options options object
|
@@ -572,6 +607,8 @@ class RuntimeTemplate {
|
|
572
607
|
* @param {string} options.importVar name of the import variable
|
573
608
|
* @param {Module} options.originModule module in which the statement is emitted
|
574
609
|
* @param {boolean=} options.weak true, if this is a weak dependency
|
610
|
+
* @param {RuntimeSpec=} options.runtime runtime for which this code will be generated
|
611
|
+
* @param {RuntimeSpec | boolean=} options.runtimeCondition only execute the statement in some runtimes
|
575
612
|
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
|
576
613
|
* @returns {[string, string]} the import statement and the compat statement
|
577
614
|
*/
|
@@ -308,7 +308,9 @@ class WebpackOptionsApply extends OptionsApply {
|
|
308
308
|
}
|
309
309
|
if (options.optimization.sideEffects) {
|
310
310
|
const SideEffectsFlagPlugin = require("./optimize/SideEffectsFlagPlugin");
|
311
|
-
new SideEffectsFlagPlugin(
|
311
|
+
new SideEffectsFlagPlugin(
|
312
|
+
options.optimization.sideEffects === true
|
313
|
+
).apply(compiler);
|
312
314
|
}
|
313
315
|
if (options.optimization.providedExports) {
|
314
316
|
const FlagDependencyExportsPlugin = require("./FlagDependencyExportsPlugin");
|
package/lib/config/defaults.js
CHANGED
@@ -848,7 +848,7 @@ const applyOptimizationDefaults = (
|
|
848
848
|
if (development) return "named";
|
849
849
|
return "natural";
|
850
850
|
});
|
851
|
-
|
851
|
+
F(optimization, "sideEffects", () => (production ? true : "flag"));
|
852
852
|
D(optimization, "providedExports", true);
|
853
853
|
D(optimization, "usedExports", production);
|
854
854
|
D(optimization, "innerGraph", production);
|
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
const Template = require("../Template");
|
8
9
|
const makeSerializable = require("../util/makeSerializable");
|
9
10
|
const HarmonyImportDependency = require("./HarmonyImportDependency");
|
10
11
|
const NullDependency = require("./NullDependency");
|
@@ -62,14 +63,41 @@ HarmonyAcceptDependency.Template = class HarmonyAcceptDependencyTemplate extends
|
|
62
63
|
*/
|
63
64
|
apply(dependency, source, templateContext) {
|
64
65
|
const dep = /** @type {HarmonyAcceptDependency} */ (dependency);
|
65
|
-
const {
|
66
|
+
const {
|
67
|
+
module,
|
68
|
+
runtime,
|
69
|
+
runtimeRequirements,
|
70
|
+
runtimeTemplate,
|
71
|
+
moduleGraph,
|
72
|
+
chunkGraph
|
73
|
+
} = templateContext;
|
66
74
|
const content = dep.dependencies
|
67
|
-
.filter(dependency =>
|
68
|
-
HarmonyImportDependency.Template.isImportEmitted(dependency, module)
|
69
|
-
)
|
70
75
|
.map(dependency => {
|
76
|
+
const referencedModule = moduleGraph.getModule(dependency);
|
77
|
+
return {
|
78
|
+
dependency,
|
79
|
+
runtimeCondition: referencedModule
|
80
|
+
? HarmonyImportDependency.Template.getImportEmittedRuntime(
|
81
|
+
module,
|
82
|
+
referencedModule
|
83
|
+
)
|
84
|
+
: false
|
85
|
+
};
|
86
|
+
})
|
87
|
+
.filter(({ runtimeCondition }) => runtimeCondition !== false)
|
88
|
+
.map(({ dependency, runtimeCondition }) => {
|
89
|
+
const condition = runtimeTemplate.runtimeConditionExpression({
|
90
|
+
chunkGraph,
|
91
|
+
runtime,
|
92
|
+
runtimeCondition,
|
93
|
+
runtimeRequirements
|
94
|
+
});
|
71
95
|
const s = dependency.getImportStatement(true, templateContext);
|
72
|
-
|
96
|
+
const code = s[0] + s[1];
|
97
|
+
if (condition !== "true") {
|
98
|
+
return `if (${condition}) {\n${Template.indent(code)}\n}\n`;
|
99
|
+
}
|
100
|
+
return code;
|
73
101
|
})
|
74
102
|
.join("");
|
75
103
|
|
@@ -5,11 +5,13 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
const ConditionalInitFragment = require("../ConditionalInitFragment");
|
8
9
|
const Dependency = require("../Dependency");
|
9
10
|
const HarmonyLinkingError = require("../HarmonyLinkingError");
|
10
11
|
const InitFragment = require("../InitFragment");
|
11
12
|
const Template = require("../Template");
|
12
13
|
const AwaitDependenciesInitFragment = require("../async-modules/AwaitDependenciesInitFragment");
|
14
|
+
const { filterRuntime, mergeRuntime } = require("../util/runtime");
|
13
15
|
const ModuleDependency = require("./ModuleDependency");
|
14
16
|
|
15
17
|
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
|
@@ -199,21 +201,38 @@ class HarmonyImportDependency extends ModuleDependency {
|
|
199
201
|
* @returns {void}
|
200
202
|
*/
|
201
203
|
updateHash(hash, context) {
|
202
|
-
const { chunkGraph } = context;
|
204
|
+
const { chunkGraph, runtime, runtimeTemplate } = context;
|
203
205
|
const { moduleGraph } = chunkGraph;
|
204
206
|
super.updateHash(hash, context);
|
205
|
-
const importedModule = moduleGraph.getModule(this);
|
206
|
-
if (importedModule) {
|
207
|
-
const parentModule = moduleGraph.getParentModule(this);
|
208
|
-
hash.update(
|
209
|
-
importedModule.getExportsType(
|
210
|
-
moduleGraph,
|
211
|
-
parentModule.buildMeta && parentModule.buildMeta.strictHarmonyModule
|
212
|
-
)
|
213
|
-
);
|
214
|
-
if (moduleGraph.isAsync(importedModule)) hash.update("async");
|
215
|
-
}
|
216
207
|
hash.update(`${this.sourceOrder}`);
|
208
|
+
const connection = moduleGraph.getConnection(this);
|
209
|
+
if (connection) {
|
210
|
+
const importedModule = connection.module;
|
211
|
+
if (importedModule) {
|
212
|
+
const parentModule = moduleGraph.getParentModule(this);
|
213
|
+
hash.update(
|
214
|
+
importedModule.getExportsType(
|
215
|
+
moduleGraph,
|
216
|
+
parentModule.buildMeta && parentModule.buildMeta.strictHarmonyModule
|
217
|
+
)
|
218
|
+
);
|
219
|
+
if (moduleGraph.isAsync(importedModule)) hash.update("async");
|
220
|
+
}
|
221
|
+
if (runtimeTemplate) {
|
222
|
+
const runtimeRequirements = new Set();
|
223
|
+
hash.update(
|
224
|
+
runtimeTemplate.runtimeConditionExpression({
|
225
|
+
chunkGraph,
|
226
|
+
runtimeCondition: filterRuntime(runtime, runtime => {
|
227
|
+
return connection.isTargetActive(runtime);
|
228
|
+
}),
|
229
|
+
runtime,
|
230
|
+
runtimeRequirements
|
231
|
+
})
|
232
|
+
);
|
233
|
+
for (const rr of runtimeRequirements) hash.update(rr);
|
234
|
+
}
|
235
|
+
}
|
217
236
|
}
|
218
237
|
|
219
238
|
serialize(context) {
|
@@ -231,6 +250,7 @@ class HarmonyImportDependency extends ModuleDependency {
|
|
231
250
|
|
232
251
|
module.exports = HarmonyImportDependency;
|
233
252
|
|
253
|
+
/** @type {WeakMap<Module, WeakMap<Module, RuntimeSpec | boolean>>} */
|
234
254
|
const importEmittedMap = new WeakMap();
|
235
255
|
|
236
256
|
HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends ModuleDependency.Template {
|
@@ -265,23 +285,42 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
|
|
265
285
|
: dep.request;
|
266
286
|
const key = `harmony import ${moduleKey}`;
|
267
287
|
|
268
|
-
|
269
|
-
|
288
|
+
const runtimeCondition = dep.weak
|
289
|
+
? false
|
290
|
+
: connection
|
291
|
+
? filterRuntime(runtime, r => connection.isTargetActive(r))
|
292
|
+
: true;
|
293
|
+
|
294
|
+
if (module && referencedModule) {
|
295
|
+
let emittedModules = importEmittedMap.get(module);
|
270
296
|
if (emittedModules === undefined) {
|
271
|
-
emittedModules = new
|
272
|
-
importEmittedMap.set(
|
297
|
+
emittedModules = new WeakMap();
|
298
|
+
importEmittedMap.set(module, emittedModules);
|
299
|
+
}
|
300
|
+
let mergedRuntimeCondition = runtimeCondition;
|
301
|
+
const oldRuntimeCondition = emittedModules.get(referencedModule) || false;
|
302
|
+
if (oldRuntimeCondition !== false && mergedRuntimeCondition !== true) {
|
303
|
+
if (mergedRuntimeCondition === false || oldRuntimeCondition === true) {
|
304
|
+
mergedRuntimeCondition = oldRuntimeCondition;
|
305
|
+
} else {
|
306
|
+
mergedRuntimeCondition = mergeRuntime(
|
307
|
+
oldRuntimeCondition,
|
308
|
+
mergedRuntimeCondition
|
309
|
+
);
|
310
|
+
}
|
273
311
|
}
|
274
|
-
emittedModules.
|
312
|
+
emittedModules.set(referencedModule, mergedRuntimeCondition);
|
275
313
|
}
|
276
314
|
|
277
315
|
const importStatement = dep.getImportStatement(false, templateContext);
|
278
316
|
if (templateContext.moduleGraph.isAsync(referencedModule)) {
|
279
317
|
templateContext.initFragments.push(
|
280
|
-
new
|
318
|
+
new ConditionalInitFragment(
|
281
319
|
importStatement[0],
|
282
320
|
InitFragment.STAGE_HARMONY_IMPORTS,
|
283
321
|
dep.sourceOrder,
|
284
|
-
key
|
322
|
+
key,
|
323
|
+
runtimeCondition
|
285
324
|
)
|
286
325
|
);
|
287
326
|
templateContext.initFragments.push(
|
@@ -290,20 +329,22 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
|
|
290
329
|
)
|
291
330
|
);
|
292
331
|
templateContext.initFragments.push(
|
293
|
-
new
|
332
|
+
new ConditionalInitFragment(
|
294
333
|
importStatement[1],
|
295
334
|
InitFragment.STAGE_ASYNC_HARMONY_IMPORTS,
|
296
335
|
dep.sourceOrder,
|
297
|
-
key + " compat"
|
336
|
+
key + " compat",
|
337
|
+
runtimeCondition
|
298
338
|
)
|
299
339
|
);
|
300
340
|
} else {
|
301
341
|
templateContext.initFragments.push(
|
302
|
-
new
|
342
|
+
new ConditionalInitFragment(
|
303
343
|
importStatement[0] + importStatement[1],
|
304
344
|
InitFragment.STAGE_HARMONY_IMPORTS,
|
305
345
|
dep.sourceOrder,
|
306
|
-
key
|
346
|
+
key,
|
347
|
+
runtimeCondition
|
307
348
|
)
|
308
349
|
);
|
309
350
|
}
|
@@ -311,12 +352,13 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
|
|
311
352
|
|
312
353
|
/**
|
313
354
|
*
|
314
|
-
* @param {Dependency} dep the dependency
|
315
355
|
* @param {Module} module the module
|
316
|
-
* @
|
356
|
+
* @param {Module} referencedModule the referenced module
|
357
|
+
* @returns {RuntimeSpec | boolean} runtimeCondition in which this import has been emitted
|
317
358
|
*/
|
318
|
-
static
|
319
|
-
const emittedModules = importEmittedMap.get(
|
320
|
-
|
359
|
+
static getImportEmittedRuntime(module, referencedModule) {
|
360
|
+
const emittedModules = importEmittedMap.get(module);
|
361
|
+
if (emittedModules === undefined) return false;
|
362
|
+
return emittedModules.get(referencedModule) || false;
|
321
363
|
}
|
322
364
|
};
|
@@ -196,7 +196,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
|
196
196
|
* @returns {void}
|
197
197
|
*/
|
198
198
|
updateHash(hash, context) {
|
199
|
-
const { chunkGraph } = context;
|
199
|
+
const { chunkGraph, runtime } = context;
|
200
200
|
super.updateHash(hash, context);
|
201
201
|
const moduleGraph = chunkGraph.moduleGraph;
|
202
202
|
const importedModule = moduleGraph.getModule(this);
|
@@ -204,7 +204,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
|
204
204
|
hash.update(ids.join());
|
205
205
|
if (importedModule) {
|
206
206
|
const exportsInfo = moduleGraph.getExportsInfo(importedModule);
|
207
|
-
hash.update(`${exportsInfo.getUsedName(ids,
|
207
|
+
hash.update(`${exportsInfo.getUsedName(ids, runtime)}`);
|
208
208
|
}
|
209
209
|
}
|
210
210
|
|
@@ -7,6 +7,7 @@
|
|
7
7
|
|
8
8
|
const { UsageState } = require("../ExportsInfo");
|
9
9
|
const makeSerializable = require("../util/makeSerializable");
|
10
|
+
const { filterRuntime } = require("../util/runtime");
|
10
11
|
const NullDependency = require("./NullDependency");
|
11
12
|
|
12
13
|
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
|
@@ -74,22 +75,45 @@ PureExpressionDependency.Template = class PureExpressionDependencyTemplate exten
|
|
74
75
|
* @param {DependencyTemplateContext} templateContext the context object
|
75
76
|
* @returns {void}
|
76
77
|
*/
|
77
|
-
apply(
|
78
|
+
apply(
|
79
|
+
dependency,
|
80
|
+
source,
|
81
|
+
{ chunkGraph, moduleGraph, runtime, runtimeTemplate, runtimeRequirements }
|
82
|
+
) {
|
78
83
|
const dep = /** @type {PureExpressionDependency} */ (dependency);
|
79
84
|
|
80
|
-
|
85
|
+
const usedByExports = dep.usedByExports;
|
86
|
+
if (usedByExports !== false) {
|
81
87
|
const selfModule = moduleGraph.getParentModule(dep);
|
82
88
|
const exportsInfo = moduleGraph.getExportsInfo(selfModule);
|
83
|
-
|
84
|
-
|
85
|
-
|
89
|
+
const runtimeCondition = filterRuntime(runtime, runtime => {
|
90
|
+
for (const exportName of usedByExports) {
|
91
|
+
if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) {
|
92
|
+
return true;
|
93
|
+
}
|
86
94
|
}
|
95
|
+
return false;
|
96
|
+
});
|
97
|
+
if (runtimeCondition === true) return;
|
98
|
+
if (runtimeCondition !== false) {
|
99
|
+
const condition = runtimeTemplate.runtimeConditionExpression({
|
100
|
+
chunkGraph,
|
101
|
+
runtime,
|
102
|
+
runtimeCondition,
|
103
|
+
runtimeRequirements
|
104
|
+
});
|
105
|
+
source.insert(
|
106
|
+
dep.range[0],
|
107
|
+
`(/* runtime-dependent pure expression or super */ ${condition} ? (`
|
108
|
+
);
|
109
|
+
source.insert(dep.range[1], ") : null)");
|
110
|
+
return;
|
87
111
|
}
|
88
112
|
}
|
89
113
|
|
90
114
|
source.insert(
|
91
115
|
dep.range[0],
|
92
|
-
|
116
|
+
`(/* unused pure expression or super */ null && (`
|
93
117
|
);
|
94
118
|
source.insert(dep.range[1], "))");
|
95
119
|
}
|
@@ -12,6 +12,7 @@ const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
|
|
12
12
|
const formatLocation = require("../formatLocation");
|
13
13
|
const EnableChunkLoadingPlugin = require("../javascript/EnableChunkLoadingPlugin");
|
14
14
|
const { equals } = require("../util/ArrayHelpers");
|
15
|
+
const { contextify } = require("../util/identifier");
|
15
16
|
const {
|
16
17
|
harmonySpecifierTag
|
17
18
|
} = require("./HarmonyImportDependencyParserPlugin");
|
@@ -48,6 +49,10 @@ class WorkerPlugin {
|
|
48
49
|
if (this._chunkLoading) {
|
49
50
|
new EnableChunkLoadingPlugin(this._chunkLoading).apply(compiler);
|
50
51
|
}
|
52
|
+
const cachedContextify = contextify.bindContextCache(
|
53
|
+
compiler.context,
|
54
|
+
compiler.root
|
55
|
+
);
|
51
56
|
compiler.hooks.thisCompilation.tap(
|
52
57
|
"WorkerPlugin",
|
53
58
|
(compilation, { normalModuleFactory }) => {
|
@@ -213,9 +218,9 @@ class WorkerPlugin {
|
|
213
218
|
}
|
214
219
|
|
215
220
|
if (!entryOptions.runtime) {
|
216
|
-
entryOptions.runtime = `${
|
217
|
-
|
218
|
-
)}`;
|
221
|
+
entryOptions.runtime = `${cachedContextify(
|
222
|
+
parser.state.module.identifier()
|
223
|
+
)}|${formatLocation(expr.loc)}`;
|
219
224
|
}
|
220
225
|
|
221
226
|
const block = new AsyncDependenciesBlock({
|