webpack 5.40.0 → 5.42.1

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 (50) hide show
  1. package/README.md +3 -3
  2. package/bin/webpack.js +0 -0
  3. package/lib/Compiler.js +14 -1
  4. package/lib/ConditionalInitFragment.js +15 -12
  5. package/lib/DependencyTemplate.js +3 -2
  6. package/lib/ExternalModule.js +213 -33
  7. package/lib/ExternalModuleFactoryPlugin.js +2 -1
  8. package/lib/InitFragment.js +10 -7
  9. package/lib/MainTemplate.js +1 -1
  10. package/lib/ModuleTemplate.js +0 -9
  11. package/lib/NormalModuleFactory.js +13 -2
  12. package/lib/RuntimeTemplate.js +8 -0
  13. package/lib/Template.js +3 -2
  14. package/lib/TemplatedPathPlugin.js +24 -26
  15. package/lib/Watching.js +2 -1
  16. package/lib/WebpackOptionsApply.js +12 -8
  17. package/lib/asset/AssetGenerator.js +2 -2
  18. package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -1
  19. package/lib/cache/IdleFileCachePlugin.js +60 -13
  20. package/lib/cache/PackFileCacheStrategy.js +26 -15
  21. package/lib/config/defaults.js +54 -12
  22. package/lib/config/normalization.js +2 -0
  23. package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
  24. package/lib/dependencies/WorkerPlugin.js +25 -10
  25. package/lib/electron/ElectronTargetPlugin.js +3 -3
  26. package/lib/esm/ModuleChunkFormatPlugin.js +97 -0
  27. package/lib/esm/ModuleChunkLoadingPlugin.js +63 -0
  28. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +208 -0
  29. package/lib/hmr/lazyCompilationBackend.js +17 -1
  30. package/lib/javascript/EnableChunkLoadingPlugin.js +5 -3
  31. package/lib/javascript/JavascriptModulesPlugin.js +80 -17
  32. package/lib/javascript/JavascriptParser.js +2 -1
  33. package/lib/json/JsonGenerator.js +2 -2
  34. package/lib/node/NodeTargetPlugin.js +1 -1
  35. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +44 -22
  36. package/lib/optimize/ModuleConcatenationPlugin.js +1 -1
  37. package/lib/runtime/AsyncModuleRuntimeModule.js +8 -4
  38. package/lib/serialization/BinaryMiddleware.js +50 -35
  39. package/lib/serialization/FileMiddleware.js +112 -12
  40. package/lib/wasm/EnableWasmLoadingPlugin.js +10 -1
  41. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +1 -1
  42. package/package.json +15 -15
  43. package/schemas/WebpackOptions.check.js +1 -1
  44. package/schemas/WebpackOptions.json +22 -8
  45. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  46. package/schemas/plugins/container/ContainerReferencePlugin.json +2 -1
  47. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  48. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  49. package/schemas/plugins/container/ModuleFederationPlugin.json +2 -1
  50. package/types.d.ts +105 -151
