@plaudit/webpack-extensions 2.94.1 → 2.96.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.
@@ -9,7 +9,7 @@ function convertToCSS(writableCSSObject, pretty = true) {
9
9
  return convertToCSSPretty(writableCSSObject, "");
10
10
  }
11
11
  else {
12
- return convertToCSS(writableCSSObject);
12
+ return convertToCSSUgly(writableCSSObject);
13
13
  }
14
14
  }
15
15
  function convertToCSSPretty(writableCSSObject, indentation) {
@@ -23,7 +23,7 @@ function convertToCSSPretty(writableCSSObject, indentation) {
23
23
  }
24
24
  else {
25
25
  res += " {\n";
26
- res += convertToCSSPretty(writableCSSObject, indentation + "\t");
26
+ res += convertToCSSPretty(value, indentation + "\t");
27
27
  res += indentation + "}\n";
28
28
  }
29
29
  }
@@ -39,7 +39,7 @@ function convertToCSSUgly(writableCSSObject) {
39
39
  res += `:${value};`;
40
40
  }
41
41
  else {
42
- res += "{" + convertToCSSUgly(writableCSSObject) + "}";
42
+ res += "{" + convertToCSSUgly(value) + "}";
43
43
  }
44
44
  }
45
45
  return res;
@@ -7,7 +7,7 @@ const node_path_1 = require("node:path");
7
7
  const shared_1 = require("../shared");
