webpack 5.108.4 → 5.109.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.
Files changed (200) hide show
  1. package/bin/webpack.js +12 -0
  2. package/lib/APIPlugin.js +48 -29
  3. package/lib/CacheFacade.js +8 -0
  4. package/lib/ChunkGraph.js +17 -15
  5. package/lib/ChunkGroup.js +1 -0
  6. package/lib/CompatibilityPlugin.js +62 -29
  7. package/lib/Compilation.js +58 -6
  8. package/lib/ConstPlugin.js +11 -11
  9. package/lib/ContextModule.js +239 -6
  10. package/lib/ContextModuleFactory.js +139 -14
  11. package/lib/DefinePlugin.js +433 -112
  12. package/lib/Entrypoint.js +1 -1
  13. package/lib/ExportsInfo.js +22 -5
  14. package/lib/ExportsInfoApiPlugin.js +2 -2
  15. package/lib/ExternalModule.js +107 -5
  16. package/lib/ExternalModuleFactoryPlugin.js +20 -1
  17. package/lib/FileSystemInfo.js +256 -100
  18. package/lib/FlagDependencyUsagePlugin.js +33 -12
  19. package/lib/HotModuleReplacementPlugin.js +18 -15
  20. package/lib/InitFragment.js +20 -32
  21. package/lib/Module.js +3 -0
  22. package/lib/ModuleFilenameHelpers.js +2 -2
  23. package/lib/ModuleTypeConstants.js +8 -1
  24. package/lib/MultiCompiler.js +13 -2
  25. package/lib/MultiWatching.js +1 -0
  26. package/lib/NodeStuffPlugin.js +51 -33
  27. package/lib/NormalModule.js +175 -401
  28. package/lib/NormalModuleFactory.js +76 -2
  29. package/lib/ProgressPlugin.js +211 -119
  30. package/lib/ProvidePlugin.js +2 -2
  31. package/lib/RuntimeGlobals.js +47 -0
  32. package/lib/RuntimePlugin.js +67 -107
  33. package/lib/RuntimeTemplate.js +304 -16
  34. package/lib/Template.js +23 -3
  35. package/lib/UseStrictPlugin.js +1 -1
  36. package/lib/WebpackIsIncludedPlugin.js +1 -1
  37. package/lib/WebpackOptionsApply.js +24 -19
  38. package/lib/asset/AssetGenerator.js +110 -28
  39. package/lib/asset/AssetModulesPlugin.js +92 -2
  40. package/lib/asset/WebManifestGenerator.js +164 -0
  41. package/lib/asset/WebManifestParser.js +130 -0
  42. package/lib/async-modules/AwaitDependenciesInitFragment.js +14 -4
  43. package/lib/async-modules/isGeneratorLowered.js +26 -0
  44. package/lib/cache/PackFileCacheStrategy.js +9 -3
  45. package/lib/config/browserslistTargetHandler.js +40 -0
  46. package/lib/config/defaults.js +219 -29
  47. package/lib/config/normalization.js +26 -0
  48. package/lib/config/target.js +9 -1
  49. package/lib/container/HoistContainerReferencesPlugin.js +47 -55
  50. package/lib/css/CssGenerator.js +40 -31
  51. package/lib/css/CssLoadingRuntimeModule.js +5 -1
  52. package/lib/css/CssModulesPlugin.js +13 -0
  53. package/lib/css/CssParser.js +729 -313
  54. package/lib/css/syntax.js +1371 -861
  55. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -6
  56. package/lib/dependencies/AMDPlugin.js +2 -2
  57. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +13 -13
  58. package/lib/dependencies/CommonJsDependencyHelpers.js +39 -0
  59. package/lib/dependencies/CommonJsExportRequireDependency.js +19 -0
  60. package/lib/dependencies/CommonJsExportsDependency.js +47 -2
  61. package/lib/dependencies/CommonJsExportsParserPlugin.js +10 -10
  62. package/lib/dependencies/CommonJsImportsParserPlugin.js +18 -18
  63. package/lib/dependencies/CommonJsPlugin.js +2 -2
  64. package/lib/dependencies/CommonJsRequireDependency.js +26 -1
  65. package/lib/dependencies/CommonJsSelfReferenceDependency.js +32 -1
  66. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  67. package/lib/dependencies/CreateRequireParserPlugin.js +6 -6
  68. package/lib/dependencies/CssIcssExportDependency.js +162 -71
  69. package/lib/dependencies/CssUrlDependency.js +35 -4
  70. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +2 -2
  71. package/lib/dependencies/HarmonyCompatibilityDependency.js +32 -14
  72. package/lib/dependencies/HarmonyDetectionParserPlugin.js +43 -13
  73. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +2 -1
  74. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +7 -19
  75. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +17 -9
  76. package/lib/dependencies/HarmonyImportDependency.js +13 -2
  77. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +11 -11
  78. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -7
  79. package/lib/dependencies/HarmonyModulesPlugin.js +6 -0
  80. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +1 -1
  81. package/lib/dependencies/HtmlEntryDependency.js +797 -172
  82. package/lib/dependencies/HtmlSourceDependency.js +26 -0
  83. package/lib/dependencies/ImportDependency.js +43 -1
  84. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +31 -18
  85. package/lib/dependencies/ImportMetaContextPlugin.js +38 -7
  86. package/lib/dependencies/ImportMetaGlobDependency.js +81 -0
  87. package/lib/dependencies/ImportMetaGlobDependencyParserPlugin.js +78 -0
  88. package/lib/dependencies/ImportMetaGlobHelpers.js +660 -0
  89. package/lib/dependencies/ImportMetaPlugin.js +532 -180
  90. package/lib/dependencies/ImportMetaResolveDependency.js +90 -0
  91. package/lib/dependencies/ImportParserPlugin.js +80 -17
  92. package/lib/dependencies/ImportPhase.js +10 -8
  93. package/lib/dependencies/LoaderPlugin.js +5 -1
  94. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  95. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +3 -6
  96. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +4 -11
  97. package/lib/dependencies/SystemPlugin.js +2 -4
  98. package/lib/dependencies/TopLevelAwaitDependency.js +93 -0
  99. package/lib/dependencies/URLDependency.js +141 -21
  100. package/lib/dependencies/{WorkerPlugin.js → WorkerAndWorkletPlugin.js} +324 -112
  101. package/lib/dependencies/WorkerDependency.js +86 -18
  102. package/lib/dependencies/WorkletDependency.js +278 -0
  103. package/lib/dll/DelegatedModuleFactoryPlugin.js +19 -0
  104. package/lib/errors/EnvironmentNotSupportAsyncWarning.js +1 -1
  105. package/lib/errors/LoaderLoadingError.js +20 -0
  106. package/lib/errors/ModuleParseError.js +39 -22
  107. package/lib/errors/NodeStuffInWebError.js +1 -1
  108. package/lib/esm/ModuleChunkFormatPlugin.js +47 -14
  109. package/lib/esm/ModuleChunkLoadingPlugin.js +8 -1
  110. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +29 -1
  111. package/lib/hmr/lazyCompilationBackend.js +51 -12
  112. package/lib/html/HtmlGenerator.js +907 -15
  113. package/lib/html/HtmlModule.js +2 -2
  114. package/lib/html/HtmlModulesPlugin.js +610 -166
  115. package/lib/html/HtmlParser.js +603 -247
  116. package/lib/html/favicon.svg +1 -0
  117. package/lib/html/syntax.js +3451 -2762
  118. package/lib/ids/IdHelpers.js +25 -11
  119. package/lib/index.js +6 -0
  120. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +4 -5
  121. package/lib/javascript/BasicEvaluatedExpression.js +366 -48
  122. package/lib/javascript/JavascriptGenerator.js +197 -49
  123. package/lib/javascript/JavascriptModulesPlugin.js +178 -24
  124. package/lib/javascript/JavascriptParser.js +704 -355
  125. package/lib/javascript/JavascriptParserHelpers.js +3 -6
  126. package/lib/javascript/syntax.js +5037 -0
  127. package/lib/library/ModuleLibraryPlugin.js +38 -1
  128. package/lib/loaders/LoaderRunner.js +714 -0
  129. package/lib/loaders/loadLoader.js +100 -0
  130. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +29 -2
  131. package/lib/node/ReadFileCompileWasmPlugin.js +24 -2
  132. package/lib/optimize/AggressiveMergingPlugin.js +19 -15
  133. package/lib/optimize/ConcatenatedModule.js +139 -31
  134. package/lib/optimize/FlagIncludedChunksPlugin.js +13 -3
  135. package/lib/optimize/InnerGraphPlugin.js +50 -30
  136. package/lib/optimize/ModuleConcatenationPlugin.js +139 -24
  137. package/lib/optimize/SideEffectsFlagPlugin.js +86 -43
  138. package/lib/optimize/SplitChunksPlugin.js +146 -44
  139. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +15 -0
  140. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +24 -13
  141. package/lib/prefetch/ResourceHintPlugin.js +687 -0
  142. package/lib/prefetch/ResourceHintRuntimeModule.js +149 -0
  143. package/lib/prefetch/StartupAssetHintRuntimeModule.js +210 -0
  144. package/lib/prefetch/parseResourceHintOptions.js +103 -0
  145. package/lib/rules/RuleSetCompiler.js +114 -0
  146. package/lib/runtime/AsyncModuleGeneratorRuntimeModule.js +56 -0
  147. package/lib/runtime/AsyncModuleRuntimeModule.js +24 -8
  148. package/lib/runtime/AutoPublicPathRuntimeModule.js +7 -1
  149. package/lib/runtime/CommonJsWrapRuntimeModule.js +37 -0
  150. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +59 -0
  151. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +204 -8
  152. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +4 -1
  153. package/lib/schemes/HttpUriPlugin.js +40 -1
  154. package/lib/schemes/VirtualUrlPlugin.js +1 -2
  155. package/lib/serialization/BinaryMiddleware.js +270 -938
  156. package/lib/serialization/FileMiddleware.js +29 -3
  157. package/lib/stats/DefaultStatsFactoryPlugin.js +229 -194
  158. package/lib/stats/DefaultStatsPresetPlugin.js +2 -0
  159. package/lib/stats/DefaultStatsPrinterPlugin.js +36 -168
  160. package/lib/stats/StatsFactory.js +46 -17
  161. package/lib/url/URLParserPlugin.js +66 -13
  162. package/lib/util/AsyncQueue.js +122 -72
  163. package/lib/util/SetHelpers.js +1 -1
  164. package/lib/util/StackedMap.js +122 -48
  165. package/lib/util/binarySearchBounds.js +2 -2
  166. package/lib/util/concatenate.js +40 -14
  167. package/lib/util/createHooksRegistry.js +13 -5
  168. package/lib/util/dataURL.js +2 -2
  169. package/lib/util/deterministicGrouping.js +7 -5
  170. package/lib/util/formatSize.js +6 -2
  171. package/lib/util/globUtils.js +710 -0
  172. package/lib/util/identifier.js +23 -6
  173. package/lib/util/implicitTypeLoaderFallback.js +62 -0
  174. package/lib/util/internalSerializables.js +88 -71
  175. package/lib/util/magicComment.js +121 -25
  176. package/lib/util/numberHash.js +2 -2
  177. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +24 -18
  178. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +33 -22
  179. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +79 -16
  180. package/lib/web/FetchCompileAsyncWasmPlugin.js +19 -0
  181. package/lib/web/FetchCompileWasmPlugin.js +14 -0
  182. package/lib/web/JsonpChunkLoadingRuntimeModule.js +2 -0
  183. package/lib/webpack.js +65 -0
  184. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +3 -0
  185. package/module.d.ts +21 -0
  186. package/package.json +12 -11
  187. package/schemas/WebpackOptions.check.js +1 -1
  188. package/schemas/WebpackOptions.json +759 -36
  189. package/schemas/plugins/HtmlParserOptions.check.js +1 -1
  190. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  191. package/schemas/plugins/ProgressPlugin.json +17 -1
  192. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  193. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  194. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  195. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  196. package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
  197. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +1 -1
  198. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  199. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  200. package/types.d.ts +1212 -99
