webpack 5.92.1 → 5.93.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.

Files changed (31) hide show
  1. package/lib/ContextModule.js +4 -2
  2. package/lib/DefinePlugin.js +1 -1
  3. package/lib/NormalModule.js +6 -1
  4. package/lib/UseStrictPlugin.js +8 -1
  5. package/lib/WebpackOptionsApply.js +5 -0
  6. package/lib/css/CssExportsGenerator.js +18 -21
  7. package/lib/css/CssGenerator.js +3 -11
  8. package/lib/dependencies/CssExportDependency.js +72 -9
  9. package/lib/dependencies/CssLocalIdentifierDependency.js +67 -20
  10. package/lib/dependencies/HarmonyImportSpecifierDependency.js +2 -2
  11. package/lib/esm/ModuleChunkFormatPlugin.js +8 -9
  12. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +1 -0
  13. package/lib/javascript/CommonJsChunkFormatPlugin.js +7 -9
  14. package/lib/javascript/JavascriptModulesPlugin.js +6 -1
  15. package/lib/library/AssignLibraryPlugin.js +1 -1
  16. package/lib/library/EnableLibraryPlugin.js +10 -1
  17. package/lib/library/ExportPropertyLibraryPlugin.js +8 -2
  18. package/lib/library/ModernModuleLibraryPlugin.js +142 -0
  19. package/lib/optimize/ConcatenatedModule.js +69 -18
  20. package/lib/optimize/ModuleConcatenationPlugin.js +2 -0
  21. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +1 -0
  22. package/lib/sharing/ConsumeSharedModule.js +19 -14
  23. package/lib/sharing/ConsumeSharedRuntimeModule.js +104 -137
  24. package/lib/util/conventions.js +2 -2
  25. package/package.json +3 -3
  26. package/schemas/WebpackOptions.check.js +1 -1
  27. package/schemas/WebpackOptions.json +16 -0
  28. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  29. package/schemas/plugins/asset/AssetInlineGeneratorOptions.check.js +1 -1
  30. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  31. package/types.d.ts +15 -0
@@ -30,6 +30,7 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
30
30
  * @typedef {object} ExportPropertyLibraryPluginOptions
31
31
  * @property {LibraryType} type
32
32
  * @property {boolean} nsObjectUsed the namespace object is used
33
+ * @property {boolean} runtimeExportsUsed runtime exports are used
33
34
  */
34
35
  /**
35
36
  * @typedef {ExportPropertyLibraryPluginParsed} T
@@ -39,12 +40,13 @@ class ExportPropertyLibraryPlugin extends AbstractLibraryPlugin {
39
40
  /**
40
41
  * @param {ExportPropertyLibraryPluginOptions} options options
41
42
  */
