webpack 5.39.0 → 5.41.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 (51) hide show
  1. package/README.md +13 -13
  2. package/bin/webpack.js +0 -0
  3. package/lib/Compilation.js +43 -28
  4. package/lib/ConditionalInitFragment.js +15 -12
  5. package/lib/DependencyTemplate.js +3 -2
  6. package/lib/ExternalModule.js +210 -35
  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/RuntimeTemplate.js +8 -0
  12. package/lib/Template.js +3 -2
  13. package/lib/TemplatedPathPlugin.js +24 -26
  14. package/lib/Watching.js +2 -1
  15. package/lib/WebpackOptionsApply.js +10 -7
  16. package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -1
  17. package/lib/cache/IdleFileCachePlugin.js +60 -13
  18. package/lib/cache/PackFileCacheStrategy.js +4 -1
  19. package/lib/cli.js +1 -1
  20. package/lib/config/defaults.js +53 -12
  21. package/lib/config/normalization.js +1 -0
  22. package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
  23. package/lib/dependencies/WorkerPlugin.js +25 -10
  24. package/lib/electron/ElectronTargetPlugin.js +3 -3
  25. package/lib/esm/ModuleChunkFormatPlugin.js +97 -0
  26. package/lib/esm/ModuleChunkLoadingPlugin.js +63 -0
  27. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +208 -0
  28. package/lib/hmr/lazyCompilationBackend.js +17 -1
  29. package/lib/javascript/EnableChunkLoadingPlugin.js +5 -3
  30. package/lib/javascript/JavascriptModulesPlugin.js +80 -17
  31. package/lib/javascript/JavascriptParser.js +12 -4
  32. package/lib/node/NodeTargetPlugin.js +2 -1
  33. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +44 -22
  34. package/lib/optimize/InnerGraphPlugin.js +33 -2
  35. package/lib/optimize/ModuleConcatenationPlugin.js +1 -1
  36. package/lib/runtime/AsyncModuleRuntimeModule.js +8 -4
  37. package/lib/serialization/BinaryMiddleware.js +24 -14
  38. package/lib/serialization/FileMiddleware.js +30 -6
  39. package/lib/serialization/PlainObjectSerializer.js +17 -8
  40. package/lib/serialization/Serializer.js +2 -2
  41. package/lib/serialization/SerializerMiddleware.js +26 -4
  42. package/lib/util/ArrayQueue.js +8 -0
  43. package/lib/util/AsyncQueue.js +9 -0
  44. package/lib/util/LazySet.js +26 -17
  45. package/lib/wasm/EnableWasmLoadingPlugin.js +10 -1
  46. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +2 -2
  47. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +1 -1
  48. package/package.json +17 -17
  49. package/schemas/WebpackOptions.check.js +1 -1
  50. package/schemas/WebpackOptions.json +16 -7
  51. package/types.d.ts +107 -158