@@ -14,6 +14,7 @@ const {
14
14
  const CommentCompilationWarning = require("../errors/CommentCompilationWarning");
15
15
  const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
16
16
  const EnableChunkLoadingPlugin = require("../javascript/EnableChunkLoadingPlugin");
17
+ const parseResourceHintOptions = require("../prefetch/parseResourceHintOptions");
17
18
  const { equals } = require("../util/ArrayHelpers");
18
19
  const createHash = require("../util/createHash");
19
20
  const { contextify } = require("../util/identifier");
@@ -23,7 +24,9 @@ const CreateScriptUrlDependency = require("./CreateScriptUrlDependency");
23
24
  const {
24
25
  harmonySpecifierTag
25
26
  } = require("./HarmonyImportDependencyParserPlugin");
27
+ const { isImportMetaFieldEnabled } = require("./ImportMetaPlugin");
26
28
  const WorkerDependency = require("./WorkerDependency");
29
+ const WorkletDependency = require("./WorkletDependency");
27
30
 
28
31
  /** @typedef {import("estree").CallExpression} CallExpression */
29
32
  /** @typedef {import("estree").Expression} Expression */
@@ -46,6 +49,7 @@ const WorkerDependency = require("./WorkerDependency");
46
49
  /** @typedef {import("../javascript/JavascriptParser").JavascriptParserState} JavascriptParserState */
47
50
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
48
51
  /** @typedef {import("./HarmonyImportDependencyParserPlugin").HarmonySettings} HarmonySettings */
52
+ /** @typedef {import("./WorkerDependency").ResourceHint} ResourceHint */
49
53
 
50
54
  /**
51
55
  * Returns url.
@@ -55,28 +59,48 @@ const WorkerDependency = require("./WorkerDependency");
55
59
  const getUrl = (module) => pathToFileURL(module.resource).toString();
56
60
 
57
61
  const WorkerSpecifierTag = Symbol("worker specifier tag");
62
+ const WorkletSpecifierTag = Symbol("worklet specifier tag");
58
63
 
59
- const DEFAULT_SYNTAX = [
64
+ const WORKER_DEFAULT_SYNTAX = [
60
65
  "Worker",
61
66
  "SharedWorker",
62
67
  "navigator.serviceWorker.register()",
63
68
  "Worker from worker_threads"
64
69
  ];
65
70
 
71
+ // Worklets are always module scripts loaded through `addModule` and — unlike Web
72
+ // Workers — cannot load additional chunks at runtime (no `importScripts`, no
73
+ // dynamic `import()`). The WorkletDependency wraps the call so every chunk is
74
+ // pre-added via `addModule` from the calling scope (see WorkletDependency).
75
+ const WORKLET_DEFAULT_SYNTAX = [
76
+ "*context.audioWorklet.addModule()",
77
+ "*audioWorklet.addModule()",
78
+ "CSS.paintWorklet.addModule()",
79
+ "CSS.layoutWorklet.addModule()",
80
+ "CSS.animationWorklet.addModule()"
81
+ ];
82
+
66
83
  /** @type {WeakMap<JavascriptParserState, number>} */
67
84
  const workerIndexMap = new WeakMap();
68
85
 
69
- const PLUGIN_NAME = "WorkerPlugin";
86
+ const PLUGIN_NAME = "WorkerAndWorkletPlugin";
70
87
 
71
- class WorkerPlugin {
88
+ class WorkerAndWorkletPlugin {
72
89
  /**
73
- * Creates an instance of WorkerPlugin.
90
+ * Creates an instance of WorkerAndWorkletPlugin.
74
91
  * @param {ChunkLoading=} chunkLoading chunk loading
75
92
  * @param {WasmLoading=} wasmLoading wasm loading
76
93
  * @param {OutputModule=} module output module
77
94
  * @param {WorkerPublicPath=} workerPublicPath worker public path
95
+ * @param {boolean=} workletDefault whether worklet parsing is on when `parser.worklet` is unset (enabled by `futureDefaults`)
78
96
  */
79
- constructor(chunkLoading, wasmLoading, module, workerPublicPath) {
97
+ constructor(
98
+ chunkLoading,
99
+ wasmLoading,
100
+ module,
101
+ workerPublicPath,
102
+ workletDefault
103
+ ) {
80
104
  /** @type {ChunkLoading | undefined} */
81
105
  this._chunkLoading = chunkLoading;
82
106
  /** @type {WasmLoading | undefined} */
@@ -85,6 +109,8 @@ class WorkerPlugin {
85
109
  this._module = module;
86
110
  /** @type {string | undefined} */
87
111
  this._workerPublicPath = workerPublicPath;
112
+ /** @type {boolean} */
113
+ this._workletDefault = Boolean(workletDefault);
88
114
  }
89
115
 
90
116
  /**
@@ -114,22 +140,54 @@ class WorkerPlugin {
114
140
  WorkerDependency,
115
141
  new WorkerDependency.Template()
116
142
  );
143
+ compilation.dependencyFactories.set(
144
+ WorkletDependency,
145
+ normalModuleFactory
146
+ );
147
+ compilation.dependencyTemplates.set(
148
+ WorkletDependency,
149
+ new WorkletDependency.Template()
150
+ );
117
151
  compilation.dependencyTemplates.set(
118
152
  CreateScriptUrlDependency,
119
153
  new CreateScriptUrlDependency.Template()
120
154
  );
121
155
 
122
156
  /**
123
- * Returns parsed.
157
+ * Checks whether the expression is `import.meta.url`.
158
+ * @param {JavascriptParser} parser the parser
159
+ * @param {MemberExpression} expr expression
160
+ * @returns {boolean} is `import.meta.url`
161
+ */
162
+ const isMetaUrl = (parser, expr) => {
163
+ const chain = parser.extractMemberExpressionChain(expr);
164
+
165
+ if (
166
+ chain.members.length !== 1 ||
167
+ chain.object.type !== "MetaProperty" ||
168
+ chain.object.meta.name !== "import" ||
169
+ chain.object.property.name !== "meta" ||
170
+ chain.members[0] !== "url"
171
+ ) {
172
+ return false;
173
+ }
174
+
175
+ return true;
176
+ };
177
+
178
+ /**
179
+ * Resolves a `new URL(..., import.meta.url)` argument to its module url.
124
180
  * @param {JavascriptParser} parser the parser
125
181
  * @param {Expression} expr expression
182
+ * @param {boolean} importMetaUrlEnabled true when import.meta.url should be handled
126
183
  * @returns {[string, Range] | void} parsed
127
184
  */
128
- const parseModuleUrl = (parser, expr) => {
185
+ const parseModuleUrl = (parser, expr, importMetaUrlEnabled) => {
129
186
  if (expr.type !== "NewExpression" || expr.callee.type === "Super") {
130
187
  return;
131
188
  }
132
189
  if (
190
+ importMetaUrlEnabled &&
133
191
  expr.arguments.length === 1 &&
134
192
  expr.arguments[0].type === "MemberExpression" &&
135
193
  isMetaUrl(parser, expr.arguments[0])
@@ -170,28 +228,6 @@ class WorkerPlugin {
170
228
  }
171
229
  };
172
230
 
173
- /**
174
- * Checks whether this worker plugin is meta url.
175
- * @param {JavascriptParser} parser the parser
176
- * @param {MemberExpression} expr expression
177
- * @returns {boolean} is `import.meta.url`
178
- */
179
- const isMetaUrl = (parser, expr) => {
180
- const chain = parser.extractMemberExpressionChain(expr);
181
-
182
- if (
183
- chain.members.length !== 1 ||
184
- chain.object.type !== "MetaProperty" ||
185
- chain.object.meta.name !== "import" ||
186
- chain.object.property.name !== "meta" ||
187
- chain.members[0] !== "url"
188
- ) {
189
- return false;
190
- }
191
-
192
- return true;
193
- };
194
-
195
231
  /** @typedef {Record<string, EXPECTED_ANY>} Values */
196
232
 
197
233
  /**
@@ -232,9 +268,12 @@ class WorkerPlugin {
232
268
  }
233
269
  }
234
270
  const insertType = expr.properties.length > 0 ? "comma" : "single";
235
- const insertLocation = /** @type {Range} */ (
236
- expr.properties[expr.properties.length - 1].range
237
- )[1];
271
+ const insertLocation =
272
+ expr.properties.length > 0
273
+ ? /** @type {Range} */ (
274
+ expr.properties[expr.properties.length - 1].range
275
+ )[1]
276
+ : /** @type {Range} */ (expr.range)[0] + 1;
238
277
  return {
239
278
  expressions,
240
279
  otherElements,
@@ -252,17 +291,17 @@ class WorkerPlugin {
252
291
  * @returns {void}
253
292
  */
254
293
  const parserPlugin = (parser, parserOptions) => {
255
- if (parserOptions.worker === false) return;
256
- const options = !Array.isArray(parserOptions.worker)
257
- ? ["..."]
258
- : parserOptions.worker;
294
+ const importMetaUrlEnabled = isImportMetaFieldEnabled(
295
+ parserOptions.importMeta,
296
+ "url"
297
+ );
298
+
259
299
  /**
260
- * Returns true when handled.
300
+ * Resolves the url argument (the `new URL(...)` / bare `import.meta.url`).
261
301
  * @param {CallExpression} expr expression
262
- * @param {boolean=} isGlobalWorker matched the global `new Worker()` syntax (eligible for universal rewrite)
263
- * @returns {boolean | void} true when handled
302
+ * @returns {{ url: string, range: Range, needNewUrl: boolean, arg1: Expression | SpreadElement, arg2: Expression | SpreadElement | undefined } | void} resolved url info
264
303
  */
265
- const handleNewWorker = (expr, isGlobalWorker = false) => {
304
+ const resolveWorkerUrl = (expr) => {
266
305
  if (expr.arguments.length === 0 || expr.arguments.length > 2) {
267
306
  return;
268
307
  }
@@ -274,10 +313,13 @@ class WorkerPlugin {
274
313
  let url;
275
314
  /** @type {Range} */
276
315
  let range;
277
- /** @type {boolean} */
278
316
  let needNewUrl = false;
279
317
 
280
- if (arg1.type === "MemberExpression" && isMetaUrl(parser, arg1)) {
318
+ if (
319
+ arg1.type === "MemberExpression" &&
320
+ importMetaUrlEnabled &&
321
+ isMetaUrl(parser, arg1)
322
+ ) {
281
323
  url = getUrl(parser.state.module);
282
324
  range = [
283
325
  /** @type {Range} */ (arg1.range)[0],
@@ -285,32 +327,24 @@ class WorkerPlugin {
285
327
  ];
286
328
  needNewUrl = true;
287
329
  } else {
288
- const parsedUrl = parseModuleUrl(parser, arg1);
330
+ const parsedUrl = parseModuleUrl(
331
+ parser,
332
+ arg1,
333
+ importMetaUrlEnabled
334
+ );
289
335
  if (!parsedUrl) return;
290
336
  [url, range] = parsedUrl;
291
337
  }
292
338
 
293
- const {
294
- expressions,
295
- otherElements,
296
- values: options,
297
- spread: hasSpreadInOptions,
298
- insertType,
299
- insertLocation
300
- } = arg2 && arg2.type === "ObjectExpression"
301
- ? parseObjectExpression(parser, arg2)
302
- : {
303
- expressions:
304
- /** @type {Record<string, Expression | Pattern>} */ ({}),
305
- otherElements: [],
306
- /** @type {Values} */
307
- values: {},
308
- spread: false,
309
- insertType: arg2 ? "spread" : "argument",
310
- insertLocation: arg2
311
- ? /** @type {Range} */ (arg2.range)
312
- : /** @type {Range} */ (arg1.range)[1]
313
- };
339
+ return { url, range, needNewUrl, arg1, arg2 };
340
+ };
341
+
342
+ /**
343
+ * Reads the magic-comment entry options for the matched expression.
344
+ * @param {CallExpression} expr expression
345
+ * @returns {EntryOptions | false} entry options, or false when `webpackIgnore`
346
+ */
347
+ const parseEntryOptions = (expr) => {
314
348
  const { options: importOptions, errors: commentErrors } =
315
349
  parser.parseCommentOptions(/** @type {Range} */ (expr.range));
316
350
 
@@ -320,7 +354,7 @@ class WorkerPlugin {
320
354
  parser.state.module.addWarning(
321
355
  new CommentCompilationWarning(
322
356
  `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
323
- /** @type {DependencyLocation} */ (comment.loc)
357
+ parser.getLocation(comment)
324
358
  )
325
359
  );
326
360
  }
@@ -335,7 +369,7 @@ class WorkerPlugin {
335
369
  parser.state.module.addWarning(
336
370
  new UnsupportedFeatureWarning(
337
371
  `\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`,
338
- /** @type {DependencyLocation} */ (expr.loc)
372
+ parser.getLocation(expr)
339
373
  )
340
374
  );
341
375
  } else if (importOptions.webpackIgnore) {
@@ -350,7 +384,7 @@ class WorkerPlugin {
350
384
  parser.state.module.addWarning(
351
385
  new UnsupportedFeatureWarning(
352
386
  `\`webpackEntryOptions\` expected a object, but received: ${importOptions.webpackEntryOptions}.`,
353
- /** @type {DependencyLocation} */ (expr.loc)
387
+ parser.getLocation(expr)
354
388
  )
355
389
  );
356
390
  } else {
@@ -379,7 +413,7 @@ class WorkerPlugin {
379
413
  parser.state.module.addWarning(
380
414
  new UnsupportedFeatureWarning(
381
415
  `\`webpackChunkName\` expected a string, but received: ${importOptions.webpackChunkName}.`,
382
- /** @type {DependencyLocation} */ (expr.loc)
416
+ parser.getLocation(expr)
383
417
  )
384
418
  );
385
419
  } else {
@@ -388,6 +422,94 @@ class WorkerPlugin {
388
422
  }
389
423
  }
390
424
 
425
+ return entryOptions;
426
+ };
427
+
428
+ /**
429
+ * Assigns a unique runtime to the entry so each worker gets its own runtime chunk.
430
+ * @param {EntryOptions} entryOptions entry options
431
+ * @returns {void}
432
+ */
433
+ const ensureRuntime = (entryOptions) => {
434
+ if (entryOptions.runtime !== undefined) return;
435
+ const i = workerIndexMap.get(parser.state) || 0;
436
+ workerIndexMap.set(parser.state, i + 1);
437
+ const name = `${cachedContextify(
438
+ parser.state.module.identifier()
439
+ )}|${i}`;
440
+ const hash = createHash(compilation.outputOptions.hashFunction);
441
+ hash.update(name);
442
+ const digest = hash.digest(compilation.outputOptions.hashDigest);
443
+ entryOptions.runtime = digest.slice(
444
+ 0,
445
+ compilation.outputOptions.hashDigestLength
446
+ );
447
+ };
448
+
449
+ /**
450
+ * Handles a matched `new Worker(...)` expression.
451
+ * @param {CallExpression} expr expression
452
+ * @param {boolean=} isGlobalWorker matched the global `new Worker()` syntax (eligible for universal rewrite)
453
+ * @returns {boolean | void} true when handled
454
+ */
455
+ const handleNewWorker = (expr, isGlobalWorker = false) => {
456
+ const parsedUrl = resolveWorkerUrl(expr);
457
+ if (!parsedUrl) return;
458
+ const { url, range, needNewUrl, arg1, arg2 } = parsedUrl;
459
+
460
+ const {
461
+ expressions,
462
+ otherElements,
463
+ values: options,
464
+ spread: hasSpreadInOptions,
465
+ insertType,
466
+ insertLocation
467
+ } = arg2 && arg2.type === "ObjectExpression"
468
+ ? parseObjectExpression(parser, arg2)
469
+ : {
470
+ expressions:
471
+ /** @type {Record<string, Expression | Pattern>} */ ({}),
472
+ otherElements: [],
473
+ /** @type {Values} */
474
+ values: {},
475
+ spread: false,
476
+ insertType: arg2 ? "spread" : "argument",
477
+ insertLocation: arg2
478
+ ? /** @type {Range} */ (arg2.range)
479
+ : /** @type {Range} */ (arg1.range)[1]
480
+ };
481
+
482
+ const entryOptions = parseEntryOptions(expr);
483
+ if (entryOptions === false) return false;
484
+
485
+ /** @type {ResourceHint | undefined} */
486
+ let resourceHint;
487
+ // Resource-hint comments belong to the asset expression — read
488
+ // them from the inner `new URL(...)` range only, never from
489
+ // elsewhere inside `new Worker(...)`. When `arg1` is bare
490
+ // `import.meta.url` there is no `new URL` and no place for
491
+ // the comments to go, so resource hints are skipped.
492
+ if (arg1.type === "NewExpression") {
493
+ const { options: urlImportOptions } = parser.parseCommentOptions(
494
+ /** @type {Range} */ (arg1.range)
495
+ );
496
+ const hints = parseResourceHintOptions(
497
+ urlImportOptions,
498
+ parser.state.module,
499
+ /** @type {DependencyLocation} */ (expr.loc)
500
+ );
501
+ if (hints.prefetch || hints.preload) {
502
+ resourceHint = {
503
+ prefetch: hints.prefetch,
504
+ preload: hints.preload,
505
+ fetchPriority: hints.fetchPriority,
506
+ as: hints.as,
507
+ type: hints.type,
508
+ media: hints.media
509
+ };
510
+ }
511
+ }
512
+
391
513
  if (
392
514
  !Object.prototype.hasOwnProperty.call(entryOptions, "name") &&
393
515
  options &&
@@ -396,20 +518,7 @@ class WorkerPlugin {
396
518
  entryOptions.name = options.name;
397
519
  }
398
520
 
399
- if (entryOptions.runtime === undefined) {
400
- const i = workerIndexMap.get(parser.state) || 0;
401
- workerIndexMap.set(parser.state, i + 1);
402
- const name = `${cachedContextify(
403
- parser.state.module.identifier()
404
- )}|${i}`;
405
- const hash = createHash(compilation.outputOptions.hashFunction);
406
- hash.update(name);
407
- const digest = hash.digest(compilation.outputOptions.hashDigest);
408
- entryOptions.runtime = digest.slice(
409
- 0,
410
- compilation.outputOptions.hashDigestLength
411
- );
412
- }
521
+ ensureRuntime(entryOptions);
413
522
 
414
523
  const block = new AsyncDependenciesBlock({
415
524
  name: entryOptions.name,
@@ -421,15 +530,16 @@ class WorkerPlugin {
421
530
  worker: true
422
531
  }
423
532
  });
424
- block.loc = expr.loc;
533
+ block.loc = parser.getLocation(expr);
425
534
  const dep = new WorkerDependency(url, range, {
426
535
  publicPath: this._workerPublicPath,
427
536
  needNewUrl,
428
537
  workerConstructorRange: isGlobalWorker
429
538
  ? /** @type {Range} */ (expr.callee.range)
430
- : undefined
539
+ : undefined,
540
+ resourceHint
431
541
  });
432
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
542
+ dep.loc = parser.getLocation(expr);
433
543
  block.addDependency(dep);
434
544
  parser.state.module.addBlock(block);
435
545
 
@@ -437,7 +547,7 @@ class WorkerPlugin {
437
547
  const dep = new CreateScriptUrlDependency(
438
548
  /** @type {Range} */ (expr.arguments[0].range)
439
549
  );
440
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
550
+ dep.loc = parser.getLocation(expr);
441
551
  parser.state.module.addDependency(dep);
442
552
  }
443
553
 
@@ -448,7 +558,7 @@ class WorkerPlugin {
448
558
  this._module ? '"module"' : "undefined",
449
559
  /** @type {Range} */ (expr.range)
450
560
  );
451
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
561
+ dep.loc = parser.getLocation(expr);
452
562
  parser.state.module.addPresentationalDependency(dep);
453
563
  /** @type {EXPECTED_ANY} */
454
564
  (expressions).type = undefined;
@@ -459,7 +569,7 @@ class WorkerPlugin {
459
569
  `, type: ${this._module ? '"module"' : "undefined"}`,
460
570
  insertLocation
461
571
  );
462
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
572
+ dep.loc = parser.getLocation(expr);
463
573
  parser.state.module.addPresentationalDependency(dep);
464
574
  }
465
575
  } else if (insertType === "spread") {
@@ -474,8 +584,8 @@ class WorkerPlugin {
474
584
  useSpread ? `), type: ${type} }` : `, { type: ${type} })`,
475
585
  /** @type {Range} */ (insertLocation)[1]
476
586
  );
477
- dep1.loc = /** @type {DependencyLocation} */ (expr.loc);
478
- dep2.loc = /** @type {DependencyLocation} */ (expr.loc);
587
+ dep1.loc = parser.getLocation(expr);
588
+ dep2.loc = parser.getLocation(expr);
479
589
  parser.state.module.addPresentationalDependency(dep1);
480
590
  parser.state.module.addPresentationalDependency(dep2);
481
591
  } else if (insertType === "argument" && this._module) {
@@ -483,7 +593,7 @@ class WorkerPlugin {
483
593
  ', { type: "module" }',
484
594
  insertLocation
485
595
  );
486
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
596
+ dep.loc = parser.getLocation(expr);
487
597
  parser.state.module.addPresentationalDependency(dep);
488
598
  }
489
599
 
@@ -501,16 +611,75 @@ class WorkerPlugin {
501
611
  parser.walkProperty(prop);
502
612
  }
503
613
  if (insertType === "spread") {
504
- parser.walkExpression(arg2);
614
+ parser.walkExpression(/** @type {Expression} */ (arg2));
505
615
  }
506
616
 
507
617
  return true;
508
618
  };
619
+
620
+ /**
621
+ * Handles a matched `addModule(...)` worklet expression.
622
+ * @param {CallExpression} expr expression
623
+ * @returns {boolean | void} true when handled
624
+ */
625
+ const handleNewWorklet = (expr) => {
626
+ const parsedUrl = resolveWorkerUrl(expr);
627
+ if (!parsedUrl) return;
628
+ const { url } = parsedUrl;
629
+
630
+ const entryOptions = parseEntryOptions(expr);
631
+ if (entryOptions === false) return false;
632
+
633
+ const block = new AsyncDependenciesBlock({
634
+ name: entryOptions.name,
635
+ circular: false,
636
+ entryOptions: {
637
+ // A module worklet links its split chunks via native `import`
638
+ // (resolved by `addModule`), so it keeps the module chunk
639
+ // loading. A script worklet can't load chunks at runtime, so its
640
+ // chunks use import-scripts and are pre-added from the calling scope.
641
+ chunkLoading: this._module
642
+ ? this._chunkLoading
643
+ : "import-scripts",
644
+ wasmLoading: false,
645
+ ...entryOptions,
646
+ worker: true,
647
+ // `addModule` always loads the chunk as a module, so its
648
+ // auto public-path can read `import.meta.url` (no shim needed).
649
+ worklet: true
650
+ }
651
+ });
652
+ block.loc = parser.getLocation(expr);
653
+ // The dependency rewrites the call site: the fast path swaps the URL
654
+ // argument directly, the multi-chunk path wraps it in a bootstrap.
655
+ const dep = new WorkletDependency(
656
+ url,
657
+ [
658
+ /** @type {Range} */ (expr.range)[0],
659
+ /** @type {Range} */ (expr.range)[0]
660
+ ],
661
+ [
662
+ /** @type {Range} */ (expr.callee.range)[1],
663
+ /** @type {Range} */ (expr.range)[1]
664
+ ],
665
+ { publicPath: this._workerPublicPath }
666
+ );
667
+ dep.loc = parser.getLocation(expr);
668
+ block.addDependency(dep);
669
+ parser.state.module.addBlock(block);
670
+
671
+ parser.walkExpression(expr.callee);
672
+
673
+ return true;
674
+ };
675
+
509
676
  /**
510
- * Processes the provided item.
677
+ * Registers the parser hooks matching a single syntax item.
511
678
  * @param {string} item item
679
+ * @param {(expr: CallExpression, isGlobalWorker?: boolean) => boolean | void} handle handler invoked on a match
680
+ * @param {symbol} specifierTag tag used for `*variable` syntax
512
681
  */
513
- const processItem = (item) => {
682
+ const processItem = (item, handle, specifierTag) => {
514
683
  if (
515
684
  item.startsWith("*") &&
516
685
  item.includes(".") &&
@@ -527,28 +696,26 @@ class WorkerPlugin {
527
696
  decl.id.type === "Identifier" &&
528
697
  decl.id.name === pattern
529
698
  ) {
530
- parser.tagVariable(decl.id.name, WorkerSpecifierTag);
699
+ parser.tagVariable(decl.id.name, specifierTag);
531
700
  return true;
532
701
  }
533
702
  }
534
703
  );
535
704
  parser.hooks.pattern.for(pattern).tap(PLUGIN_NAME, (pattern) => {
536
- parser.tagVariable(pattern.name, WorkerSpecifierTag);
705
+ parser.tagVariable(pattern.name, specifierTag);
537
706
  return true;
538
707
  });
539
708
  parser.hooks.callMemberChain
540
- .for(WorkerSpecifierTag)
709
+ .for(specifierTag)
541
710
  .tap(PLUGIN_NAME, (expression, members) => {
542
711
  if (itemMembers !== members.join(".")) {
543
712
  return;
544
713
  }
545
714
 
546
- return handleNewWorker(expression);
715
+ return handle(expression);
547
716
  });
548
717
  } else if (item.endsWith("()")) {
549
- parser.hooks.call
550
- .for(item.slice(0, -2))
551
- .tap(PLUGIN_NAME, handleNewWorker);
718
+ parser.hooks.call.for(item.slice(0, -2)).tap(PLUGIN_NAME, handle);
552
719
  } else {
553
720
  const match = /^(.+?)(\(\))?\s+from\s+(.+)$/.exec(item);
554
721
  if (match) {
@@ -568,25 +735,70 @@ class WorkerPlugin {
568
735
  ) {
569
736
  return;
570
737
  }
571
- return handleNewWorker(expr);
738
+ return handle(expr);
572
739
  });
573
740
  } else {
574
741
  parser.hooks.new
575
742
  .for(item)
576
- .tap(PLUGIN_NAME, (expr) =>
577
- handleNewWorker(expr, item === "Worker")
578
- );
743
+ .tap(PLUGIN_NAME, (expr) => handle(expr, item === "Worker"));
579
744
  }
580
745
  }
581
746
  };
582
- for (const item of options) {
583
- if (item === "...") {
584
- for (const itemFromDefault of DEFAULT_SYNTAX) {
585
- processItem(itemFromDefault);
747
+
748
+ /**
749
+ * Expands and registers a syntax list.
750
+ * @param {string[]} syntaxList syntax list (may contain "...")
751
+ * @param {string[]} defaultSyntax default syntax used for "..."
752
+ * @param {(expr: CallExpression, isGlobalWorker?: boolean) => boolean | void} handle handler
753
+ * @param {symbol} specifierTag tag used for `*variable` syntax
754
+ */
755
+ const processList = (
756
+ syntaxList,
757
+ defaultSyntax,
758
+ handle,
759
+ specifierTag
760
+ ) => {
761
+ for (const item of syntaxList) {
762
+ if (item === "...") {
763
+ for (const itemFromDefault of defaultSyntax) {
764
+ processItem(itemFromDefault, handle, specifierTag);
765
+ }
766
+ } else {
767
+ processItem(item, handle, specifierTag);
586
768
  }
587
- } else {
588
- processItem(item);
589
769
  }
770
+ };
771
+
772
+ if (parserOptions.worker !== false) {
773
+ const workerSyntax = !Array.isArray(parserOptions.worker)
774
+ ? ["..."]
775
+ : parserOptions.worker;
776
+ processList(
777
+ workerSyntax,
778
+ WORKER_DEFAULT_SYNTAX,
779
+ handleNewWorker,
780
+ WorkerSpecifierTag
781
+ );
782
+ }
783
+
784
+ // Worklet parsing is opt-in: unset falls back to the `futureDefaults`
785
+ // default, `false` disables it. It is not defaulted in
786
+ // `config/defaults.js` because that would splice into the `"..."`
787
+ // merge sentinel of a user-provided list.
788
+ const workletOption =
789
+ parserOptions.worklet === undefined
790
+ ? this._workletDefault
791
+ : parserOptions.worklet;
792
+ if (workletOption) {
793
+ const workletSyntax = !Array.isArray(workletOption)
794
+ ? ["..."]
795
+ : workletOption;
796
+ processList(
797
+ workletSyntax,
798
+ WORKLET_DEFAULT_SYNTAX,
799
+ handleNewWorklet,
800
+ WorkletSpecifierTag
801
+ );
590
802
  }
591
803
  };
592
804
  normalModuleFactory.hooks.parser
@@ -600,4 +812,4 @@ class WorkerPlugin {
600
812
  }
601
813
  }
602
814
 
603
- module.exports = WorkerPlugin;
815
+ module.exports = WorkerAndWorkletPlugin;