webpack 5.2.1 → 5.4.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.

@@ -14,7 +14,13 @@ const { STAGE_DEFAULT } = require("../OptimizationStages");
14
14
  const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
15
15
  const StackedMap = require("../util/StackedMap");
16
16
  const { compareModulesByIdentifier } = require("../util/comparators");
17
- const { intersectRuntime, mergeRuntimeOwned } = require("../util/runtime");
17
+ const {
18
+ intersectRuntime,
19
+ mergeRuntimeOwned,
20
+ filterRuntime,
21
+ runtimeToString,
22
+ mergeRuntime
23
+ } = require("../util/runtime");
18
24
  const ConcatenatedModule = require("./ConcatenatedModule");
19
25
 
20
26
  /** @typedef {import("../Compilation")} Compilation */
@@ -211,13 +217,26 @@ class ModuleConcatenationPlugin {
211
217
  // the other configuration is better and we can skip this one
212
218
  if (usedAsInner.has(currentRoot)) continue;
213
219
 
214
- let runtime = undefined;
220
+ let chunkRuntime = undefined;
215
221
  for (const r of chunkGraph.getModuleRuntimes(currentRoot)) {
216
- runtime = mergeRuntimeOwned(runtime, r);
222
+ chunkRuntime = mergeRuntimeOwned(chunkRuntime, r);
217
223
  }
224
+ const exportsInfo = moduleGraph.getExportsInfo(currentRoot);
225
+ const filteredRuntime = filterRuntime(chunkRuntime, r =>
226
+ exportsInfo.isModuleUsed(r)
227
+ );
228
+ const activeRuntime =
229
+ filteredRuntime === true
230
+ ? chunkRuntime
231
+ : filteredRuntime === false
232
+ ? undefined
233
+ : filteredRuntime;
218
234
 
219
235
  // create a configuration with the root
220
- const currentConfiguration = new ConcatConfiguration(currentRoot);
236
+ const currentConfiguration = new ConcatConfiguration(
237
+ currentRoot,
238
+ activeRuntime
239
+ );
221
240
 
222
241
  // cache failures to add modules
223
242
  const failureCache = new Map();
@@ -230,7 +249,7 @@ class ModuleConcatenationPlugin {
230
249
  for (const imp of this._getImports(
231
250
  compilation,
232
251
  currentRoot,
233
- runtime
252
+ activeRuntime
234
253
  )) {
235
254
  candidates.add(imp);
236
255
  }
@@ -244,7 +263,8 @@ class ModuleConcatenationPlugin {
244
263
  compilation,
245
264
  currentConfiguration,
246
265
  imp,
247
- runtime,
266
+ chunkRuntime,
267
+ activeRuntime,
248
268
  possibleInners,
249
269
  impCandidates,
250
270
  failureCache,
@@ -313,6 +333,7 @@ class ModuleConcatenationPlugin {
313
333
  let newModule = ConcatenatedModule.create(
314
334
  rootModule,
315
335
  modules,
336
+ concatConfiguration.runtime,
316
337
  compiler.root
317
338
  );
318
339
 
@@ -478,7 +499,8 @@ class ModuleConcatenationPlugin {
478
499
  * @param {Compilation} compilation webpack compilation
479
500
  * @param {ConcatConfiguration} config concat configuration (will be modified when added)
480
501
  * @param {Module} module the module to be added
481
- * @param {RuntimeSpec} runtime the runtime scope
502
+ * @param {RuntimeSpec} runtime the runtime scope of the generated code
503
+ * @param {RuntimeSpec} activeRuntime the runtime scope of the root module
482
504
  * @param {Set<Module>} possibleModules modules that are candidates
483
505
  * @param {Set<Module>} candidates list of potential candidates (will be added to)
484
506
  * @param {Map<Module, Module | function(RequestShortener): string>} failureCache cache for problematic modules to be more performant
@@ -490,6 +512,7 @@ class ModuleConcatenationPlugin {
490
512
  config,
491
513
  module,
492
514
  runtime,
515
+ activeRuntime,
493
516
  possibleModules,
494
517
  candidates,
495
518
  failureCache,
@@ -657,6 +680,50 @@ class ModuleConcatenationPlugin {
657
680
  return problem;
658
681
  }
659
682
 
683
+ if (runtime !== undefined && typeof runtime !== "string") {
684
+ // Module must be consistently referenced in the same runtimes
685
+ /** @type {Map<Module, boolean | RuntimeSpec>} */
686
+ const runtimeConditionMap = new Map();
687
+ for (const connection of incomingConnections) {
688
+ const runtimeCondition = filterRuntime(runtime, runtime => {
689
+ return connection.isTargetActive(runtime);
690
+ });
691
+ if (runtimeCondition === false) continue;
692
+ const old = runtimeConditionMap.get(connection.originModule) || false;
693
+ if (old === true) continue;
694
+ if (old !== false && runtimeCondition !== true) {
695
+ runtimeConditionMap.set(
696
+ connection.originModule,
697
+ mergeRuntime(old, runtimeCondition)
698
+ );
699
+ } else {
700
+ runtimeConditionMap.set(connection.originModule, runtimeCondition);
701
+ }
702
+ }
703
+ const otherRuntimeConnections = Array.from(runtimeConditionMap).filter(
704
+ ([, runtimeCondition]) => typeof runtimeCondition !== "boolean"
705
+ );
706
+ if (otherRuntimeConnections.length > 0) {
707
+ const problem = requestShortener => {
708
+ return `Module ${module.readableIdentifier(
709
+ requestShortener
710
+ )} is runtime-dependent referenced by these modules: ${Array.from(
711
+ otherRuntimeConnections,
712
+ ([module, runtimeCondition]) =>
713
+ `${module.readableIdentifier(
714
+ requestShortener
715
+ )} (expected runtime ${runtimeToString(
716
+ runtime
717
+ )}, module is only referenced in ${runtimeToString(
718
+ /** @type {RuntimeSpec} */ (runtimeCondition)
719
+ )})`
720
+ ).join(", ")}`;
721
+ };
722
+ failureCache.set(module, problem); // cache failures for performance
723
+ return problem;
724
+ }
725
+ }
726
+
660
727
  const incomingModules = Array.from(
661
728
  new Set(incomingConnections.map(c => c.originModule))
662
729
  ).sort(compareModulesByIdentifier);
@@ -668,6 +735,7 @@ class ModuleConcatenationPlugin {
668
735
  config,
669
736
  originModule,
670
737
  runtime,
738
+ activeRuntime,
671
739
  possibleModules,
672
740
  candidates,
673
741
  failureCache,
@@ -689,11 +757,12 @@ class ModuleConcatenationPlugin {
689
757
 
690
758
  class ConcatConfiguration {
691
759
  /**
692
- *
693
760
  * @param {Module} rootModule the root module
761
+ * @param {RuntimeSpec} runtime the runtime
694
762
  */
695
- constructor(rootModule) {
763
+ constructor(rootModule, runtime) {
696
764
  this.rootModule = rootModule;
765
+ this.runtime = runtime;
697
766
  /** @type {StackedMap<Module, true>} */
698
767
  this.modules = new StackedMap();
699
768
  this.modules.set(rootModule, true);
@@ -50,6 +50,12 @@ const globToRegexp = (glob, cache) => {
50
50
  };
51
51
 
52
52
  class SideEffectsFlagPlugin {
53
+ /**
54
+ * @param {boolean} analyseSource analyse source code for side effects
55
+ */
56
+ constructor(analyseSource = true) {
57
+ this._analyseSource = analyseSource;
58
+ }
53
59
  /**
54
60
  * Apply the plugin
55
61
  * @param {Compiler} compiler the compiler instance
@@ -98,108 +104,114 @@ class SideEffectsFlagPlugin {
98
104
  }
99
105
  return module;
100
106
  });
101
- /**
102
- * @param {JavascriptParser} parser the parser
103
- * @returns {void}
104
- */
105
- const parserHandler = parser => {
106
- let hasSideEffects = false;
107
- parser.hooks.program.tap("SideEffectsFlagPlugin", () => {
108
- hasSideEffects = false;
109
- });
110
- parser.hooks.statement.tap(
111
- { name: "SideEffectsFlagPlugin", stage: -100 },
112
- statement => {
113
- if (hasSideEffects) return;
114
- if (parser.scope.topLevelScope !== true) return;
115
- switch (statement.type) {
116
- case "ExpressionStatement":
117
- if (!parser.isPure(statement.expression, statement.range[0])) {
118
- hasSideEffects = true;
119
- }
120
- break;
121
- case "IfStatement":
122
- case "WhileStatement":
123
- case "DoWhileStatement":
124
- if (!parser.isPure(statement.test, statement.range[0])) {
125
- hasSideEffects = true;
126
- }
127
- // statement hook will be called for child statements too
128
- break;
129
- case "ForStatement":
130
- if (
131
- !parser.isPure(statement.init, statement.range[0]) ||
132
- !parser.isPure(
133
- statement.test,
134
- statement.init
135
- ? statement.init.range[1]
136
- : statement.range[0]
137
- ) ||
138
- !parser.isPure(
139
- statement.update,
140
- statement.test
141
- ? statement.test.range[1]
142
- : statement.init
143
- ? statement.init.range[1]
144
- : statement.range[0]
145
- )
146
- ) {
147
- hasSideEffects = true;
148
- }
149
- // statement hook will be called for child statements too
150
- break;
151
- case "SwitchStatement":
152
- if (
153
- !parser.isPure(statement.discriminant, statement.range[0])
154
- ) {
155
- hasSideEffects = true;
156
- }
157
- // statement hook will be called for child statements too
158
- break;
159
- case "VariableDeclaration":
160
- case "ClassDeclaration":
161
- case "FunctionDeclaration":
162
- if (!parser.isPure(statement, statement.range[0])) {
163
- hasSideEffects = true;
164
- }
165
- break;
166
- case "ExportDefaultDeclaration":
167
- if (!parser.isPure(statement.declaration, statement.range[0])) {
168
- hasSideEffects = true;
169
- }
170
- break;
171
- case "ExportNamedDeclaration":
172
- if (statement.source) {
107
+ if (this._analyseSource) {
108
+ /**
109
+ * @param {JavascriptParser} parser the parser
110
+ * @returns {void}
111
+ */
112
+ const parserHandler = parser => {
113
+ let hasSideEffects = false;
114
+ parser.hooks.program.tap("SideEffectsFlagPlugin", () => {
115
+ hasSideEffects = false;
116
+ });
117
+ parser.hooks.statement.tap(
118
+ { name: "SideEffectsFlagPlugin", stage: -100 },
119
+ statement => {
120
+ if (hasSideEffects) return;
121
+ if (parser.scope.topLevelScope !== true) return;
122
+ switch (statement.type) {
123
+ case "ExpressionStatement":
124
+ if (
125
+ !parser.isPure(statement.expression, statement.range[0])
126
+ ) {
127
+ hasSideEffects = true;
128
+ }
129
+ break;
130
+ case "IfStatement":
131
+ case "WhileStatement":
132
+ case "DoWhileStatement":
133
+ if (!parser.isPure(statement.test, statement.range[0])) {
134
+ hasSideEffects = true;
135
+ }
136
+ // statement hook will be called for child statements too
137
+ break;
138
+ case "ForStatement":
139
+ if (
140
+ !parser.isPure(statement.init, statement.range[0]) ||
141
+ !parser.isPure(
142
+ statement.test,
143
+ statement.init
144
+ ? statement.init.range[1]
145
+ : statement.range[0]
146
+ ) ||
147
+ !parser.isPure(
148
+ statement.update,
149
+ statement.test
150
+ ? statement.test.range[1]
151
+ : statement.init
152
+ ? statement.init.range[1]
153
+ : statement.range[0]
154
+ )
155
+ ) {
156
+ hasSideEffects = true;
157
+ }
158
+ // statement hook will be called for child statements too
159
+ break;
160
+ case "SwitchStatement":
161
+ if (
162
+ !parser.isPure(statement.discriminant, statement.range[0])
163
+ ) {
164
+ hasSideEffects = true;
165
+ }
166
+ // statement hook will be called for child statements too
167
+ break;
168
+ case "VariableDeclaration":
169
+ case "ClassDeclaration":
170
+ case "FunctionDeclaration":
171
+ if (!parser.isPure(statement, statement.range[0])) {
172
+ hasSideEffects = true;
173
+ }
174
+ break;
175
+ case "ExportDefaultDeclaration":
176
+ if (
177
+ !parser.isPure(statement.declaration, statement.range[0])
178
+ ) {
179
+ hasSideEffects = true;
180
+ }
181
+ break;
182
+ case "ExportNamedDeclaration":
183
+ if (statement.source) {
184
+ hasSideEffects = true;
185
+ }
186
+ break;
187
+ case "LabeledStatement":
188
+ case "BlockStatement":
189
+ // statement hook will be called for child statements too
190
+ break;
191
+ case "EmptyStatement":
192
+ break;
193
+ case "ImportDeclaration":
194
+ // imports will be handled by the dependencies
195
+ break;
196
+ default:
173
197
  hasSideEffects = true;
174
- }
175
- break;
176
- case "LabeledStatement":
177
- case "BlockStatement":
178
- // statement hook will be called for child statements too
179
- break;
180
- case "EmptyStatement":
181
- break;
182
- case "ImportDeclaration":
183
- // imports will be handled by the dependencies
184
- break;
185
- default:
186
- hasSideEffects = true;
187
- break;
198
+ break;
199
+ }
188
200
  }
189
- }
190
- );
191
- parser.hooks.finish.tap("SideEffectsFlagPlugin", () => {
192
- if (!hasSideEffects) {
193
- parser.state.module.buildMeta.sideEffectFree = true;
194
- }
195
- });
196
- };
197
- for (const key of [
198
- "javascript/auto",
199
- "javascript/esm",
200
- "javascript/dynamic"
201
- ]) {
202
- nmf.hooks.parser.for(key).tap("SideEffectsFlagPlugin", parserHandler);
201
+ );
202
+ parser.hooks.finish.tap("SideEffectsFlagPlugin", () => {
203
+ if (!hasSideEffects) {
204
+ parser.state.module.buildMeta.sideEffectFree = true;
205
+ }
206
+ });
207
+ };
208
+ for (const key of [
209
+ "javascript/auto",
210
+ "javascript/esm",
211
+ "javascript/dynamic"
212
+ ]) {
213
+ nmf.hooks.parser.for(key).tap("SideEffectsFlagPlugin", parserHandler);
214
+ }
203
215
  }
204
216
  });
205
217
  compiler.hooks.compilation.tap("SideEffectsFlagPlugin", compilation => {
@@ -0,0 +1,29 @@
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 RuntimeModule = require("../RuntimeModule");
9
+
10
+ class RuntimeIdRuntimeModule extends RuntimeModule {
11
+ constructor() {
12
+ super("runtimeId");
13
+ }
14
+
15
+ /**
16
+ * @returns {string} runtime code
17
+ */
18
+ generate() {
19
+ const { chunk, compilation } = this;
20
+ const { chunkGraph } = compilation;
21
+ const runtime = chunk.runtime;
22
+ if (typeof runtime !== "string")
23
+ throw new Error("RuntimeIdRuntimeModule must be in a single runtime");
24
+ const id = chunkGraph.getRuntimeId(runtime);
25
+ return `${RuntimeGlobals.runtimeId} = ${JSON.stringify(id)};`;
26
+ }
27
+ }
28
+
29
+ module.exports = RuntimeIdRuntimeModule;
@@ -25,6 +25,17 @@ const compileBooleanMatcher = map => {
25
25
  const negativeItems = Object.keys(map).filter(i => !map[i]);
26
26
  if (positiveItems.length === 0) return false;
27
27
  if (negativeItems.length === 0) return true;
28
+ return compileBooleanMatcherFromLists(positiveItems, negativeItems);
29
+ };
30
+
31
+ /**
32
+ * @param {string[]} positiveItems positive items
33
+ * @param {string[]} negativeItems negative items
34
+ * @returns {function(string): string} a template function to determine the value at runtime
35
+ */
36
+ const compileBooleanMatcherFromLists = (positiveItems, negativeItems) => {
37
+ if (positiveItems.length === 0) return () => "false";
38
+ if (negativeItems.length === 0) return () => "true";
28
39
  if (positiveItems.length === 1)
29
40
  return value => `${toSimpleString(positiveItems[0])} == ${value}`;
30
41
  if (negativeItems.length === 1)
@@ -188,5 +199,6 @@ const itemsToRegexp = itemsArr => {
188
199
  return `(${conditional.join("|")})`;
189
200
  };
190
201
 
202
+ compileBooleanMatcher.fromLists = compileBooleanMatcherFromLists;
203
+ compileBooleanMatcher.itemsToRegexp = itemsToRegexp;
191
204
  module.exports = compileBooleanMatcher;
192
- module.exports.itemsToRegexp = itemsToRegexp;
@@ -11,6 +11,7 @@ const SortableSet = require("./SortableSet");
11
11
  /** @typedef {import("../Entrypoint").EntryOptions} EntryOptions */
12
12
 
13
13
  /** @typedef {string | SortableSet<string> | undefined} RuntimeSpec */
14
+ /** @typedef {RuntimeSpec | boolean} RuntimeCondition */
14
15
 
15
16
  /**
16
17
  * @param {Compilation} compilation the compilation
@@ -104,11 +105,22 @@ const getRuntimesString = set => {
104
105
  * @param {RuntimeSpec} runtime runtime(s)
105
106
  * @returns {string} readable version
106
107
  */
107
- exports.runtimeToString = runtime => {
108
+ const runtimeToString = runtime => {
108
109
  if (runtime === undefined) return "*";
109
110
  if (typeof runtime === "string") return runtime;
110
111
  return runtime.getFromUnorderedCache(getRuntimesString);
111
112
  };
113
+ exports.runtimeToString = runtimeToString;
114
+
115
+ /**
116
+ * @param {RuntimeCondition} runtimeCondition runtime condition
117
+ * @returns {string} readable version
118
+ */
119
+ exports.runtimeConditionToString = runtimeCondition => {
120
+ if (runtimeCondition === true) return "true";
121
+ if (runtimeCondition === false) return "false";
122
+ return runtimeToString(runtimeCondition);
123
+ };
112
124
 
113
125
  /**
114
126
  * @param {RuntimeSpec} a first
@@ -203,6 +215,46 @@ const mergeRuntime = (a, b) => {
203
215
  };
204
216
  exports.mergeRuntime = mergeRuntime;
205
217
 
218
+ /**
219
+ * @param {RuntimeCondition} a first
220
+ * @param {RuntimeCondition} b second
221
+ * @param {RuntimeSpec} runtime full runtime
222
+ * @returns {RuntimeCondition} result
223
+ */
224
+ exports.mergeRuntimeCondition = (a, b, runtime) => {
225
+ if (a === false) return b;
226
+ if (b === false) return a;
227
+ if (a === true || b === true) return true;
228
+ const merged = mergeRuntime(a, b);
229
+ if (merged === undefined) return undefined;
230
+ if (typeof merged === "string") {
231
+ if (typeof runtime === "string" && merged === runtime) return true;
232
+ return merged;
233
+ }
234
+ if (typeof runtime === "string" || runtime === undefined) return merged;
235
+ if (merged.size === runtime.size) return true;
236
+ return merged;
237
+ };
238
+
239
+ /**
240
+ * @param {RuntimeSpec | true} a first
241
+ * @param {RuntimeSpec | true} b second
242
+ * @param {RuntimeSpec} runtime full runtime
243
+ * @returns {RuntimeSpec | true} result
244
+ */
245
+ exports.mergeRuntimeConditionNonFalse = (a, b, runtime) => {
246
+ if (a === true || b === true) return true;
247
+ const merged = mergeRuntime(a, b);
248
+ if (merged === undefined) return undefined;
249
+ if (typeof merged === "string") {
250
+ if (typeof runtime === "string" && merged === runtime) return true;
251
+ return merged;
252
+ }
253
+ if (typeof runtime === "string" || runtime === undefined) return merged;
254
+ if (merged.size === runtime.size) return true;
255
+ return merged;
256
+ };
257
+
206
258
  /**
207
259
  * @param {RuntimeSpec} a first (may be modified)
208
260
  * @param {RuntimeSpec} b second
@@ -280,6 +332,88 @@ exports.intersectRuntime = (a, b) => {
280
332
  }
281
333
  };
282
334
 
335
+ /**
336
+ * @param {RuntimeSpec} a first
337
+ * @param {RuntimeSpec} b second
338
+ * @returns {RuntimeSpec} result
339
+ */
340
+ const subtractRuntime = (a, b) => {
341
+ if (a === undefined) {
342
+ return undefined;
343
+ } else if (b === undefined) {
344
+ return a;
345
+ } else if (a === b) {
346
+ return undefined;
347
+ } else if (typeof a === "string") {
348
+ if (typeof b === "string") {
349
+ return undefined;
350
+ } else if (b.has(a)) {
351
+ return undefined;
352
+ } else {
353
+ return a;
354
+ }
355
+ } else {
356
+ if (typeof b === "string") {
357
+ if (!a.has(b)) return a;
358
+ if (a.size === 2) {
359
+ for (const item of a) {
360
+ if (item !== b) return item;
361
+ }
362
+ }
363
+ const set = new SortableSet(a);
364
+ set.delete(b);
365
+ } else {
366
+ const set = new SortableSet();
367
+ for (const item of a) {
368
+ if (!b.has(item)) set.add(item);
369
+ }
370
+ if (set.size === 0) return undefined;
371
+ if (set.size === 1) for (const item of set) return item;
372
+ return set;
373
+ }
374
+ }
375
+ };
376
+ exports.subtractRuntime = subtractRuntime;
377
+
378
+ /**
379
+ * @param {RuntimeCondition} a first
380
+ * @param {RuntimeCondition} b second
381
+ * @param {RuntimeSpec} runtime runtime
382
+ * @returns {RuntimeCondition} result
383
+ */
384
+ exports.subtractRuntimeCondition = (a, b, runtime) => {
385
+ if (b === true) return false;
386
+ if (b === false) return a;
387
+ if (a === false) return false;
388
+ const result = subtractRuntime(a === true ? runtime : a, b);
389
+ return result === undefined ? false : result;
390
+ };
391
+
392
+ /**
393
+ * @param {RuntimeSpec} runtime runtime
394
+ * @param {function(RuntimeSpec): boolean} filter filter function
395
+ * @returns {boolean | RuntimeSpec} true/false if filter is constant for all runtimes, otherwise runtimes that are active
396
+ */
397
+ exports.filterRuntime = (runtime, filter) => {
398
+ if (runtime === undefined) return filter(undefined);
399
+ if (typeof runtime === "string") return filter(runtime);
400
+ let some = false;
401
+ let every = true;
402
+ let result = undefined;
403
+ for (const r of runtime) {
404
+ const v = filter(r);
405
+ if (v) {
406
+ some = true;
407
+ result = mergeRuntimeOwned(result, r);
408
+ } else {
409
+ every = false;
410
+ }
411
+ }
412
+ if (!some) return false;
413
+ if (every) return true;
414
+ return result;
415
+ };
416
+
283
417
  /**
284
418
  * @template T
285
419
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "5.2.1",
3
+ "version": "5.4.0",
4
4
  "author": "Tobias Koppers @sokra",
5
5
  "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
6
6
  "license": "MIT",
@@ -26,9 +26,9 @@
26
26
  "pkg-dir": "^4.2.0",
27
27
  "schema-utils": "^3.0.0",
28
28
  "tapable": "^2.0.0",
29
- "terser-webpack-plugin": "^5.0.0",
29
+ "terser-webpack-plugin": "^5.0.3",
30
30
  "watchpack": "^2.0.0",
31
- "webpack-sources": "^2.1.0"
31
+ "webpack-sources": "^2.1.1"
32
32
  },
33
33
  "peerDependenciesMeta": {
34
34
  "webpack-cli": {
@@ -92,13 +92,12 @@
92
92
  "style-loader": "^1.1.4",
93
93
  "terser": "^4.8.0",
94
94
  "toml": "^3.0.0",
95
- "tooling": "webpack/tooling#v1.8.0",
95
+ "tooling": "webpack/tooling#v1.8.1",
96
96
  "ts-loader": "^8.0.2",
97
97
  "typescript": "^3.9.7",
98
98
  "url-loader": "^4.1.0",
99
99
  "wast-loader": "^1.9.0",
100
100
  "webassembly-feature": "1.3.0",
101
- "worker-loader": "^3.0.1",
102
101
  "xxhashjs": "^0.2.2",
103
102
  "yamljs": "^0.3.0",
104
103
  "yarn-deduplicate": "^2.1.1"
@@ -1350,8 +1350,15 @@
1350
1350
  "$ref": "#/definitions/OptimizationRuntimeChunk"
1351
1351
  },
1352
1352
  "sideEffects": {
1353
- "description": "Skip over modules which are flagged to contain no side effects when exports are not used.",
1354
- "type": "boolean"
1353
+ "description": "Skip over modules which contain no side effects when exports are not used (false: disabled, 'flag': only use manually placed side effects flag, true: also analyse source code for side effects).",
1354
+ "anyOf": [
1355
+ {
1356
+ "enum": ["flag"]
1357
+ },
1358
+ {
1359
+ "type": "boolean"
1360
+ }
1361
+ ]
1355
1362
  },
1356
1363
  "splitChunks": {
1357
1364
  "description": "Optimize duplication and caching by splitting chunks by shared modules and cache group.",