@@ -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");
@@ -17,6 +17,7 @@ const {
17
17
  const Compilation = require("../Compilation");
18
18
  const { tryRunOrWebpackError } = require("../HookWebpackError");
19
19
  const HotUpdateChunk = require("../HotUpdateChunk");
20
+ const InitFragment = require("../InitFragment");
20
21
  const RuntimeGlobals = require("../RuntimeGlobals");
21
22
  const Template = require("../Template");
22
23
  const { last, someInIterable } = require("../util/IterableHelpers");
@@ -84,6 +85,17 @@ const printGeneratedCodeForStack = (module, code) => {
84
85
  * @property {string} hash hash to be used for render call
85
86
  */
86
87
 
88
+ /**
89
+ * @typedef {Object} ChunkRenderContext
90
+ * @property {Chunk} chunk the chunk
91
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
92
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
93
+ * @property {ModuleGraph} moduleGraph the module graph
94
+ * @property {ChunkGraph} chunkGraph the chunk graph
95
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
96
+ * @property {InitFragment<ChunkRenderContext>[]} chunkInitFragments init fragments for the chunk
97
+ */
98
+
87
99
  /**
88
100
  * @typedef {Object} RenderBootstrapContext
89
101
  * @property {Chunk} chunk the chunk
@@ -97,11 +109,12 @@ const printGeneratedCodeForStack = (module, code) => {
97
109
 
98
110
  /**
99
111
  * @typedef {Object} CompilationHooks
100
- * @property {SyncWaterfallHook<[Source, Module, RenderContext]>} renderModuleContent
101
- * @property {SyncWaterfallHook<[Source, Module, RenderContext]>} renderModuleContainer
102
- * @property {SyncWaterfallHook<[Source, Module, RenderContext]>} renderModulePackage
112
+ * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModuleContent
113
+ * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModuleContainer
114
+ * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModulePackage
103
115
  * @property {SyncWaterfallHook<[Source, RenderContext]>} renderChunk
104
116
  * @property {SyncWaterfallHook<[Source, RenderContext]>} renderMain
117
+ * @property {SyncWaterfallHook<[Source, RenderContext]>} renderContent
105
118
  * @property {SyncWaterfallHook<[Source, RenderContext]>} render
106
119
  * @property {SyncWaterfallHook<[Source, Module, StartupRenderContext]>} renderStartup
107
120
  * @property {SyncWaterfallHook<[string, RenderBootstrapContext]>} renderRequire
@@ -145,6 +158,7 @@ class JavascriptModulesPlugin {
145
158
  "renderContext"
146
159
  ]),
147
160
  render: new SyncWaterfallHook(["source", "renderContext"]),
161
+ renderContent: new SyncWaterfallHook(["source", "renderContext"]),
148
162
  renderStartup: new SyncWaterfallHook([
149
163
  "source",
150
164
  "module",
@@ -462,7 +476,7 @@ class JavascriptModulesPlugin {
462
476
 
463
477
  /**
464
478
  * @param {Module} module the rendered module
465
- * @param {RenderContext} renderContext options object
479
+ * @param {ChunkRenderContext} renderContext options object
466
480
  * @param {CompilationHooks} hooks hooks
467
481
  * @param {boolean | "strict"} factory true: renders as factory method, "strict": renders as factory method already in strict scope, false: pure module content
468
482
  * @returns {Source} the newly generated source from rendering
@@ -471,12 +485,16 @@ class JavascriptModulesPlugin {
471
485
  const { chunk, chunkGraph, runtimeTemplate, codeGenerationResults } =
472
486
  renderContext;
473
487
  try {
474
- const moduleSource = codeGenerationResults.getSource(
475
- module,
476
- chunk.runtime,
477
- "javascript"
478
- );
488
+ const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
489
+ const moduleSource = codeGenResult.sources.get("javascript");
479
490
  if (!moduleSource) return null;
491
+ if (codeGenResult.data !== undefined) {
492
+ const chunkInitFragments = codeGenResult.data.get("chunkInitFragments");
493
+ if (chunkInitFragments) {
494
+ for (const i of chunkInitFragments)
495
+ renderContext.chunkInitFragments.push(i);
496
+ }
497
+ }
480
498
  const moduleSourcePostContent = tryRunOrWebpackError(
481
499
  () =>
482
500
  hooks.renderModuleContent.call(moduleSource, module, renderContext),
@@ -580,20 +598,44 @@ class JavascriptModulesPlugin {
580
598
  "javascript",
581
599
  compareModulesByIdentifier
582
600
  );
601
+ /** @type {ChunkRenderContext} */
602
+ const chunkRenderContext = {
603
+ ...renderContext,
604
+ chunkInitFragments: []
605
+ };
583
606
  const moduleSources =
584
607
  Template.renderChunkModules(
585
- renderContext,
608
+ chunkRenderContext,
586
609
  modules ? Array.from(modules) : [],
587
- module => this.renderModule(module, renderContext, hooks, true)
610
+ module => this.renderModule(module, chunkRenderContext, hooks, true)
588
611
  ) || new RawSource("{}");
589
612
  let source = tryRunOrWebpackError(
590
- () => hooks.renderChunk.call(moduleSources, renderContext),
613
+ () => hooks.renderChunk.call(moduleSources, chunkRenderContext),
591
614
  "JavascriptModulesPlugin.getCompilationHooks().renderChunk"
592
615
  );
593
616
  source = tryRunOrWebpackError(
594
- () => hooks.render.call(source, renderContext),
617
+ () => hooks.renderContent.call(source, chunkRenderContext),
618
+ "JavascriptModulesPlugin.getCompilationHooks().renderContent"
619
+ );
620
+ if (!source) {
621
+ throw new Error(
622
+ "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something"
623
+ );
624
+ }
625
+ source = InitFragment.addToSource(
626
+ source,
627
+ chunkRenderContext.chunkInitFragments,
628
+ chunkRenderContext
629
+ );
630
+ source = tryRunOrWebpackError(
631
+ () => hooks.render.call(source, chunkRenderContext),
595
632
  "JavascriptModulesPlugin.getCompilationHooks().render"
596
633
  );
634
+ if (!source) {
635
+ throw new Error(
636
+ "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().render plugins should return something"
637
+ );
638
+ }
597
639
  chunk.rendered = true;
598
640
  return new ConcatSource(source, ";");
599
641
  }
@@ -607,6 +649,12 @@ class JavascriptModulesPlugin {
607
649
  renderMain(renderContext, hooks, compilation) {
608
650
  const { chunk, chunkGraph, runtimeTemplate } = renderContext;
609
651
 
652
+ /** @type {ChunkRenderContext} */
653
+ const chunkRenderContext = {
654
+ ...renderContext,
655
+ chunkInitFragments: []
656
+ };
657
+
610
658
  const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
611
659
  const iife = runtimeTemplate.isIIFE();
612
660
 
@@ -654,14 +702,14 @@ class JavascriptModulesPlugin {
654
702
  }
655
703
 
656
704
  const chunkModules = Template.renderChunkModules(
657
- renderContext,
705
+ chunkRenderContext,
658
706
  inlinedModules
659
707
  ? allModules.filter(m => !inlinedModules.has(m))
660
708
  : allModules,
661
709
  module =>
662
710
  this.renderModule(
663
711
  module,
664
- renderContext,
712
+ chunkRenderContext,
665
713
  hooks,
666
714
  allStrict ? "strict" : true
667
715
  ),
@@ -670,7 +718,8 @@ class JavascriptModulesPlugin {
670
718
  if (
671
719
  chunkModules ||
672
720
  runtimeRequirements.has(RuntimeGlobals.moduleFactories) ||
673
- runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly)
721
+ runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly) ||
722
+ runtimeRequirements.has(RuntimeGlobals.require)
674
723
  ) {
675
724
  source.add(prefix + "var __webpack_modules__ = (");
676
725
  source.add(chunkModules || "{}");
@@ -731,7 +780,7 @@ class JavascriptModulesPlugin {
731
780
  for (const m of inlinedModules) {
732
781
  const renderedModule = this.renderModule(
733
782
  m,
734
- renderContext,
783
+ chunkRenderContext,
735
784
  hooks,
736
785
  false
737
786
  );
@@ -852,6 +901,20 @@ class JavascriptModulesPlugin {
852
901
  "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderMain plugins should return something"
853
902
  );
854
903
  }
904
+ finalSource = tryRunOrWebpackError(
905
+ () => hooks.renderContent.call(finalSource, renderContext),
906
+ "JavascriptModulesPlugin.getCompilationHooks().renderContent"
907
+ );
908
+ if (!finalSource) {
909
+ throw new Error(
910
+ "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something"
911
+ );
912
+ }
913
+ finalSource = InitFragment.addToSource(
914
+ finalSource,
915
+ chunkRenderContext.chunkInitFragments,
916
+ chunkRenderContext
917
+ );
855
918
  finalSource = tryRunOrWebpackError(
856
919
  () => hooks.render.call(finalSource, renderContext),
857
920
  "JavascriptModulesPlugin.getCompilationHooks().render"
@@ -25,6 +25,8 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
25
25
  /** @typedef {import("estree").Comment} CommentNode */
26
26
  /** @typedef {import("estree").ConditionalExpression} ConditionalExpressionNode */
27
27
  /** @typedef {import("estree").Declaration} DeclarationNode */
28
+ /** @typedef {import("estree").PrivateIdentifier} PrivateIdentifierNode */
29
+ /** @typedef {import("estree").PropertyDefinition} PropertyDefinitionNode */
28
30
  /** @typedef {import("estree").Expression} ExpressionNode */
29
31
  /** @typedef {import("estree").Identifier} IdentifierNode */
30
32
  /** @typedef {import("estree").IfStatement} IfStatementNode */
@@ -128,7 +130,6 @@ const defaultParserOptions = {
128
130
  locations: true,
129
131
  ecmaVersion: "latest",
130
132
  sourceType: "module",
131
- allowAwaitOutsideFunction: true,
132
133
  onComment: null
133
134
  };
134
135
 
@@ -175,11 +176,18 @@ class JavascriptParser extends Parser {
175
176
  /** @type {SyncBailHook<[IfStatementNode], boolean | void>} */
176
177
  statementIf: new SyncBailHook(["statement"]),
177
178
  /** @type {SyncBailHook<[ExpressionNode, ClassExpressionNode | ClassDeclarationNode], boolean | void>} */
178
- classExtendsExpression: new SyncBailHook(["expression", "statement"]),
179
+ classExtendsExpression: new SyncBailHook([
180
+ "expression",
181
+ "classDefinition"
182
+ ]),
179
183
  /** @type {SyncBailHook<[MethodDefinitionNode | PropertyDefinitionNode, ClassExpressionNode | ClassDeclarationNode], boolean | void>} */
180
- classBodyElement: new SyncBailHook(["element", "statement"]),
184
+ classBodyElement: new SyncBailHook(["element", "classDefinition"]),
181
185
  /** @type {SyncBailHook<[ExpressionNode, MethodDefinitionNode | PropertyDefinitionNode, ClassExpressionNode | ClassDeclarationNode], boolean | void>} */
182
- classBodyValue: new SyncBailHook(["expression", "element", "statement"]),
186
+ classBodyValue: new SyncBailHook([
187
+ "expression",
188
+ "element",
189
+ "classDefinition"
190
+ ]),
183
191
  /** @type {HookMap<SyncBailHook<[LabeledStatementNode], boolean | void>>} */
184
192
  label: new HookMap(() => new SyncBailHook(["statement"])),
185
193
  /** @type {SyncBailHook<[StatementNode, ImportSource], boolean | void>} */
@@ -55,6 +55,7 @@ const builtins = [
55
55
  "wasi",
56
56
  "worker_threads",
57
57
  "zlib",
58
+ /^node:/,
58
59
 
59
60
  // cspell:word pnpapi
60
61
  // Yarn PnP adds pnpapi as "builtin"
@@ -68,7 +69,7 @@ class NodeTargetPlugin {
68
69
  * @returns {void}
69
70
  */
70
71
  apply(compiler) {
71
- new ExternalsPlugin("commonjs", builtins).apply(compiler);
72
+ new ExternalsPlugin("node-commonjs", builtins).apply(compiler);
72
73
  }
73
74
  }
74
75
 
@@ -12,6 +12,10 @@ const AsyncWasmChunkLoadingRuntimeModule = require("../wasm-async/AsyncWasmChunk
12
12
  /** @typedef {import("../Compiler")} Compiler */
13
13
 
14
14
  class ReadFileCompileAsyncWasmPlugin {
15
+ constructor({ type = "async-node", import: useImport = false } = {}) {
16
+ this._type = type;
17
+ this._import = useImport;
18
+ }
15
19
  /**
16
20
  * Apply the plugin
17
21
  * @param {Compiler} compiler the compiler instance
@@ -28,32 +32,50 @@ class ReadFileCompileAsyncWasmPlugin {
28
32
  options && options.wasmLoading !== undefined
29
33
  ? options.wasmLoading
30
34
  : globalWasmLoading;
31
- return wasmLoading === "async-node";
35
+ return wasmLoading === this._type;
32
36
  };
33
- const generateLoadBinaryCode = path =>
34
- Template.asString([
35
- "new Promise(function (resolve, reject) {",
36
- Template.indent([
37
- "var { readFile } = require('fs');",
38
- "var { join } = require('path');",
39
- "",
40
- "try {",
41
- Template.indent([
42
- `readFile(join(__dirname, ${path}), function(err, buffer){`,
37
+ const generateLoadBinaryCode = this._import
38
+ ? path =>
39
+ Template.asString([
40
+ "Promise.all([import('fs'), import('url')]).then(([{ readFile }, { URL }]) => new Promise((resolve, reject) => {",
43
41
  Template.indent([
44
- "if (err) return reject(err);",
45
- "",
46
- "// Fake fetch response",
47
- "resolve({",
48
- Template.indent(["arrayBuffer() { return buffer; }"]),
42
+ `readFile(new URL(${path}, import.meta.url), (err, buffer) => {`,
43
+ Template.indent([
44
+ "if (err) return reject(err);",
45
+ "",
46
+ "// Fake fetch response",
47
+ "resolve({",
48
+ Template.indent(["arrayBuffer() { return buffer; }"]),
49
+ "});"
50
+ ]),
49
51
  "});"
50
52
  ]),
51
- "});"
52
- ]),
53
- "} catch (err) { reject(err); }"
54
- ]),
55
- "})"
56
- ]);
53
+ "}))"
54
+ ])
55
+ : path =>
56
+ Template.asString([
57
+ "new Promise(function (resolve, reject) {",
58
+ Template.indent([
59
+ "try {",
60
+ Template.indent([
61
+ "var { readFile } = require('fs');",
62
+ "var { join } = require('path');",
63
+ "",
64
+ `readFile(join(__dirname, ${path}), function(err, buffer){`,
65
+ Template.indent([
66
+ "if (err) return reject(err);",
67
+ "",
68
+ "// Fake fetch response",
69
+ "resolve({",
70
+ Template.indent(["arrayBuffer() { return buffer; }"]),
71
+ "});"
72
+ ]),
73
+ "});"
74
+ ]),
75
+ "} catch (err) { reject(err); }"
76
+ ]),
77
+ "})"
78
+ ]);
57
79
 
58
80
  compilation.hooks.runtimeRequirementInTree
59
81
  .for(RuntimeGlobals.instantiateWasm)
@@ -238,12 +238,25 @@ class InnerGraphPlugin {
238
238
  }
239
239
  );
240
240
 
241
+ parser.hooks.classBodyElement.tap(
242
+ "InnerGraphPlugin",
243
+ (element, classDefinition) => {
244
+ if (!InnerGraph.isEnabled(parser.state)) return;
245
+ if (parser.scope.topLevelScope === true) {
246
+ const fn = classWithTopLevelSymbol.get(classDefinition);
247
+ if (fn) {
248
+ InnerGraph.setTopLevelSymbol(parser.state, undefined);
249
+ }
250
+ }
251
+ }
252
+ );
253
+
241
254
  parser.hooks.classBodyValue.tap(
242
255
  "InnerGraphPlugin",
243
- (expression, element, statement) => {
256
+ (expression, element, classDefinition) => {
244
257
  if (!InnerGraph.isEnabled(parser.state)) return;
245
258
  if (parser.scope.topLevelScope === true) {
246
- const fn = classWithTopLevelSymbol.get(statement);
259
+ const fn = classWithTopLevelSymbol.get(classDefinition);
247
260
  if (fn) {
248
261
  if (
249
262
  !element.static ||
@@ -253,6 +266,24 @@ class InnerGraphPlugin {
253
266
  )
254
267
  ) {
255
268
  InnerGraph.setTopLevelSymbol(parser.state, fn);
269
+ if (element.type !== "MethodDefinition" && element.static) {
270
+ InnerGraph.onUsage(parser.state, usedByExports => {
271
+ switch (usedByExports) {
272
+ case undefined:
273
+ case true:
274
+ return;
275
+ default: {
276
+ const dep = new PureExpressionDependency(
277
+ expression.range
278
+ );
279
+ dep.loc = expression.loc;
280
+ dep.usedByExports = usedByExports;
281
+ parser.state.module.addDependency(dep);
282
+ break;
283
+ }
284
+ }
285
+ });
286
+ }
256
287
  } else {
257
288
  InnerGraph.setTopLevelSymbol(parser.state, undefined);
258
289
  }
@@ -450,7 +450,7 @@ class ModuleConcatenationPlugin {
450
450
  },
451
451
  err => {
452
452
  logger.timeEnd("create concatenated modules");
453
- process.nextTick(() => callback(err));
453
+ process.nextTick(callback.bind(null, err));
454
454
  }
455
455
  );
456
456
  }
@@ -57,19 +57,23 @@ class AsyncModuleRuntimeModule extends HelperRuntimeModule {
57
57
  "completeQueue(queue);",
58
58
  "queue = 0;"
59
59
  ])});`,
60
- `var obj = { [webpackThen]: ${runtimeTemplate.expressionFunction(
60
+ `var obj = {};
61
+ obj[webpackThen] = ${runtimeTemplate.expressionFunction(
61
62
  "queueFunction(queue, fn), dep.catch(reject)",
62
63
  "fn, reject"
63
- )} };`,
64
+ )};`,
64
65
  "return obj;"
65
66
  ]),
66
67
  "}"
67
68
  ]),
68
69
  "}",
69
- `return { [webpackThen]: ${runtimeTemplate.expressionFunction(
70
+ `var ret = {};
71
+ ret[webpackThen] = ${runtimeTemplate.expressionFunction(
70
72
  "completeFunction(fn)",
71
73
  "fn"
72
- )}, [webpackExports]: dep };`
74
+ )};
75
+ ret[webpackExports] = dep;
76
+ return ret;`
73
77
  ])})`,
74
78
  "deps"
75
79
  )};`,