webpack 5.96.0 → 5.97.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.
Files changed (64) hide show
  1. package/lib/CssModule.js +5 -0
  2. package/lib/DependencyTemplate.js +2 -2
  3. package/lib/EvalSourceMapDevToolPlugin.js +5 -0
  4. package/lib/FalseIIFEUmdWarning.js +19 -0
  5. package/lib/HotModuleReplacementPlugin.js +4 -0
  6. package/lib/Module.js +6 -0
  7. package/lib/ModuleSourceTypesConstants.js +12 -0
  8. package/lib/NormalModule.js +1 -0
  9. package/lib/RuntimeTemplate.js +7 -0
  10. package/lib/SourceMapDevToolPlugin.js +8 -0
  11. package/lib/WebpackOptionsApply.js +3 -1
  12. package/lib/asset/AssetModulesPlugin.js +7 -2
  13. package/lib/config/defaults.js +52 -36
  14. package/lib/config/normalization.js +0 -1
  15. package/lib/config/target.js +8 -8
  16. package/lib/css/CssGenerator.js +139 -35
  17. package/lib/css/CssLoadingRuntimeModule.js +108 -198
  18. package/lib/css/CssModulesPlugin.js +78 -124
  19. package/lib/css/CssParser.js +545 -121
  20. package/lib/css/walkCssTokens.js +41 -19
  21. package/lib/dependencies/CachedConstDependency.js +2 -1
  22. package/lib/dependencies/ContextDependencyTemplateAsId.js +3 -2
  23. package/lib/dependencies/{CssExportDependency.js → CssIcssExportDependency.js} +35 -35
  24. package/lib/dependencies/CssIcssImportDependency.js +118 -0
  25. package/lib/dependencies/CssIcssSymbolDependency.js +132 -0
  26. package/lib/dependencies/CssImportDependency.js +0 -8
  27. package/lib/dependencies/CssLocalIdentifierDependency.js +69 -73
  28. package/lib/dependencies/CssUrlDependency.js +1 -0
  29. package/lib/esm/ModuleChunkFormatPlugin.js +8 -4
  30. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +17 -10
  31. package/lib/index.js +13 -6
  32. package/lib/javascript/EnableChunkLoadingPlugin.js +2 -4
  33. package/lib/library/AssignLibraryPlugin.js +1 -1
  34. package/lib/library/EnableLibraryPlugin.js +17 -0
  35. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +81 -78
  36. package/lib/node/ReadFileCompileWasmPlugin.js +76 -57
  37. package/lib/optimize/MergeDuplicateChunksPlugin.js +22 -2
  38. package/lib/sharing/ConsumeSharedPlugin.js +35 -12
  39. package/lib/sharing/utils.js +35 -4
  40. package/lib/stats/DefaultStatsFactoryPlugin.js +0 -5
  41. package/lib/util/Queue.js +52 -24
  42. package/lib/util/generateDebugId.js +33 -0
  43. package/lib/util/internalSerializables.js +6 -2
  44. package/lib/wasm/EnableWasmLoadingPlugin.js +36 -25
  45. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +26 -2
  46. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +103 -0
  47. package/lib/wasm-sync/WebAssemblyParser.js +1 -1
  48. package/lib/web/FetchCompileAsyncWasmPlugin.js +43 -44
  49. package/lib/web/FetchCompileWasmPlugin.js +4 -4
  50. package/package.json +5 -5
  51. package/schemas/WebpackOptions.check.js +1 -1
  52. package/schemas/WebpackOptions.json +34 -12
  53. package/schemas/plugins/BannerPlugin.json +1 -1
  54. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  55. package/schemas/plugins/SourceMapDevToolPlugin.json +4 -0
  56. package/schemas/plugins/css/CssAutoParserOptions.check.js +1 -1
  57. package/schemas/plugins/css/CssGlobalParserOptions.check.js +1 -1
  58. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  59. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  60. package/schemas/plugins/optimize/MergeDuplicateChunksPlugin.check.d.ts +7 -0
  61. package/schemas/plugins/optimize/MergeDuplicateChunksPlugin.check.js +6 -0
  62. package/schemas/plugins/optimize/MergeDuplicateChunksPlugin.json +11 -0
  63. package/types.d.ts +85 -24
  64. package/lib/css/CssExportsGenerator.js +0 -207