@@ -48,9 +48,10 @@ const DEFAULT_SYNTAX = [
48
48
  const workerIndexMap = new WeakMap();
49
49
 
50
50
  class WorkerPlugin {
51
- constructor(chunkLoading, wasmLoading) {
51
+ constructor(chunkLoading, wasmLoading, module) {
52
52
  this._chunkLoading = chunkLoading;
53
53
  this._wasmLoading = wasmLoading;
54
+ this._module = module;
54
55
  }
55
56
  /**
56
57
  * Apply the plugin
@@ -311,31 +312,45 @@ class WorkerPlugin {
311
312
  if (expressions.type) {
312
313
  const expr = expressions.type;
313
314
  if (options.type !== false) {
314
- const dep = new ConstDependency("undefined", expr.range);
315
+ const dep = new ConstDependency(
316
+ this._module ? '"module"' : "undefined",
317
+ expr.range
318
+ );
315
319
  dep.loc = expr.loc;
316
320
  parser.state.module.addPresentationalDependency(dep);
317
321
  expressions.type = undefined;
318
322
  }
319
- } else if (hasSpreadInOptions && insertType === "comma") {
320
- const dep = new ConstDependency(
321
- ", type: undefined",
322
- insertLocation
323
- );
324
- dep.loc = expr.loc;
325
- parser.state.module.addPresentationalDependency(dep);
323
+ } else if (insertType === "comma") {
324
+ if (this._module || hasSpreadInOptions) {
325
+ const dep = new ConstDependency(
326
+ `, type: ${this._module ? '"module"' : "undefined"}`,
327
+ insertLocation
328
+ );
329
+ dep.loc = expr.loc;
330
+ parser.state.module.addPresentationalDependency(dep);
331
+ }
326
332
  } else if (insertType === "spread") {
327
333
  const dep1 = new ConstDependency(
328
334
  "Object.assign({}, ",
329
335
  insertLocation[0]
330
336
  );
331
337
  const dep2 = new ConstDependency(
332
- ", { type: undefined })",
338
+ `, { type: ${this._module ? '"module"' : "undefined"} })`,
333
339
  insertLocation[1]
334
340
  );
335
341
  dep1.loc = expr.loc;
336
342
  dep2.loc = expr.loc;
337
343
  parser.state.module.addPresentationalDependency(dep1);
338
344
  parser.state.module.addPresentationalDependency(dep2);
345
+ } else if (insertType === "argument") {
346
+ if (this._module) {
347
+ const dep = new ConstDependency(
348
+ ', { type: "module" }',
349
+ insertLocation
350
+ );
351
+ dep.loc = expr.loc;
352
+ parser.state.module.addPresentationalDependency(dep);
353
+ }
339
354
  }
340
355
 
341
356
  parser.walkExpression(expr.callee);
@@ -22,7 +22,7 @@ class ElectronTargetPlugin {
22
22
  * @returns {void}
23
23
  */
24
24
  apply(compiler) {
25
- new ExternalsPlugin("commonjs", [
25
+ new ExternalsPlugin("node-commonjs", [
26
26
  "clipboard",
27
27
  "crash-reporter",
28
28
  "electron",
@@ -34,7 +34,7 @@ class ElectronTargetPlugin {
34
34
  ]).apply(compiler);
35
35
  switch (this._context) {
36
36
  case "main":
37
- new ExternalsPlugin("commonjs", [
37
+ new ExternalsPlugin("node-commonjs", [
38
38
  "app",
39
39
  "auto-updater",
40
40
  "browser-window",
@@ -54,7 +54,7 @@ class ElectronTargetPlugin {
54
54
  break;
55
55
  case "preload":
56
56
  case "renderer":
57
- new ExternalsPlugin("commonjs", [
57
+ new ExternalsPlugin("node-commonjs", [
58
58
  "desktop-capturer",
59
59
  "ipc-renderer",
60
60
  "remote",
@@ -0,0 +1,97 @@
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 { RuntimeGlobals } = require("..");
10
+ const HotUpdateChunk = require("../HotUpdateChunk");
11
+ const Template = require("../Template");
12
+ const {
13
+ getCompilationHooks
14
+ } = require("../javascript/JavascriptModulesPlugin");
15
+
16
+ /** @typedef {import("../Compiler")} Compiler */
17
+
18
+ class ModuleChunkFormatPlugin {
19
+ /**
20
+ * Apply the plugin
21
+ * @param {Compiler} compiler the compiler instance
22
+ * @returns {void}
23
+ */
24
+ apply(compiler) {
25
+ compiler.hooks.thisCompilation.tap(
26
+ "ModuleChunkFormatPlugin",
27
+ compilation => {
28
+ compilation.hooks.additionalChunkRuntimeRequirements.tap(
29
+ "ModuleChunkFormatPlugin",
30
+ (chunk, set) => {
31
+ if (chunk.hasRuntime()) return;
32
+ if (compilation.chunkGraph.getNumberOfEntryModules(chunk) > 0) {
33
+ set.add(RuntimeGlobals.onChunksLoaded);
34
+ set.add(RuntimeGlobals.require);
35
+ }
36
+ }
37
+ );
38
+ const hooks = getCompilationHooks(compilation);
39
+ hooks.renderChunk.tap(
40
+ "ModuleChunkFormatPlugin",
41
+ (modules, renderContext) => {
42
+ const { chunk, chunkGraph } = renderContext;
43
+ const hotUpdateChunk =
44
+ chunk instanceof HotUpdateChunk ? chunk : null;
45
+ const source = new ConcatSource();
46
+ if (hotUpdateChunk) {
47
+ throw new Error(
48
+ "HMR is not implemented for module chunk format yet"
49
+ );
50
+ } else {
51
+ source.add(`export const id = ${JSON.stringify(chunk.id)};\n`);
52
+ source.add(`export const ids = ${JSON.stringify(chunk.ids)};\n`);
53
+ source.add(`export const modules = `);
54
+ source.add(modules);
55
+ source.add(`;\n`);
56
+ const runtimeModules =
57
+ chunkGraph.getChunkRuntimeModulesInOrder(chunk);
58
+ if (runtimeModules.length > 0) {
59
+ source.add("export const runtime =\n");
60
+ source.add(
61
+ Template.renderChunkRuntimeModules(
62
+ runtimeModules,
63
+ renderContext
64
+ )
65
+ );
66
+ }
67
+ const entries = Array.from(
68
+ chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
69
+ );
70
+ if (entries.length > 0) {
71
+ throw new Error(
72
+ "Entry modules in chunk is not implemented for module chunk format yet"
73
+ );
74
+ }
75
+ }
76
+ return source;
77
+ }
78
+ );
79
+ hooks.chunkHash.tap(
80
+ "ModuleChunkFormatPlugin",
81
+ (chunk, hash, { chunkGraph, runtimeTemplate }) => {
82
+ if (chunk.hasRuntime()) return;
83
+ hash.update("ModuleChunkFormatPlugin");
84
+ hash.update("1");
85
+ // TODO
86
+ // const entries = Array.from(
87
+ // chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
88
+ // );
89
+ // updateHashForEntryStartup(hash, chunkGraph, entries, chunk);
90
+ }
91
+ );
92
+ }
93
+ );
94
+ }
95
+ }
96
+
97
+ module.exports = ModuleChunkFormatPlugin;
@@ -0,0 +1,63 @@
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 RuntimeGlobals = require("../RuntimeGlobals");
9
+ const ModuleChunkLoadingRuntimeModule = require("./ModuleChunkLoadingRuntimeModule");
10
+
11
+ /** @typedef {import("../Compiler")} Compiler */
12
+
13
+ class ModuleChunkLoadingPlugin {
14
+ /**
15
+ * Apply the plugin
16
+ * @param {Compiler} compiler the compiler instance
17
+ * @returns {void}
18
+ */
19
+ apply(compiler) {
20
+ compiler.hooks.thisCompilation.tap(
21
+ "ModuleChunkLoadingPlugin",
22
+ compilation => {
23
+ const globalChunkLoading = compilation.outputOptions.chunkLoading;
24
+ const isEnabledForChunk = chunk => {
25
+ const options = chunk.getEntryOptions();
26
+ const chunkLoading =
27
+ (options && options.chunkLoading) || globalChunkLoading;
28
+ return chunkLoading === "import";
29
+ };
30
+ const onceForChunkSet = new WeakSet();
31
+ const handler = (chunk, set) => {
32
+ if (onceForChunkSet.has(chunk)) return;
33
+ onceForChunkSet.add(chunk);
34
+ if (!isEnabledForChunk(chunk)) return;
35
+ set.add(RuntimeGlobals.moduleFactoriesAddOnly);
36
+ set.add(RuntimeGlobals.hasOwnProperty);
37
+ compilation.addRuntimeModule(
38
+ chunk,
39
+ new ModuleChunkLoadingRuntimeModule(set)
40
+ );
41
+ };
42
+ compilation.hooks.runtimeRequirementInTree
43
+ .for(RuntimeGlobals.ensureChunkHandlers)
44
+ .tap("ModuleChunkLoadingPlugin", handler);
45
+ compilation.hooks.runtimeRequirementInTree
46
+ .for(RuntimeGlobals.baseURI)
47
+ .tap("ModuleChunkLoadingPlugin", handler);
48
+ compilation.hooks.runtimeRequirementInTree
49
+ .for(RuntimeGlobals.onChunksLoaded)
50
+ .tap("ModuleChunkLoadingPlugin", handler);
51
+
52
+ compilation.hooks.runtimeRequirementInTree
53
+ .for(RuntimeGlobals.ensureChunkHandlers)
54
+ .tap("ModuleChunkLoadingPlugin", (chunk, set) => {
55
+ if (!isEnabledForChunk(chunk)) return;
56
+ set.add(RuntimeGlobals.getChunkScriptFilename);
57
+ });
58
+ }
59
+ );
60
+ }
61
+ }
62
+
63
+ module.exports = ModuleChunkLoadingPlugin;
@@ -0,0 +1,208 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ */
4
+
5
+ "use strict";
6
+
7
+ const { SyncWaterfallHook } = require("tapable");
8
+ const Compilation = require("../Compilation");
9
+ const RuntimeGlobals = require("../RuntimeGlobals");
10
+ const RuntimeModule = require("../RuntimeModule");
11
+ const Template = require("../Template");
12
+ const {
13
+ getChunkFilenameTemplate,
14
+ chunkHasJs
15
+ } = require("../javascript/JavascriptModulesPlugin");
16
+ const { getInitialChunkIds } = require("../javascript/StartupHelpers");
17
+ const compileBooleanMatcher = require("../util/compileBooleanMatcher");
18
+ const { getUndoPath } = require("../util/identifier");
19
+
20
+ /** @typedef {import("../Chunk")} Chunk */
21
+
22
+ /**
23
+ * @typedef {Object} JsonpCompilationPluginHooks
24
+ * @property {SyncWaterfallHook<[string, Chunk]>} linkPreload
25
+ * @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch
26
+ */
27
+
28
+ /** @type {WeakMap<Compilation, JsonpCompilationPluginHooks>} */
29
+ const compilationHooksMap = new WeakMap();
30
+
31
+ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
32
+ /**
33
+ * @param {Compilation} compilation the compilation
34
+ * @returns {JsonpCompilationPluginHooks} hooks
35
+ */
36
+ static getCompilationHooks(compilation) {
37
+ if (!(compilation instanceof Compilation)) {
38
+ throw new TypeError(
39
+ "The 'compilation' argument must be an instance of Compilation"
40
+ );
41
+ }
42
+ let hooks = compilationHooksMap.get(compilation);
43
+ if (hooks === undefined) {
44
+ hooks = {
45
+ linkPreload: new SyncWaterfallHook(["source", "chunk"]),
46
+ linkPrefetch: new SyncWaterfallHook(["source", "chunk"])
47
+ };
48
+ compilationHooksMap.set(compilation, hooks);
49
+ }
50
+ return hooks;
51
+ }
52
+
53
+ constructor(runtimeRequirements) {
54
+ super("import chunk loading", RuntimeModule.STAGE_ATTACH);
55
+ this._runtimeRequirements = runtimeRequirements;
56
+ }
57
+
58
+ /**
59
+ * @returns {string} runtime code
60
+ */
61
+ generate() {
62
+ const { compilation, chunk } = this;
63
+ const {
64
+ runtimeTemplate,
65
+ chunkGraph,
66
+ outputOptions: { importFunctionName, importMetaName }
67
+ } = compilation;
68
+ const fn = RuntimeGlobals.ensureChunkHandlers;
69
+ const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI);
70
+ const withLoading = this._runtimeRequirements.has(
71
+ RuntimeGlobals.ensureChunkHandlers
72
+ );
73
+ const withOnChunkLoad = this._runtimeRequirements.has(
74
+ RuntimeGlobals.onChunksLoaded
75
+ );
76
+ const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs);
77
+ const hasJsMatcher = compileBooleanMatcher(conditionMap);
78
+ const initialChunkIds = getInitialChunkIds(chunk, chunkGraph);
79
+
80
+ const outputName = this.compilation.getPath(
81
+ getChunkFilenameTemplate(chunk, this.compilation.outputOptions),
82
+ {
83
+ chunk,
84
+ contentHashType: "javascript"
85
+ }
86
+ );
87
+ const rootOutputDir = getUndoPath(
88
+ outputName,
89
+ this.compilation.outputOptions.path,
90
+ true
91
+ );
92
+
93
+ return Template.asString([
94
+ withBaseURI
95
+ ? Template.asString([
96
+ `${RuntimeGlobals.baseURI} = new URL(${JSON.stringify(
97
+ rootOutputDir
98
+ )}, ${importMetaName}.url);`
99
+ ])
100
+ : "// no baseURI",
101
+ "",
102
+ "// object to store loaded and loading chunks",
103
+ "// undefined = chunk not loaded, null = chunk preloaded/prefetched",
104
+ "// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded",
105
+ "var installedChunks = {",
106
+ Template.indent(
107
+ Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 0`).join(
108
+ ",\n"
109
+ )
110
+ ),
111
+ "};",
112
+ "",
113
+ withLoading
114
+ ? Template.asString([
115
+ `${fn}.j = ${runtimeTemplate.basicFunction(
116
+ "chunkId, promises",
117
+ hasJsMatcher !== false
118
+ ? Template.indent([
119
+ "// import() chunk loading for javascript",
120
+ `var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`,
121
+ 'if(installedChunkData !== 0) { // 0 means "already installed".',
122
+ Template.indent([
123
+ "",
124
+ '// a Promise means "currently loading".',
125
+ "if(installedChunkData) {",
126
+ Template.indent([
127
+ "promises.push(installedChunkData[1]);"
128
+ ]),
129
+ "} else {",
130
+ Template.indent([
131
+ hasJsMatcher === true
132
+ ? "if(true) { // all chunks have JS"
133
+ : `if(${hasJsMatcher("chunkId")}) {`,
134
+ Template.indent([
135
+ "// setup Promise in chunk cache",
136
+ `var promise = ${importFunctionName}(${JSON.stringify(
137
+ rootOutputDir
138
+ )} + ${
139
+ RuntimeGlobals.getChunkScriptFilename
140
+ }(chunkId)).then(${runtimeTemplate.basicFunction(
141
+ "data",
142
+ [
143
+ runtimeTemplate.destructureObject(
144
+ ["ids", "modules", "runtime"],
145
+ "data"
146
+ ),
147
+ '// add "modules" to the modules object,',
148
+ '// then flag all "ids" as loaded and fire callback',
149
+ "var moduleId, chunkId, i = 0;",
150
+ "for(moduleId in modules) {",
151
+ Template.indent([
152
+ `if(${RuntimeGlobals.hasOwnProperty}(modules, moduleId)) {`,
153
+ Template.indent(
154
+ `${RuntimeGlobals.moduleFactories}[moduleId] = modules[moduleId];`
155
+ ),
156
+ "}"
157
+ ]),
158
+ "}",
159
+ "if(runtime) runtime(__webpack_require__);",
160
+ "for(;i < ids.length; i++) {",
161
+ Template.indent([
162
+ "chunkId = ids[i];",
163
+ `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`,
164
+ Template.indent(
165
+ "installedChunks[chunkId][0]();"
166
+ ),
167
+ "}",
168
+ "installedChunks[ids[i]] = 0;"
169
+ ]),
170
+ "}",
171
+ withOnChunkLoad
172
+ ? `${RuntimeGlobals.onChunksLoaded}();`
173
+ : ""
174
+ ]
175
+ )}, ${runtimeTemplate.basicFunction("e", [
176
+ "if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined;",
177
+ "throw e;"
178
+ ])});`,
179
+ `var promise = Promise.race([promise, new Promise(${runtimeTemplate.expressionFunction(
180
+ `installedChunkData = installedChunks[chunkId] = [resolve]`,
181
+ "resolve"
182
+ )})])`,
183
+ `promises.push(installedChunkData[1] = promise);`
184
+ ]),
185
+ "} else installedChunks[chunkId] = 0;"
186
+ ]),
187
+ "}"
188
+ ]),
189
+ "}"
190
+ ])
191
+ : Template.indent(["installedChunks[chunkId] = 0;"])
192
+ )};`
193
+ ])
194
+ : "// no chunk on demand loading",
195
+ "",
196
+ withOnChunkLoad
197
+ ? `${
198
+ RuntimeGlobals.onChunksLoaded
199
+ }.j = ${runtimeTemplate.returningFunction(
200
+ "installedChunks[chunkId] === 0",
201
+ "chunkId"
202
+ )};`
203
+ : "// no on chunks loaded"
204
+ ]);
205
+ }
206
+ }
207
+
208
+ module.exports = ModuleChunkLoadingRuntimeModule;
@@ -52,6 +52,16 @@ module.exports = (compiler, client, callback) => {
52
52
  }
53
53
  if (moduleActivated && compiler.watching) compiler.watching.invalidate();
54
54
  });
55
+ let isClosing = false;
56
+ /** @type {Set<import("net").Socket>} */
57
+ const sockets = new Set();
58
+ server.on("connection", socket => {
59
+ sockets.add(socket);
60
+ socket.on("close", () => {
61
+ sockets.delete(socket);
62
+ });
63
+ if (isClosing) socket.destroy();
64
+ });
55
65
  server.listen(err => {
56
66
  if (err) return callback(err);
57
67
  const addr = server.address();
@@ -67,7 +77,13 @@ module.exports = (compiler, client, callback) => {
67
77
  );
68
78
  callback(null, {
69
79
  dispose(callback) {
70
- server.close(callback);
80
+ isClosing = true;
81
+ server.close(err => {
82
+ callback(err);
83
+ });
84
+ for (const socket of sockets) {
85
+ socket.destroy(new Error("Server is disposing"));
86
+ }
71
87
  },
72
88
  module(originalModule) {
73
89
  const key = `${encodeURIComponent(
@@ -96,9 +96,11 @@ class EnableChunkLoadingPlugin {
96
96
  }).apply(compiler);
97
97
  break;
98
98
  }
99
- case "import":
100
- // TODO implement import chunk loading
101
- throw new Error("Chunk Loading via import() is not implemented yet");
99
+ case "import": {
100
+ const ModuleChunkLoadingPlugin = require("../esm/ModuleChunkLoadingPlugin");
101
+ new ModuleChunkLoadingPlugin().apply(compiler);
102
+ break;
103
+ }
102
104
  case "universal":
103
105
  // TODO implement universal chunk loading
104
106
  throw new Error("Universal Chunk Loading is not implemented yet");