8
8
  function parseLocationEncodingFilename(filename) {
9
9
  const { name, ext } = (0, node_path_1.parse)(filename);
10
- if (name.startsWith("~")) {
10
+ if ((0, shared_1.shouldBeSkipped)(name)) {
11
11
  return undefined;
12
12
  }
13
13
  let type = /^\.(?:s[ac]|p?c)ss$/i.test(ext) ? 'style' : /^\.m[jt]sx?/i.test(ext) ? 'script-module' : /^\.[jt]sx?/i.test(ext) ? 'script' : false;
@@ -84,7 +84,7 @@ function parseLocationEncodingFilenameForBlock(filename, errorBuilder = shared_1
84
84
  const parsedFilename = parseLocationEncodingFilename(filename);
85
85
  if (parsedFilename !== undefined) {
86
86
  if ((0, shared_1.constantKeys)(parsedFilename.locations).some(value => value !== 'clientView' && value !== 'clientEditor')) {
87
- throw errorBuilder(`Block assets cannot be enqueued anywhere other than view, editor, or both. Saw: ${(0, shared_1.constantKeys)(parsedFilename).join(", ")}`, filename);
87
+ throw errorBuilder(`Block assets cannot be enqueued anywhere other than view, editor, or both. Saw: ${(0, shared_1.constantKeys)(parsedFilename.locations).join(", ")}`, filename);
88
88
  }
89
89
  if (Object.values(parsedFilename.locations).some(value => typeof value === 'number')) {
90
90
  throw errorBuilder(`Block assets cannot be enqueued with a priority`, filename);
@@ -15,7 +15,6 @@ export declare function unpackPotentiallyPrefixedFilePath(filePath: string): [st
15
15
  */
16
16
  export declare function unpackPathQuery(pathQuery: string): PathQueryParameters | undefined;
17
17
  export type LoadingStrategy = boolean | 'defer' | 'async' | 'eager' | 'lazy' | 'inline';
18
- export declare function isValidLoadingStrategy(strategy: any): strategy is LoadingStrategy | undefined;
19
18
  export declare function newInvalidLoadingStrategyError(strategy: unknown, file: string): import("webpack").WebpackError;
20
19
  export type InFooter = boolean;
21
20
  export declare function isValidInFooter(in_footer: unknown): in_footer is InFooter;
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getAssetFileContents = getAssetFileContents;
4
4
  exports.unpackPotentiallyPrefixedFilePath = unpackPotentiallyPrefixedFilePath;
5
5
  exports.unpackPathQuery = unpackPathQuery;
6
- exports.isValidLoadingStrategy = isValidLoadingStrategy;
7
6
  exports.newInvalidLoadingStrategyError = newInvalidLoadingStrategyError;
8
7
  exports.isValidInFooter = isValidInFooter;
9
8
  exports.newInvalidInFooterError = newInvalidInFooterError;
@@ -78,9 +77,6 @@ function unpackPathQuery(pathQuery) {
78
77
  }, {});
79
78
  }
80
79
  const namedStrategies = ['defer', 'async', 'eager', 'lazy', 'inline'];
81
- function isValidLoadingStrategy(strategy) {
82
- return strategy === undefined || (typeof strategy === 'string' && namedStrategies.includes(strategy));
83
- }
84
80
  function newInvalidLoadingStrategyError(strategy, file) {
85
81
  return (0, shared_1.newWebpackErrorForFile)(`The strategy was invalid. Received: ${strategy}, Expected: undefined|boolean|'${namedStrategies.join("'|'")}'`, file);
86
82
  }
@@ -0,0 +1,72 @@
1
+ import LegacyDependencyExtractionWebpackPlugin from "@wordpress/dependency-extraction-webpack-plugin";
2
+ import { Compilation, Compiler, Module, type TemplatePath } from "webpack";
3
+ export interface EnhancedDependencyExtractionWebpackPluginOptions {
4
+ injectPolyfill?: boolean;
5
+ useDefaults?: boolean;
6
+ outputFilename?: TemplatePath;
7
+ requestToExternal?: (request: string) => string | string[] | undefined;
8
+ requestToExternalModule?: (request: string) => string | boolean | undefined;
9
+ requestToHandle?: (request: string) => string | undefined;
10
+ requestToScriptModule?: (request: string) => string | boolean | Error | undefined;
11
+ externalizedReport?: string | boolean;
12
+ }
13
+ export declare class EnhancedDependencyExtractionWebpackPlugin {
14
+ /**
15
+ * Track requests that are externalized.
16
+ *
17
+ * Because we don't have a closed set of dependencies, we need to track what has
18
+ * been externalized so we can recognize them in a later phase when the dependency
19
+ * lists are generated.
20
+ */
21
+ private readonly externalizedDeps;
22
+ private readonly options;
23
+ /**
24
+ * Track requests that a script build externalizes as script modules.
25
+ *
26
+ * These can only be reached through a runtime `import()`, which requires
27
+ * support for dynamic import in the output environment. The set is used
28
+ * to report an actionable error when that support is missing.
29
+ */
30
+ private readonly scriptModuleDepsInScript;
31
+ /**
32
+ * Whether we should use modules. This will be set later to match webpack's `output.module` option.
33
+ */
34
+ private useModules;
35
+ constructor(options: EnhancedDependencyExtractionWebpackPluginOptions | LegacyDependencyExtractionWebpackPlugin | EnhancedDependencyExtractionWebpackPlugin);
36
+ /**
37
+ * Convert a script module request to an external suitable for a script
38
+ * build.
39
+ *
40
+ * A classic script cannot contain a static `import`, so the `module`
41
+ * external type is not usable here: the script module has to be reached
42
+ * through a runtime `import()`, which is the `import` external type. The
43
+ * bare specifier is resolved by the import map that WordPress prints for
44
+ * enqueued script modules.
45
+ *
46
+ * @param {string} request Original module request.
47
+ * @param {string|boolean|Error=} external Result of a script module external resolution.
48
+ * @return {string|undefined} The resulting external definition.
49
+ */
50
+ static toScriptModuleExternalInScript(request: string, external?: string | boolean | Error): string | undefined;
51
+ private readonly externalizeWpDeps;
52
+ /**
53
+ * @param {string} request
54
+ * @return {string} Mapped dependency name
55
+ */
56
+ protected mapRequestToDependency(request: string): string;
57
+ apply(compiler: Compiler): void;
58
+ /**
59
+ * Check for magic comments before minification, so minification doesn't have to preserve them.
60
+ */
61
+ checkForMagicComments(compilation: Compilation): void;
62
+ addAssets(compilation: Compilation): void;
63
+ private static readonly staticDepsCurrent;
64
+ private static readonly staticDepsCache;
65
+ /**
66
+ * Can we trace a line of static dependencies from an entry to a module
67
+ *
68
+ * @return {boolean} True if there is a static import path to the root
69
+ */
70
+ static hasStaticDependencyPathToRoot(compilation: Compilation, block: Module): boolean;
71
+ readonly addExternalizedDep: (value: string) => Set<string>;
72
+ }
@@ -0,0 +1,519 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EnhancedDependencyExtractionWebpackPlugin = void 0;
7
+ const dependency_extraction_webpack_plugin_1 = __importDefault(require("@wordpress/dependency-extraction-webpack-plugin"));
8
+ const webpack_1 = require("webpack");
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ const util_1 = require("./util");
13
+ const defaultExternalizedReportFileName = 'externalized-dependencies.json';
14
+ class EnhancedDependencyExtractionWebpackPlugin {
15
+ /**
16
+ * Track requests that are externalized.
17
+ *
18
+ * Because we don't have a closed set of dependencies, we need to track what has
19
+ * been externalized so we can recognize them in a later phase when the dependency
20
+ * lists are generated.
21
+ */
22
+ externalizedDeps = new Set();
23
+ options;
24
+ /**
25
+ * Track requests that a script build externalizes as script modules.
26
+ *
27
+ * These can only be reached through a runtime `import()`, which requires
28
+ * support for dynamic import in the output environment. The set is used
29
+ * to report an actionable error when that support is missing.
30
+ */
31
+ scriptModuleDepsInScript = new Set();
32
+ /**
33
+ * Whether we should use modules. This will be set later to match webpack's `output.module` option.
34
+ */
35
+ useModules = false;
36
+ constructor(options) {
37
+ if (options instanceof dependency_extraction_webpack_plugin_1.default) {
38
+ options = options.options;
39
+ }
40
+ if (options instanceof EnhancedDependencyExtractionWebpackPlugin) {
41
+ options = options.options;
42
+ }
43
+ this.options = {
44
+ externalizedReport: false,
45
+ injectPolyfill: false,
46
+ outputFilename: undefined,
47
+ useDefaults: true,
48
+ ...options
49
+ };
50
+ }
51
+ /**
52
+ * Convert a script module request to an external suitable for a script
53
+ * build.
54
+ *
55
+ * A classic script cannot contain a static `import`, so the `module`
56
+ * external type is not usable here: the script module has to be reached
57
+ * through a runtime `import()`, which is the `import` external type. The
58
+ * bare specifier is resolved by the import map that WordPress prints for
59
+ * enqueued script modules.
60
+ *
61
+ * @param {string} request Original module request.
62
+ * @param {string|boolean|Error=} external Result of a script module external resolution.
63
+ * @return {string|undefined} The resulting external definition.
64
+ */
65
+ static toScriptModuleExternalInScript(request, external) {
66
+ if (!external) {
67
+ return undefined;
68
+ }
69
+ if (external instanceof Error) {
70
+ throw external;
71
+ }
72
+ // The script module resolvers allow a boolean shorthand.
73
+ const target = external === true ? request : String(external);
74
+ return target.replace(/^module\s+/, 'import ');
75
+ }
76
+ externalizeWpDeps = ({ request }, callback) => {
77
+ let externalRequest;
78
+ let isScriptModule = false;
79
+ try {
80
+ // Handle via options.requestToExternal(Module) first.
81
+ if (this.useModules) {
82
+ if (typeof this.options.requestToExternalModule === 'function') {
83
+ const rawExternalRequest = this.options.requestToExternalModule(request);
84
+ // requestToExternalModule allows a boolean shorthand
85
+ if (rawExternalRequest === false) {
86
+ externalRequest = undefined;
87
+ }
88
+ else if (rawExternalRequest === true) {
89
+ externalRequest = request;
90
+ }
91
+ else {
92
+ externalRequest = rawExternalRequest;
93
+ }
94
+ }
95
+ }
96
+ else {
97
+ if (typeof this.options.requestToExternal === 'function') {
98
+ externalRequest = this.options.requestToExternal(request);
99
+ }
100
+ /*
101
+ * A script can depend on a script module, so fall back to
102
+ * `requestToScriptModule`. An explicit `requestToExternal`
103
+ * mapping wins: it describes a global that is known to exist.
104
+ *
105
+ * This deliberately does not consult `requestToExternalModule`:
106
+ * that option describes a module build, and the same options
107
+ * object is commonly shared by both builds.
108
+ */
109
+ if (typeof externalRequest === 'undefined' &&
110
+ typeof this.options.requestToScriptModule === 'function') {
111
+ externalRequest =
112
+ EnhancedDependencyExtractionWebpackPlugin.toScriptModuleExternalInScript(request, this.options.requestToScriptModule(request));
113
+ isScriptModule = Boolean(externalRequest);
114
+ }
115
+ }
116
+ // Cascade to default if unhandled and enabled.
117
+ if (typeof externalRequest === 'undefined' &&
118
+ this.options.useDefaults) {
119
+ if (this.useModules) {
120
+ externalRequest = (0, util_1.defaultRequestToExternalModule)(request);
121
+ }
122
+ else {
123
+ /*
124
+ * Prefer the script module: a request that is available as
125
+ * a script module is used as one, even when it is also
126
+ * registered as a script.
127
+ */
128
+ try {
129
+ externalRequest =
130
+ EnhancedDependencyExtractionWebpackPlugin.toScriptModuleExternalInScript(request, (0, util_1.defaultRequestToExternalModule)(request));
131
+ isScriptModule = Boolean(externalRequest);
132
+ }
133
+ catch {
134
+ /*
135
+ * `defaultRequestToExternalModule` throws for WordPress
136
+ * scripts, which is exactly what we want to fall back
137
+ * to here.
138
+ */
139
+ }
140
+ if (typeof externalRequest === 'undefined') {
141
+ externalRequest = (0, util_1.defaultRequestToExternal)(request);
142
+ }
143
+ }
144
+ }
145
+ }
146
+ catch (err) {
147
+ if (err instanceof Error) {
148
+ return callback(err);
149
+ }
150
+ throw err;
151
+ }
152
+ if (externalRequest) {
153
+ this.externalizedDeps.add(request);
154
+ if (isScriptModule) {
155
+ this.scriptModuleDepsInScript.add(request);
156
+ }
157
+ return callback(null, externalRequest);
158
+ }
159
+ return callback();
160
+ };
161
+ /**
162
+ * @param {string} request
163
+ * @return {string} Mapped dependency name
164
+ */
165
+ mapRequestToDependency(request) {
166
+ // Handle via options.requestToHandle first.
167
+ if (typeof this.options.requestToHandle === 'function') {
168
+ const scriptDependency = this.options.requestToHandle(request);
169
+ if (scriptDependency) {
170
+ return scriptDependency;
171
+ }
172
+ }
173
+ // Cascade to default if enabled.
174
+ if (this.options.useDefaults) {
175
+ const scriptDependency = (0, util_1.defaultRequestToHandle)(request);
176
+ if (scriptDependency) {
177
+ return scriptDependency;
178
+ }
179
+ }
180
+ // Fall back to the request name.
181
+ return request;
182
+ }
183
+ // noinspection JSUnusedGlobalSymbols
184
+ apply(compiler) {
185
+ this.useModules = Boolean(compiler.options.output?.module);
186
+ /**
187
+ * Offload externalization work to the ExternalsPlugin.
188
+ */
189
+ new webpack_1.ExternalsPlugin(this.useModules ? 'import' : 'window', this.externalizeWpDeps).apply(compiler);
190
+ compiler.hooks.thisCompilation.tap(this.constructor.name, (compilation) => {
191
+ compilation.hooks.processAssets.tap({
192
+ name: this.constructor.name,
193
+ stage: compiler.webpack.Compilation
194
+ .PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY,
195
+ }, () => this.checkForMagicComments(compilation));
196
+ compilation.hooks.processAssets.tap({
197
+ name: this.constructor.name,
198
+ stage: compiler.webpack.Compilation
199
+ .PROCESS_ASSETS_STAGE_ANALYSE,
200
+ }, () => this.addAssets(compilation));
201
+ });
202
+ }
203
+ /**
204
+ * Check for magic comments before minification, so minification doesn't have to preserve them.
205
+ */
206
+ checkForMagicComments(compilation) {
207
+ // Accumulate all entrypoint chunks, some of them shared
208
+ const entrypointChunks = new Set();
209
+ for (const entrypoint of compilation.entrypoints.values()) {
210
+ for (const chunk of entrypoint.chunks) {
211
+ entrypointChunks.add(chunk);
212
+ }
213
+ }
214
+ // Process each entrypoint chunk independently
215
+ for (const chunk of entrypointChunks) {
216
+ const chunkFiles = Array.from(chunk.files);
217
+ const jsExtensionRegExp = this.useModules ? /\.m?js$/i : /\.js$/i;
218
+ const chunkJSFile = chunkFiles.find((f) => jsExtensionRegExp.test(f));
219
+ if (!chunkJSFile) {
220
+ // There's no JS file in this chunk, no work for us. This is typically a `style.css` from cache group.
221
+ continue;
222
+ }
223
+ // Prepare to look for magic comments, in order to decide whether
224
+ // `wp-polyfill` is needed.
225
+ const processContentsForMagicComments = (content) => {
226
+ const magicComments = [];
227
+ if (content.includes('/* wp:polyfill */')) {
228
+ magicComments.push('wp-polyfill');
229
+ }
230
+ return magicComments;
231
+ };
232
+ // Go through the assets to process the sources.
233
+ // This allows us to look for magic comments.
234
+ for (const filename of chunkFiles.sort()) {
235
+ const asset = compilation.getAsset(filename);
236
+ const content = asset?.source.buffer();
237
+ const wpMagicComments = content ? processContentsForMagicComments(content) : [];
238
+ compilation.updateAsset(filename, (v) => v, {
239
+ wpMagicComments,
240
+ });
241
+ }
242
+ }
243
+ }
244
+ addAssets(compilation) {
245
+ const { externalizedReport, injectPolyfill, } = this.options;
246
+ /*
247
+ * A script reaches a script module through a runtime `import()`, so the
248
+ * output environment has to support it. Report this directly: webpack's
249
+ * own error for the underlying external does not explain the cause.
250
+ */
251
+ if (!this.useModules &&
252
+ this.scriptModuleDepsInScript.size &&
253
+ compilation.outputOptions.environment?.dynamicImport === false) {
254
+ compilation.errors.push(new webpack_1.WebpackError(`${this.constructor.name}: ${Array.from(this.scriptModuleDepsInScript)
255
+ .sort()
256
+ .join(', ')} can only be loaded from a script through a dynamic \`import()\`, but the output environment does not support it. ` +
257
+ "Set `target: 'browserslist'` with a browserslist configuration whose browsers support dynamic import (as @wordpress/scripts does), or set `output.environment.dynamicImport: true`."));
258
+ }
259
+ // Dump actually externalized dependencies to a report file.
260
+ if (externalizedReport) {
261
+ const externalizedReportFile = typeof externalizedReport === 'string' ? externalizedReport : defaultExternalizedReportFileName;
262
+ compilation.emitAsset(externalizedReportFile, new webpack_1.sources.RawSource(JSON.stringify(Array.from(this.externalizedDeps).sort())));
263
+ }
264
+ const combinedAssetsData = {};
265
+ const jsExtensionRegExp = this.useModules ? /\.m?js$/i : /\.js$/i;
266
+ // Accumulate all entrypoint chunks, some of them shared
267
+ const entrypointChunks = new Set();
268
+ /**
269
+ * Track the files of each entrypoint's JS-less chunks, typically styles
270
+ * extracted by a `style.css` cache group. Those chunks don't get an
271
+ * asset file of their own, but their content must contribute to the
272
+ * version hash of the entrypoint's entry chunk so that style-only
273
+ * changes still produce a new version.
274
+ */
275
+ const styleFilesByEntryChunk = new Map();
276
+ for (const entrypoint of compilation.entrypoints.values()) {
277
+ const entryChunk = entrypoint.getEntrypointChunk();
278
+ for (const chunk of entrypoint.chunks) {
279
+ entrypointChunks.add(chunk);
280
+ if (chunk === entryChunk ||
281
+ Array.from(chunk.files).some((f) => jsExtensionRegExp.test(f))) {
282
+ continue;
283
+ }
284
+ const styleFiles = styleFilesByEntryChunk.get(entryChunk) ?? new Set();
285
+ for (const file of chunk.files) {
286
+ styleFiles.add(file);
287
+ }
288
+ styleFilesByEntryChunk.set(entryChunk, styleFiles);
289
+ }
290
+ }
291
+ // Process each entrypoint chunk independently
292
+ for (const chunk of entrypointChunks) {
293
+ const chunkFiles = Array.from(chunk.files);
294
+ const chunkJSFile = chunkFiles.find((f) => jsExtensionRegExp.test(f));
295
+ if (!chunkJSFile) {
296
+ // There's no JS file in this chunk, no work for us. This is typically a `style.css` from cache group.
297
+ continue;
298
+ }
299
+ const chunkStaticDeps = new Set();
300
+ const chunkDynamicDeps = new Set();
301
+ const chunkScriptModuleStaticDeps = new Set();
302
+ const chunkScriptModuleDynamicDeps = new Set();
303
+ if (injectPolyfill) {
304
+ chunkStaticDeps.add('wp-polyfill');
305
+ }
306
+ /**
307
+ * @param {webpack.Module} m
308
+ * @param {boolean} [fromAsyncChunk] Module was found in an async chunk of the entry.
309
+ */
310
+ const processModule = (m, fromAsyncChunk) => {
311
+ const viableRequest = typeof m.request === 'string' && m.request !== '__REMOVE_ME__' ? m.request : m.userRequest;
312
+ if (viableRequest !== undefined && this.externalizedDeps.has(viableRequest)) {
313
+ if (this.useModules) {
314
+ // A static occurrence (in the entry chunk) wins.
315
+ if (fromAsyncChunk && chunkStaticDeps.has(viableRequest)) {
316
+ return;
317
+ }
318
+ // Externals in an async chunk are reached via a dynamic
319
+ // import by definition.
320
+ const isStatic = !fromAsyncChunk &&
321
+ EnhancedDependencyExtractionWebpackPlugin.hasStaticDependencyPathToRoot(compilation, m);
322
+ (isStatic ? chunkStaticDeps : chunkDynamicDeps).add(viableRequest);
323
+ }
324
+ else if (m instanceof webpack_1.ExternalModule && (m.externalType === 'import' || m.externalType === 'module')) {
325
+ // A static occurrence (in the entry chunk) wins.
326
+ if (fromAsyncChunk && chunkScriptModuleStaticDeps.has(viableRequest)) {
327
+ return;
328
+ }
329
+ // Externals in an async chunk are reached via a dynamic
330
+ // import by definition.
331
+ const isStatic = !fromAsyncChunk &&
332
+ EnhancedDependencyExtractionWebpackPlugin.hasStaticDependencyPathToRoot(compilation, m);
333
+ (isStatic ? chunkScriptModuleStaticDeps : chunkScriptModuleDynamicDeps).add(viableRequest);
334
+ }
335
+ else {
336
+ chunkStaticDeps.add(this.mapRequestToDependency(viableRequest));
337
+ }
338
+ }
339
+ };
340
+ const processChunkModules = (searchChunk, fromAsyncChunk) => {
341
+ for (const chunkModule of compilation.chunkGraph.getChunkModulesIterable(searchChunk)) {
342
+ if (chunkModule instanceof webpack_1.NormalModule || chunkModule instanceof webpack_1.ExternalModule) {
343
+ processModule(chunkModule, fromAsyncChunk);
344
+ }
345
+ if ((0, util_1.isConcatenatedModule)(chunkModule) && chunkModule.modules) {
346
+ // Loop through submodules of ConcatenatedModule.
347
+ for (const concatModule of chunkModule.modules) {
348
+ if (concatModule instanceof webpack_1.NormalModule || concatModule instanceof webpack_1.ExternalModule) {
349
+ processModule(concatModule, fromAsyncChunk);
350
+ }
351
+ }
352
+ }
353
+ }
354
+ };
355
+ processChunkModules(chunk);
356
+ /*
357
+ * Also search the entry's async chunks: webpack can code-split a
358
+ * dynamically imported external into its own chunk.
359
+ */
360
+ for (const group of chunk.groupsIterable) {
361
+ if (!(0, util_1.isEntrypoint)(group) || group.getEntrypointChunk() !== chunk) {
362
+ continue;
363
+ }
364
+ const seenGroups = new Set();
365
+ const groupQueue = [...group.getChildren()];
366
+ for (let childGroup = groupQueue.pop(); childGroup !== undefined; childGroup = groupQueue.pop()) {
367
+ if (!seenGroups.has(childGroup)) {
368
+ seenGroups.add(childGroup);
369
+ for (const asyncChunk of childGroup.chunks) {
370
+ processChunkModules(asyncChunk, true);
371
+ }
372
+ groupQueue.push(...childGroup.getChildren());
373
+ }
374
+ }
375
+ }
376
+ // Prepare to hash the sources. We can't just use
377
+ // `chunk.contentHash` because that's not updated when
378
+ // assets are minified. In practice the hash is updated by
379
+ // `RealContentHashPlugin` after minification, but it only modifies
380
+ // already-produced asset filenames and the updated hash is not
381
+ // available to plugins.
382
+ const { hashFunction, hashDigest, hashDigestLength } = compilation.outputOptions;
383
+ const hashBuilder = webpack_1.util.createHash(hashFunction);
384
+ // Prepare to look for magic comments in order to decide whether `wp-polyfill` is needed.
385
+ const handleMagicComments = (info) => {
386
+ if (info && info.includes('wp-polyfill')) {
387
+ chunkStaticDeps.add('wp-polyfill');
388
+ }
389
+ };
390
+ // Include the files of the entrypoint's JS-less sibling chunks,
391
+ // typically extracted styles, in the version hash so that
392
+ // style-only changes still produce a new version.
393
+ const filesToHash = [
394
+ ...new Set([
395
+ ...chunkFiles,
396
+ ...(styleFilesByEntryChunk.get(chunk) ?? []),
397
+ ]),
398
+ ];
399
+ // Go through the assets to process the sources.
400
+ // This allows us to generate hashes, as well as look for magic comments.
401
+ for (const filename of filesToHash.sort()) {
402
+ const asset = compilation.getAsset(filename);
403
+ if (asset) {
404
+ const content = asset.source.buffer();
405
+ hashBuilder.update(content);
406
+ handleMagicComments(asset.info.wpMagicComments);
407
+ }
408
+ }
409
+ // Finalise hash.
410
+ const contentHash = hashBuilder
411
+ .digest(hashDigest)
412
+ .slice(0, hashDigestLength);
413
+ const assetData = {
414
+ dependencies: [
415
+ // Sort these so we can produce a stable, stringified representation.
416
+ ...Array.from(chunkStaticDeps).sort(),
417
+ ...Array.from(chunkDynamicDeps)
418
+ .sort()
419
+ .map((id) => ({ id, import: 'dynamic' })),
420
+ ],
421
+ };
422
+ /*
423
+ * Merge the script module dependencies into a single list, keyed by
424
+ * script module ID, with an explicit import kind for each. This is
425
+ * the shape WordPress writes for its own assets.
426
+ */
427
+ const scriptModuleDeps = new Map();
428
+ for (const id of chunkScriptModuleDynamicDeps) {
429
+ scriptModuleDeps.set(id, 'dynamic');
430
+ }
431
+ // A static occurrence wins: the script cannot start without it.
432
+ for (const id of chunkScriptModuleStaticDeps) {
433
+ scriptModuleDeps.set(id, 'static');
434
+ }
435
+ if (scriptModuleDeps.size) {
436
+ assetData.module_dependencies = Array.from(scriptModuleDeps.keys())
437
+ // Sort these so we can produce a stable, stringified representation.
438
+ .sort()
439
+ .map((id) => ({
440
+ id,
441
+ import: scriptModuleDeps.get(id),
442
+ }));
443
+ }
444
+ assetData.version = contentHash;
445
+ if (this.useModules) {
446
+ assetData.type = 'module';
447
+ }
448
+ if (compilation.options?.optimization?.runtimeChunk !== false) {
449
+ // Sets the script handle for the shared runtime file so WordPress registers it only once when using the asset file.
450
+ assetData.handle =
451
+ compilation.name +
452
+ '-' +
453
+ chunkJSFile
454
+ .replace(/\\/g, '/')
455
+ .replace(jsExtensionRegExp, '');
456
+ }
457
+ combinedAssetsData[chunkJSFile] = assetData;
458
+ }
459
+ // Add source into compilation for webpack to trigger a phase re-run
460
+ compilation.emitAsset("assets.json", new webpack_1.sources.RawSource(JSON.stringify(combinedAssetsData, undefined, " ")), { "parsed-assets-json": combinedAssetsData });
461
+ }
462
+ static staticDepsCurrent = new WeakSet();
463
+ static staticDepsCache = new WeakMap();
464
+ /**
465
+ * Can we trace a line of static dependencies from an entry to a module
466
+ *
467
+ * @return {boolean} True if there is a static import path to the root
468
+ */
469
+ static hasStaticDependencyPathToRoot(compilation, block) {
470
+ const existingDepsCacheValue = EnhancedDependencyExtractionWebpackPlugin.staticDepsCache.get(block);
471
+ if (existingDepsCacheValue !== undefined) {
472
+ return existingDepsCacheValue;
473
+ }
474
+ if (EnhancedDependencyExtractionWebpackPlugin.staticDepsCurrent.has(block)) {
475
+ return false;
476
+ }
477
+ EnhancedDependencyExtractionWebpackPlugin.staticDepsCurrent.add(block);
478
+ const incomingConnections = [
479
+ ...compilation.moduleGraph.getIncomingConnections(block),
480
+ ].filter((connection) => {
481
+ // Library connections don't have a dependency, this is a root
482
+ return connection.dependency &&
483
+ // Entry dependencies are another root
484
+ connection.dependency.constructor.name !== 'EntryDependency';
485
+ });
486
+ // If we don't have non-entry, non-library incoming connections,
487
+ // we've reached a root of
488
+ if (!incomingConnections.length) {
489
+ EnhancedDependencyExtractionWebpackPlugin.staticDepsCache.set(block, true);
490
+ EnhancedDependencyExtractionWebpackPlugin.staticDepsCurrent.delete(block);
491
+ return true;
492
+ }
493
+ const staticDependentModules = incomingConnections.flatMap((connection) => {
494
+ const { dependency } = connection;
495
+ if (!dependency) {
496
+ return [];
497
+ }
498
+ const parentBlock = compilation.moduleGraph.getParentBlock(dependency);
499
+ return parentBlock && parentBlock.constructor.name !== webpack_1.AsyncDependenciesBlock.name
500
+ ? [compilation.moduleGraph.getParentModule(dependency)]
501
+ : [];
502
+ });
503
+ // All the dependencies were Async, the module was reached via a dynamic import
504
+ if (!staticDependentModules.length) {
505
+ EnhancedDependencyExtractionWebpackPlugin.staticDepsCache.set(block, false);
506
+ EnhancedDependencyExtractionWebpackPlugin.staticDepsCurrent.delete(block);
507
+ return false;
508
+ }
509
+ // Continue to explore any static dependencies
510
+ const result = staticDependentModules.some((parentStaticDependentModule) => {
511
+ return !!parentStaticDependentModule && EnhancedDependencyExtractionWebpackPlugin.hasStaticDependencyPathToRoot(compilation, parentStaticDependentModule);
512
+ });
513
+ EnhancedDependencyExtractionWebpackPlugin.staticDepsCache.set(block, result);
514
+ EnhancedDependencyExtractionWebpackPlugin.staticDepsCurrent.delete(block);
515
+ return result;
516
+ }
517
+ addExternalizedDep = this.externalizedDeps.add.bind(this.externalizedDeps);
518
+ }
519
+ exports.EnhancedDependencyExtractionWebpackPlugin = EnhancedDependencyExtractionWebpackPlugin;