@@ -16,10 +16,13 @@ const WasmChunkLoadingRuntimeModule = require("../wasm-sync/WasmChunkLoadingRunt
16
16
  /**
17
17
  * @typedef {object} ReadFileCompileWasmPluginOptions
18
18
  * @property {boolean} [mangleImports] mangle imports
19
+ * @property {boolean} [import] use import?
19
20
  */
20
21
 
21
22
  // TODO webpack 6 remove
22
23
 
24
+ const PLUGIN_NAME = "ReadFileCompileWasmPlugin";
25
+
23
26
  class ReadFileCompileWasmPlugin {
24
27
  /**
25
28
  * @param {ReadFileCompileWasmPluginOptions} [options] options object
@@ -34,36 +37,31 @@ class ReadFileCompileWasmPlugin {
34
37
  * @returns {void}
35
38
  */
36
39
  apply(compiler) {
37
- compiler.hooks.thisCompilation.tap(
38
- "ReadFileCompileWasmPlugin",
39
- compilation => {
40
- const globalWasmLoading = compilation.outputOptions.wasmLoading;
41
- /**
42
- * @param {Chunk} chunk chunk
43
- * @returns {boolean} true, when wasm loading is enabled for the chunk
44
- */
45
- const isEnabledForChunk = chunk => {
46
- const options = chunk.getEntryOptions();
47
- const wasmLoading =
48
- options && options.wasmLoading !== undefined
49
- ? options.wasmLoading
50
- : globalWasmLoading;
51
- return wasmLoading === "async-node";
52
- };
53
- /**
54
- * @param {string} path path to wasm file
55
- * @returns {string} generated code to load the wasm file
56
- */
57
- const generateLoadBinaryCode = path =>
58
- Template.asString([
59
- "new Promise(function (resolve, reject) {",
60
- Template.indent([
61
- "var { readFile } = require('fs');",
62
- "var { join } = require('path');",
63
- "",
64
- "try {",
40
+ compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => {
41
+ const globalWasmLoading = compilation.outputOptions.wasmLoading;
42
+ /**
43
+ * @param {Chunk} chunk chunk
44
+ * @returns {boolean} true, when wasm loading is enabled for the chunk
45
+ */
46
+ const isEnabledForChunk = chunk => {
47
+ const options = chunk.getEntryOptions();
48
+ const wasmLoading =
49
+ options && options.wasmLoading !== undefined
50
+ ? options.wasmLoading
51
+ : globalWasmLoading;
52
+ return wasmLoading === "async-node";
53
+ };
54
+
55
+ /**
56
+ * @param {string} path path to wasm file
57
+ * @returns {string} generated code to load the wasm file
58
+ */
59
+ const generateLoadBinaryCode = this.options.import
60
+ ? path =>
61
+ Template.asString([
62
+ "Promise.all([import('fs'), import('url')]).then(([{ readFile }, { URL }]) => new Promise((resolve, reject) => {",
65
63
  Template.indent([
66
- `readFile(join(__dirname, ${path}), function(err, buffer){`,
64
+ `readFile(new URL(${path}, ${compilation.outputOptions.importMetaName}.url), (err, buffer) => {`,
67
65
  Template.indent([
68
66
  "if (err) return reject(err);",
69
67
  "",
@@ -74,36 +72,57 @@ class ReadFileCompileWasmPlugin {
74
72
  ]),
75
73
  "});"
76
74
  ]),
77
- "} catch (err) { reject(err); }"
78
- ]),
79
- "})"
80
- ]);
75
+ "}))"
76
+ ])
77
+ : path =>
78
+ Template.asString([
79
+ "new Promise(function (resolve, reject) {",
80
+ Template.indent([
81
+ "var { readFile } = require('fs');",
82
+ "var { join } = require('path');",
83
+ "",
84
+ "try {",
85
+ Template.indent([
86
+ `readFile(join(__dirname, ${path}), function(err, buffer){`,
87
+ Template.indent([
88
+ "if (err) return reject(err);",
89
+ "",
90
+ "// Fake fetch response",
91
+ "resolve({",
92
+ Template.indent(["arrayBuffer() { return buffer; }"]),
93
+ "});"
94
+ ]),
95
+ "});"
96
+ ]),
97
+ "} catch (err) { reject(err); }"
98
+ ]),
99
+ "})"
100
+ ]);
81
101
 
82
- compilation.hooks.runtimeRequirementInTree
83
- .for(RuntimeGlobals.ensureChunkHandlers)
84
- .tap("ReadFileCompileWasmPlugin", (chunk, set, { chunkGraph }) => {
85
- if (!isEnabledForChunk(chunk)) return;
86
- if (
87
- !chunkGraph.hasModuleInGraph(
88
- chunk,
89
- m => m.type === WEBASSEMBLY_MODULE_TYPE_SYNC
90
- )
91
- ) {
92
- return;
93
- }
94
- set.add(RuntimeGlobals.moduleCache);
95
- compilation.addRuntimeModule(
102
+ compilation.hooks.runtimeRequirementInTree
103
+ .for(RuntimeGlobals.ensureChunkHandlers)
104
+ .tap(PLUGIN_NAME, (chunk, set, { chunkGraph }) => {
105
+ if (!isEnabledForChunk(chunk)) return;
106
+ if (
107
+ !chunkGraph.hasModuleInGraph(
96
108
  chunk,
97
- new WasmChunkLoadingRuntimeModule({
98
- generateLoadBinaryCode,
99
- supportsStreaming: false,
100
- mangleImports: this.options.mangleImports,
101
- runtimeRequirements: set
102
- })
103
- );
104
- });
105
- }
106
- );
109
+ m => m.type === WEBASSEMBLY_MODULE_TYPE_SYNC
110
+ )
111
+ ) {
112
+ return;
113
+ }
114
+ set.add(RuntimeGlobals.moduleCache);
115
+ compilation.addRuntimeModule(
116
+ chunk,
117
+ new WasmChunkLoadingRuntimeModule({
118
+ generateLoadBinaryCode,
119
+ supportsStreaming: false,
120
+ mangleImports: this.options.mangleImports,
121
+ runtimeRequirements: set
122
+ })
123
+ );
124
+ });
125
+ });
107
126
  }
108
127
  }
109
128
 
@@ -5,12 +5,32 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const { STAGE_ADVANCED } = require("../OptimizationStages");
8
+ const { STAGE_BASIC } = require("../OptimizationStages");
9
+ const createSchemaValidation = require("../util/create-schema-validation");
9
10
  const { runtimeEqual } = require("../util/runtime");
10
11
 
12
+ /** @typedef {import("../../declarations/plugins/optimize/MergeDuplicateChunksPlugin").MergeDuplicateChunksPluginOptions} MergeDuplicateChunksPluginOptions */
11
13
  /** @typedef {import("../Compiler")} Compiler */
12
14
 
15
+ const validate = createSchemaValidation(
16
+ require("../../schemas/plugins/optimize/MergeDuplicateChunksPlugin.check.js"),
17
+ () =>
18
+ require("../../schemas/plugins/optimize/MergeDuplicateChunksPlugin.json"),
19
+ {
20
+ name: "Merge Duplicate Chunks Plugin",
21
+ baseDataPath: "options"
22
+ }
23
+ );
24
+
13
25
  class MergeDuplicateChunksPlugin {
26
+ /**
27
+ * @param {MergeDuplicateChunksPluginOptions} options options object
28
+ */
29
+ constructor(options = { stage: STAGE_BASIC }) {
30
+ validate(options);
31
+ this.options = options;
32
+ }
33
+
14
34
  /**
15
35
  * @param {Compiler} compiler the compiler
16
36
  * @returns {void}
@@ -22,7 +42,7 @@ class MergeDuplicateChunksPlugin {
22
42
  compilation.hooks.optimizeChunks.tap(
23
43
  {
24
44
  name: "MergeDuplicateChunksPlugin",
25
- stage: STAGE_ADVANCED
45
+ stage: this.options.stage
26
46
  },
27
47
  chunks => {
28
48
  const { chunkGraph, moduleGraph } = compilation;
@@ -236,19 +236,31 @@ class ConsumeSharedPlugin {
236
236
  compilation.inputFileSystem,
237
237
  context,
238
238
  ["package.json"],
239
- (err, result) => {
239
+ (err, result, checkedDescriptionFilePaths) => {
240
240
  if (err) {
241
241
  requiredVersionWarning(
242
242
  `Unable to read description file: ${err}`
243
243
  );
244
244
  return resolve();
245
245
  }
246
- const { data, path: descriptionPath } =
247
- /** @type {DescriptionFile} */ (result);
246
+ const { data } =
247
+ /** @type {DescriptionFile} */
248
+ (result || {});
248
249
  if (!data) {
249
- requiredVersionWarning(
250
- `Unable to find description file in ${context}.`
251
- );
250
+ if (checkedDescriptionFilePaths) {
251
+ requiredVersionWarning(
252
+ [
253
+ `Unable to find required version for "${packageName}" in description file/s`,
254
+ checkedDescriptionFilePaths.join("\n"),
255
+ "It need to be in dependencies, devDependencies or peerDependencies."
256
+ ].join("\n")
257
+ );
258
+ } else {
259
+ requiredVersionWarning(
260
+ `Unable to find description file in ${context}.`
261
+ );
262
+ }
263
+
252
264
  return resolve();
253
265
  }
254
266
  if (data.name === packageName) {
@@ -257,13 +269,24 @@ class ConsumeSharedPlugin {
257
269
  }
258
270
  const requiredVersion =
259
271
  getRequiredVersionFromDescriptionFile(data, packageName);
260
- if (typeof requiredVersion !== "string") {
261
- requiredVersionWarning(
262
- `Unable to find required version for "${packageName}" in description file (${descriptionPath}). It need to be in dependencies, devDependencies or peerDependencies.`
263
- );
264
- return resolve();
272
+
273
+ if (requiredVersion) {
274
+ return resolve(parseRange(requiredVersion));
265
275
  }
266
- resolve(parseRange(requiredVersion));
276
+
277
+ resolve();
278
+ },
279
+ result => {
280
+ if (!result) return false;
281
+ const maybeRequiredVersion =
282
+ getRequiredVersionFromDescriptionFile(
283
+ result.data,
284
+ packageName
285
+ );
286
+ return (
287
+ result.data.name === packageName ||
288
+ typeof maybeRequiredVersion === "string"
289
+ );
267
290
  }
268
291
  );
269
292
  }
@@ -326,19 +326,42 @@ module.exports.normalizeVersion = normalizeVersion;
326
326
  * @param {InputFileSystem} fs file system
327
327
  * @param {string} directory directory to start looking into
328
328
  * @param {string[]} descriptionFiles possible description filenames
329
- * @param {function((Error | null)=, DescriptionFile=): void} callback callback
329
+ * @param {function((Error | null)=, DescriptionFile=, string[]=): void} callback callback
330
+ * @param {function(DescriptionFile=): boolean} satisfiesDescriptionFileData file data compliance check
331
+ * @param {Set<string>} checkedFilePaths set of file paths that have been checked
330
332
  */
331
- const getDescriptionFile = (fs, directory, descriptionFiles, callback) => {
333
+ const getDescriptionFile = (
334
+ fs,
335
+ directory,
336
+ descriptionFiles,
337
+ callback,
338
+ satisfiesDescriptionFileData,
339
+ checkedFilePaths = new Set()
340
+ ) => {
332
341
  let i = 0;
342
+
343
+ const satisfiesDescriptionFileDataInternal = {
344
+ check: satisfiesDescriptionFileData,
345
+ checkedFilePaths
346
+ };
347
+
333
348
  const tryLoadCurrent = () => {
334
349
  if (i >= descriptionFiles.length) {
335
350
  const parentDirectory = dirname(fs, directory);
336
- if (!parentDirectory || parentDirectory === directory) return callback();
351
+ if (!parentDirectory || parentDirectory === directory) {
352
+ return callback(
353
+ null,
354
+ undefined,
355
+ Array.from(satisfiesDescriptionFileDataInternal.checkedFilePaths)
356
+ );
357
+ }
337
358
  return getDescriptionFile(
338
359
  fs,
339
360
  parentDirectory,
340
361
  descriptionFiles,
341
- callback
362
+ callback,
363
+ satisfiesDescriptionFileDataInternal.check,
364
+ satisfiesDescriptionFileDataInternal.checkedFilePaths
342
365
  );
343
366
  }
344
367
  const filePath = join(fs, directory, descriptionFiles[i]);
@@ -355,6 +378,14 @@ const getDescriptionFile = (fs, directory, descriptionFiles, callback) => {
355
378
  new Error(`Description file ${filePath} is not an object`)
356
379
  );
357
380
  }
381
+ if (
382
+ typeof satisfiesDescriptionFileDataInternal.check === "function" &&
383
+ !satisfiesDescriptionFileDataInternal.check({ data, path: filePath })
384
+ ) {
385
+ i++;
386
+ satisfiesDescriptionFileDataInternal.checkedFilePaths.add(filePath);
387
+ return tryLoadCurrent();
388
+ }
358
389
  callback(null, { data, path: filePath });
359
390
  });
360
391
  };