42
- constructor({ type, nsObjectUsed }) {
43
+ constructor({ type, nsObjectUsed, runtimeExportsUsed }) {
43
44
  super({
44
45
  pluginName: "ExportPropertyLibraryPlugin",
45
46
  type
46
47
  });
47
48
  this.nsObjectUsed = nsObjectUsed;
49
+ this.runtimeExportsUsed = runtimeExportsUsed;
48
50
  }
49
51
 
50
52
  /**
@@ -93,7 +95,11 @@ class ExportPropertyLibraryPlugin extends AbstractLibraryPlugin {
93
95
  * @param {LibraryContext<T>} libraryContext context
94
96
  * @returns {void}
95
97
  */
96
- runtimeRequirements(chunk, set, libraryContext) {}
98
+ runtimeRequirements(chunk, set, libraryContext) {
99
+ if (this.runtimeExportsUsed) {
100
+ set.add(RuntimeGlobals.exports);
101
+ }
102
+ }
97
103
 
98
104
  /**
99
105
  * @param {Source} source source
@@ -0,0 +1,142 @@
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 } = require("webpack-sources");
9
+ const ConcatenatedModule = require("../optimize/ConcatenatedModule");
10
+ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
11
+
12
+ /** @typedef {import("webpack-sources").Source} Source */
13
+ /** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
14
+ /** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
15
+ /** @typedef {import("../Chunk")} Chunk */
16
+ /** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
17
+ /** @typedef {import("../Compiler")} Compiler */
18
+ /** @typedef {import("../Module")} Module */
19
+ /** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */
20
+ /** @typedef {import("../util/Hash")} Hash */
21
+ /** @template T @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T> */
22
+
23
+ /**
24
+ * @typedef {object} ModernModuleLibraryPluginOptions
25
+ * @property {LibraryType} type
26
+ */
27
+
28
+ /**
29
+ * @typedef {object} ModernModuleLibraryPluginParsed
30
+ * @property {string} name
31
+ */
32
+
33
+ /**
34
+ * @typedef {ModernModuleLibraryPluginParsed} T
35
+ * @extends {AbstractLibraryPlugin<ModernModuleLibraryPluginParsed>}
36
+ */
37
+ class ModernModuleLibraryPlugin extends AbstractLibraryPlugin {
38
+ /**
39
+ * Apply the plugin
40
+ * @param {Compiler} compiler the compiler instance
41
+ * @returns {void}
42
+ */
43
+ apply(compiler) {
44
+ super.apply(compiler);
45
+
46
+ compiler.hooks.compilation.tap("ModernModuleLibraryPlugin", compilation => {
47
+ const { exportsDefinitions } =
48
+ ConcatenatedModule.getCompilationHooks(compilation);
49
+ exportsDefinitions.tap("ModernModuleLibraryPlugin", () => {
50
+ return true;
51
+ });
52
+ });
53
+ }
54
+
55
+ /**
56
+ * @param {ModernModuleLibraryPluginOptions} options the plugin options
57
+ */
58
+ constructor(options) {
59
+ super({
60
+ pluginName: "ModernModuleLibraryPlugin",
61
+ type: options.type
62
+ });
63
+ }
64
+
65
+ /**
66
+ * @param {LibraryOptions} library normalized library option
67
+ * @returns {T | false} preprocess as needed by overriding
68
+ */
69
+ parseOptions(library) {
70
+ const { name } = library;
71
+ if (name) {
72
+ throw new Error(
73
+ `Library name must be unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}`
74
+ );
75
+ }
76
+ return {
77
+ name: /** @type {string} */ (name)
78
+ };
79
+ }
80
+
81
+ /**
82
+ * @param {Source} source source
83
+ * @param {Module} module module
84
+ * @param {StartupRenderContext} renderContext render context
85
+ * @param {LibraryContext<T>} libraryContext context
86
+ * @returns {Source} source with library export
87
+ */
88
+ renderStartup(
89
+ source,
90
+ module,
91
+ { moduleGraph, chunk },
92
+ { options, compilation }
93
+ ) {
94
+ const result = new ConcatSource(source);
95
+ const exportsInfo = moduleGraph.getExportsInfo(module);
96
+ const definitions = module.buildMeta.exportsFinalName;
97
+ const exports = [];
98
+
99
+ for (const exportInfo of exportsInfo.orderedExports) {
100
+ let shouldContinue = false;
101
+ const reexport = exportInfo.findTarget(moduleGraph, _m => true);
102
+
103
+ if (reexport) {
104
+ const exp = moduleGraph.getExportsInfo(reexport.module);
105
+
106
+ for (const reexportInfo of exp.orderedExports) {
107
+ if (
108
+ !reexportInfo.provided &&
109
+ reexportInfo.name === reexport.export[0]
110
+ ) {
111
+ shouldContinue = true;
112
+ }
113
+ }
114
+ }
115
+
116
+ if (shouldContinue) continue;
117
+
118
+ const webpackExportsProperty = exportInfo.getUsedName(
119
+ exportInfo.name,
120
+ chunk.runtime
121
+ );
122
+ const finalName =
123
+ definitions[
124
+ /** @type {string} */
125
+ (webpackExportsProperty)
126
+ ];
127
+ exports.push(
128
+ finalName === exportInfo.name
129
+ ? finalName
130
+ : `${finalName} as ${exportInfo.name}`
131
+ );
132
+ }
133
+
134
+ if (exports.length > 0) {
135
+ result.add(`export { ${exports.join(", ")} };\n`);
136
+ }
137
+
138
+ return result;
139
+ }
140
+ }
141
+
142
+ module.exports = ModernModuleLibraryPlugin;
@@ -7,6 +7,7 @@
7
7
 
8
8
  const eslintScope = require("eslint-scope");
9
9
  const Referencer = require("eslint-scope/lib/referencer");
10
+ const { SyncBailHook } = require("tapable");
10
11
  const {
11
12
  CachedSource,
12
13
  ConcatSource,
@@ -628,11 +629,20 @@ const addScopeSymbols = (s, nameSet, scopeSet1, scopeSet2) => {
628
629
 
629
630
  const TYPES = new Set(["javascript"]);
630
631
 
632
+ /**
633
+ * @typedef {object} ConcatenateModuleHooks
634
+ * @property {SyncBailHook<[Record<string, string>]>} exportsDefinitions
635
+ */
636
+
637
+ /** @type {WeakMap<Compilation, ConcatenateModuleHooks>} */
638
+ const compilationHooksMap = new WeakMap();
639
+
631
640
  class ConcatenatedModule extends Module {
632
641
  /**
633
642
  * @param {Module} rootModule the root module of the concatenation
634
643
  * @param {Set<Module>} modules all modules in the concatenation (including the root module)
635
644
  * @param {RuntimeSpec} runtime the runtime
645
+ * @param {Compilation} compilation the compilation
636
646
  * @param {object=} associatedObjectForCache object for caching
637
647
  * @param {string | HashConstructor=} hashFunction hash function to use
638
648
  * @returns {ConcatenatedModule} the module
@@ -641,6 +651,7 @@ class ConcatenatedModule extends Module {
641
651
  rootModule,
642
652
  modules,
643
653
  runtime,
654
+ compilation,
644
655
  associatedObjectForCache,
645
656
  hashFunction = "md4"
646
657
  ) {
@@ -654,18 +665,35 @@ class ConcatenatedModule extends Module {
654
665
  identifier,
655
666
  rootModule,
656
667
  modules,
657
- runtime
668
+ runtime,
669
+ compilation
658
670
  });
659
671
  }
660
672
 
673
+ /**
674
+ * @param {Compilation} compilation the compilation
675
+ * @returns {ConcatenateModuleHooks} the attached hooks
676
+ */
677
+ static getCompilationHooks(compilation) {
678
+ let hooks = compilationHooksMap.get(compilation);
679
+ if (hooks === undefined) {
680
+ hooks = {
681
+ exportsDefinitions: new SyncBailHook(["definitions"])
682
+ };
683
+ compilationHooksMap.set(compilation, hooks);
684
+ }
685
+ return hooks;
686
+ }
687
+
661
688
  /**
662
689
  * @param {object} options options
663
690
  * @param {string} options.identifier the identifier of the module
664
691
  * @param {Module=} options.rootModule the root module of the concatenation
665
692
  * @param {RuntimeSpec} options.runtime the selected runtime
666
693
  * @param {Set<Module>=} options.modules all concatenated modules
694
+ * @param {Compilation} options.compilation the compilation
667
695
  */
668
- constructor({ identifier, rootModule, modules, runtime }) {
696
+ constructor({ identifier, rootModule, modules, runtime, compilation }) {
669
697
  super(JAVASCRIPT_MODULE_TYPE_ESM, null, rootModule && rootModule.layer);
670
698
 
671
699
  // Info from Factory
@@ -677,6 +705,8 @@ class ConcatenatedModule extends Module {
677
705
  this._modules = modules;
678
706
  this._runtime = runtime;
679
707
  this.factoryMeta = rootModule && rootModule.factoryMeta;
708
+ /** @type {Compilation | undefined} */
709
+ this.compilation = compilation;
680
710
  }
681
711
 
682
712
  /**
@@ -1427,6 +1457,8 @@ class ConcatenatedModule extends Module {
1427
1457
  /** @type {BuildMeta} */
1428
1458
  (rootInfo.module.buildMeta).strictHarmonyModule;
1429
1459
  const exportsInfo = moduleGraph.getExportsInfo(rootInfo.module);
1460
+ /** @type {Record<string, string>} */
1461
+ const exportsFinalName = {};
1430
1462
  for (const exportInfo of exportsInfo.orderedExports) {
1431
1463
  const name = exportInfo.name;
1432
1464
  if (exportInfo.provided === false) continue;
@@ -1451,6 +1483,7 @@ class ConcatenatedModule extends Module {
1451
1483
  strictHarmonyModule,
1452
1484
  true
1453
1485
  );
1486
+ exportsFinalName[used] = finalName;
1454
1487
  return `/* ${
1455
1488
  exportInfo.isReexport() ? "reexport" : "binding"
1456
1489
  } */ ${finalName}`;
@@ -1466,23 +1499,20 @@ class ConcatenatedModule extends Module {
1466
1499
  const result = new ConcatSource();
1467
1500
 
1468
1501
  // add harmony compatibility flag (must be first because of possible circular dependencies)
1502
+ let shouldAddHarmonyFlag = false;
1469
1503
  if (
1470
1504
  moduleGraph.getExportsInfo(this).otherExportsInfo.getUsed(runtime) !==
1471
1505
  UsageState.Unused
1472
1506
  ) {
1473
- result.add(`// ESM COMPAT FLAG\n`);
1474
- result.add(
1475
- runtimeTemplate.defineEsModuleFlagStatement({
1476
- exportsArgument: this.exportsArgument,
1477
- runtimeRequirements
1478
- })
1479
- );
1507
+ shouldAddHarmonyFlag = true;
1480
1508
  }
1481
1509
 
1482
1510
  // define exports
1483
1511
  if (exportsMap.size > 0) {
1484
- runtimeRequirements.add(RuntimeGlobals.exports);
1485
- runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
1512
+ const { exportsDefinitions } = ConcatenatedModule.getCompilationHooks(
1513
+ this.compilation
1514
+ );
1515
+
1486
1516
  const definitions = [];
1487
1517
  for (const [key, value] of exportsMap) {
1488
1518
  definitions.push(
@@ -1491,12 +1521,32 @@ class ConcatenatedModule extends Module {
1491
1521
  )}`
1492
1522
  );
1493
1523
  }
1494
- result.add(`\n// EXPORTS\n`);
1495
- result.add(
1496
- `${RuntimeGlobals.definePropertyGetters}(${
1497
- this.exportsArgument
1498
- }, {${definitions.join(",")}\n});\n`
1499
- );
1524
+ const shouldSkipRenderDefinitions =
1525
+ exportsDefinitions.call(exportsFinalName);
1526
+
1527
+ if (!shouldSkipRenderDefinitions) {
1528
+ runtimeRequirements.add(RuntimeGlobals.exports);
1529
+ runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
1530
+
1531
+ if (shouldAddHarmonyFlag) {
1532
+ result.add(`// ESM COMPAT FLAG\n`);
1533
+ result.add(
1534
+ runtimeTemplate.defineEsModuleFlagStatement({
1535
+ exportsArgument: this.exportsArgument,
1536
+ runtimeRequirements
1537
+ })
1538
+ );
1539
+ }
1540
+
1541
+ result.add(`\n// EXPORTS\n`);
1542
+ result.add(
1543
+ `${RuntimeGlobals.definePropertyGetters}(${
1544
+ this.exportsArgument
1545
+ }, {${definitions.join(",")}\n});\n`
1546
+ );
1547
+ } else {
1548
+ this.buildMeta.exportsFinalName = exportsFinalName;
1549
+ }
1500
1550
  }
1501
1551
 
1502
1552
  // list unused exports
@@ -1913,7 +1963,8 @@ ${defineGetters}`
1913
1963
  identifier: undefined,
1914
1964
  rootModule: undefined,
1915
1965
  modules: undefined,
1916
- runtime: undefined
1966
+ runtime: undefined,
1967
+ compilation: undefined
1917
1968
  });
1918
1969
  obj.deserialize(context);
1919
1970
  return obj;
@@ -398,10 +398,12 @@ class ModuleConcatenationPlugin {
398
398
  }
399
399
 
400
400
  // Create a new ConcatenatedModule
401
+ ConcatenatedModule.getCompilationHooks(compilation);
401
402
  let newModule = ConcatenatedModule.create(
402
403
  rootModule,
403
404
  modules,
404
405
  concatConfiguration.runtime,
406
+ compilation,
405
407
  compiler.root,
406
408
  compilation.outputOptions.hashFunction
407
409
  );
@@ -35,6 +35,7 @@ class ChunkPrefetchPreloadPlugin {
35
35
  if (startupChildChunks) {
36
36
  set.add(RuntimeGlobals.prefetchChunk);
37
37
  set.add(RuntimeGlobals.onChunksLoaded);
38
+ set.add(RuntimeGlobals.exports);
38
39
  compilation.addRuntimeModule(
39
40
  chunk,
40
41
  new ChunkPrefetchStartupRuntimeModule(startupChildChunks)
@@ -207,26 +207,31 @@ class ConsumeSharedModule extends Module {
207
207
  });
208
208
  }
209
209
  }
210
- let fn = "load";
211
- const args = [JSON.stringify(shareScope), JSON.stringify(shareKey)];
210
+
211
+ const args = [
212
+ JSON.stringify(shareScope),
213
+ JSON.stringify(shareKey),
214
+ JSON.stringify(eager)
215
+ ];
212
216
  if (requiredVersion) {
213
- if (strictVersion) {
214
- fn += "Strict";
215
- }
216
- if (singleton) {
217
- fn += "Singleton";
218
- }
219
217
  args.push(stringifyHoley(requiredVersion));
220
- fn += "VersionCheck";
221
- } else {
222
- if (singleton) {
223
- fn += "Singleton";
224
- }
225
218
  }
226
219
  if (fallbackCode) {
227
- fn += "Fallback";
228
220
  args.push(fallbackCode);
229
221
  }
222
+
223
+ let fn;
224
+
225
+ if (requiredVersion) {
226
+ if (strictVersion) {
227
+ fn = singleton ? "loadStrictSingletonVersion" : "loadStrictVersion";
228
+ } else {
229
+ fn = singleton ? "loadSingletonVersion" : "loadVersion";
230
+ }
231
+ } else {
232
+ fn = singleton ? "loadSingleton" : "load";
233
+ }
234
+
230
235
  const code = runtimeTemplate.returningFunction(`${fn}(${args.join(", ")})`);
231
236
  const sources = new Map();
232
237
  sources.set("consume-shared", new RawSource(code));