@@ -1190,11 +1190,6 @@ const SIMPLE_EXTRACTORS = {
1190
1190
  const warnings = module.getWarnings();
1191
1191
  const warningsCount =
1192
1192
  warnings !== undefined ? countIterable(warnings) : 0;
1193
- /** @type {{[x: string]: number}} */
1194
- const sizes = {};
1195
- for (const sourceType of module.getSourceTypes()) {
1196
- sizes[sourceType] = module.size(sourceType);
1197
- }
1198
1193
  /** @type {KnownStatsModule} */
1199
1194
  const statsModule = {
1200
1195
  identifier: module.identifier(),
package/lib/util/Queue.js CHANGED
@@ -8,29 +8,25 @@
8
8
  /**
9
9
  * @template T
10
10
  */
11
- class Queue {
11
+ class Node {
12
12
  /**
13
- * @param {Iterable<T>=} items The initial elements.
13
+ * @param {T} value the value
14
14
  */
15
- constructor(items) {
16
- /**
17
- * @private
18
- * @type {Set<T>}
19
- */
20
- this._set = new Set(items);
21
- /**
22
- * @private
23
- * @type {Iterator<T>}
24
- */
25
- this._iterator = this._set[Symbol.iterator]();
15
+ constructor(value) {
16
+ this.value = value;
17
+ /** @type {Node<T> | undefined} */
18
+ this.next = undefined;
26
19
  }
20
+ }
27
21
 
28
- /**
29
- * Returns the number of elements in this queue.
30
- * @returns {number} The number of elements in this queue.
31
- */
32
- get length() {
33
- return this._set.size;
22
+ /**
23
+ * @template T
24
+ */
25
+ class Queue {
26
+ constructor() {
27
+ this._head = undefined;
28
+ this._tail = undefined;
29
+ this._size = 0;
34
30
  }
35
31
 
36
32
  /**
@@ -39,7 +35,18 @@ class Queue {
39
35
  * @returns {void}
40
36
  */
41
37
  enqueue(item) {
42
- this._set.add(item);
38
+ const node = new Node(item);
39
+
40
+ if (this._head) {
41
+ /** @type {Node<T>} */
42
+ (this._tail).next = node;
43
+ this._tail = node;
44
+ } else {
45
+ this._head = node;
46
+ this._tail = node;
47
+ }
48
+
49
+ this._size++;
43
50
  }
44
51
 
45
52
  /**
@@ -47,10 +54,31 @@ class Queue {
47
54
  * @returns {T | undefined} The head of the queue of `undefined` if this queue is empty.
48
55
  */
49
56
  dequeue() {
50
- const result = this._iterator.next();
51
- if (result.done) return;
52
- this._set.delete(result.value);
53
- return result.value;
57
+ const current = this._head;
58
+ if (!current) {
59
+ return;
60
+ }
61
+
62
+ this._head = this._head.next;
63
+ this._size--;
64
+ return current.value;
65
+ }
66
+
67
+ /**
68
+ * Returns the number of elements in this queue.
69
+ * @returns {number} The number of elements in this queue.
70
+ */
71
+ get length() {
72
+ return this._size;
73
+ }
74
+
75
+ *[Symbol.iterator]() {
76
+ let current = this._head;
77
+
78
+ while (current) {
79
+ yield current.value;
80
+ current = current.next;
81
+ }
54
82
  }
55
83
  }
56
84
 
@@ -0,0 +1,33 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Alexander Akait @alexander-akait
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const createHash = require("./createHash");
9
+
10
+ /**
11
+ * @param {string | Buffer} content content
12
+ * @param {string} file file
13
+ * @returns {string} generated debug id
14
+ */
15
+ module.exports = (content, file) => {
16
+ // We need a uuid which is 128 bits so we need 2x 64 bit hashes.
17
+ // The first 64 bits is a hash of the source.
18
+ const sourceHash = createHash("xxhash64").update(content).digest("hex");
19
+ // The next 64 bits is a hash of the filename and sourceHash
20
+ const hash128 = `${sourceHash}${createHash("xxhash64")
21
+ .update(file)
22
+ .update(sourceHash)
23
+ .digest("hex")}`;
24
+
25
+ return [
26
+ hash128.slice(0, 8),
27
+ hash128.slice(8, 12),
28
+ `4${hash128.slice(12, 15)}`,
29
+ ((Number.parseInt(hash128.slice(15, 16), 16) & 3) | 8).toString(16) +
30
+ hash128.slice(17, 20),
31
+ hash128.slice(20, 32)
32
+ ].join("-");
33
+ };
@@ -77,10 +77,14 @@ module.exports = {
77
77
  require("../dependencies/CssLocalIdentifierDependency"),
78
78
  "dependencies/CssSelfLocalIdentifierDependency": () =>
79
79
  require("../dependencies/CssSelfLocalIdentifierDependency"),
80
- "dependencies/CssExportDependency": () =>
81
- require("../dependencies/CssExportDependency"),
80
+ "dependencies/CssIcssImportDependency": () =>
81
+ require("../dependencies/CssIcssImportDependency"),
82
+ "dependencies/CssIcssExportDependency": () =>
83
+ require("../dependencies/CssIcssExportDependency"),
82
84
  "dependencies/CssUrlDependency": () =>
83
85
  require("../dependencies/CssUrlDependency"),
86
+ "dependencies/CssIcssSymbolDependency": () =>
87
+ require("../dependencies/CssIcssSymbolDependency"),
84
88
  "dependencies/DelegatedSourceDependency": () =>
85
89
  require("../dependencies/DelegatedSourceDependency"),
86
90
  "dependencies/DllEntryDependency": () =>
@@ -77,38 +77,49 @@ class EnableWasmLoadingPlugin {
77
77
  if (typeof type === "string") {
78
78
  switch (type) {
79
79
  case "fetch": {
80
- // TODO webpack 6 remove FetchCompileWasmPlugin
81
- const FetchCompileWasmPlugin = require("../web/FetchCompileWasmPlugin");
82
- const FetchCompileAsyncWasmPlugin = require("../web/FetchCompileAsyncWasmPlugin");
83
- new FetchCompileWasmPlugin({
84
- mangleImports: compiler.options.optimization.mangleWasmImports
85
- }).apply(compiler);
86
- new FetchCompileAsyncWasmPlugin().apply(compiler);
80
+ if (compiler.options.experiments.syncWebAssembly) {
81
+ // TODO webpack 6 remove FetchCompileWasmPlugin
82
+ const FetchCompileWasmPlugin = require("../web/FetchCompileWasmPlugin");
83
+ new FetchCompileWasmPlugin({
84
+ mangleImports: compiler.options.optimization.mangleWasmImports
85
+ }).apply(compiler);
86
+ }
87
+
88
+ if (compiler.options.experiments.asyncWebAssembly) {
89
+ const FetchCompileAsyncWasmPlugin = require("../web/FetchCompileAsyncWasmPlugin");
90
+ new FetchCompileAsyncWasmPlugin().apply(compiler);
91
+ }
92
+
87
93
  break;
88
94
  }
89
95
  case "async-node": {
90
- // TODO webpack 6 remove ReadFileCompileWasmPlugin
91
- const ReadFileCompileWasmPlugin = require("../node/ReadFileCompileWasmPlugin");
92
- // @ts-expect-error typescript bug for duplicate require
93
- const ReadFileCompileAsyncWasmPlugin = require("../node/ReadFileCompileAsyncWasmPlugin");
94
- new ReadFileCompileWasmPlugin({
95
- mangleImports: compiler.options.optimization.mangleWasmImports
96
- }).apply(compiler);
97
- new ReadFileCompileAsyncWasmPlugin({ type }).apply(compiler);
96
+ if (compiler.options.experiments.syncWebAssembly) {
97
+ // TODO webpack 6 remove ReadFileCompileWasmPlugin
98
+ const ReadFileCompileWasmPlugin = require("../node/ReadFileCompileWasmPlugin");
99
+ new ReadFileCompileWasmPlugin({
100
+ mangleImports: compiler.options.optimization.mangleWasmImports,
101
+ import:
102
+ compiler.options.output.environment.module &&
103
+ compiler.options.output.environment.dynamicImport
104
+ }).apply(compiler);
105
+ }
106
+
107
+ if (compiler.options.experiments.asyncWebAssembly) {
108
+ const ReadFileCompileAsyncWasmPlugin = require("../node/ReadFileCompileAsyncWasmPlugin");
109
+ new ReadFileCompileAsyncWasmPlugin({
110
+ import:
111
+ compiler.options.output.environment.module &&
112
+ compiler.options.output.environment.dynamicImport
113
+ }).apply(compiler);
114
+ }
115
+
98
116
  break;
99
117
  }
100
- case "async-node-module": {
101
- // @ts-expect-error typescript bug for duplicate require
102
- const ReadFileCompileAsyncWasmPlugin = require("../node/ReadFileCompileAsyncWasmPlugin");
103
- new ReadFileCompileAsyncWasmPlugin({ type, import: true }).apply(
104
- compiler
105
- );
118
+ case "universal": {
119
+ const UniversalCompileAsyncWasmPlugin = require("../wasm-async/UniversalCompileAsyncWasmPlugin");
120
+ new UniversalCompileAsyncWasmPlugin().apply(compiler);
106
121
  break;
107
122
  }
108
- case "universal":
109
- throw new Error(
110
- "Universal WebAssembly Loading is not implemented yet"
111
- );
112
123
  default:
113
124
  throw new Error(`Unsupported wasm loading type ${type}.
114
125
  Plugins which provide custom wasm loading types must call EnableWasmLoadingPlugin.setEnabled(compiler, type) to disable this error.`);
@@ -14,7 +14,9 @@ const Template = require("../Template");
14
14
 
15
15
  /**
16
16
  * @typedef {object} AsyncWasmLoadingRuntimeModuleOptions
17
+ * @property {(function(string): string)=} generateBeforeLoadBinaryCode
17
18
  * @property {function(string): string} generateLoadBinaryCode
19
+ * @property {(function(): string)=} generateBeforeInstantiateStreaming
18
20
  * @property {boolean} supportsStreaming
19
21
  */
20
22
 
@@ -22,9 +24,17 @@ class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
22
24
  /**
23
25
  * @param {AsyncWasmLoadingRuntimeModuleOptions} options options
24
26
  */
25
- constructor({ generateLoadBinaryCode, supportsStreaming }) {
27
+ constructor({
28
+ generateLoadBinaryCode,
29
+ generateBeforeLoadBinaryCode,
30
+ generateBeforeInstantiateStreaming,
31
+ supportsStreaming
32
+ }) {
26
33
  super("wasm loading", RuntimeModule.STAGE_NORMAL);
27
34
  this.generateLoadBinaryCode = generateLoadBinaryCode;
35
+ this.generateBeforeLoadBinaryCode = generateBeforeLoadBinaryCode;
36
+ this.generateBeforeInstantiateStreaming =
37
+ generateBeforeInstantiateStreaming;
28
38
  this.supportsStreaming = supportsStreaming;
29
39
  }
30
40
 
@@ -68,6 +78,9 @@ class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
68
78
  const getStreaming = () => {
69
79
  const concat = (/** @type {string[]} */ ...text) => text.join("");
70
80
  return [
81
+ this.generateBeforeLoadBinaryCode
82
+ ? this.generateBeforeLoadBinaryCode(wasmModuleSrcPath)
83
+ : "",
71
84
  `var req = ${loader};`,
72
85
  `var fallback = ${runtimeTemplate.returningFunction(
73
86
  Template.asString(["req", Template.indent(fallback)])
@@ -76,6 +89,11 @@ class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
76
89
  "return req.then(",
77
90
  runtimeTemplate.basicFunction("res", [
78
91
  'if (typeof WebAssembly.instantiateStreaming === "function") {',
92
+ Template.indent(
93
+ this.generateBeforeInstantiateStreaming
94
+ ? this.generateBeforeInstantiateStreaming()
95
+ : ""
96
+ ),
79
97
  Template.indent([
80
98
  "return WebAssembly.instantiateStreaming(res, importsObj)",
81
99
  Template.indent([
@@ -110,7 +128,13 @@ class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
110
128
  "exports, wasmModuleId, wasmModuleHash, importsObj",
111
129
  this.supportsStreaming
112
130
  ? getStreaming()
113
- : [`return ${loader}`, `${Template.indent(fallback)};`]
131
+ : [
132
+ this.generateBeforeLoadBinaryCode
133
+ ? this.generateBeforeLoadBinaryCode(wasmModuleSrcPath)
134
+ : "",
135
+ `return ${loader}`,
136
+ `${Template.indent(fallback)};`
137
+ ]
114
138
  )};`;
115
139
  }
116
140
  }