@plaudit/webpack-extensions 3.20.2 → 3.21.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.
package/CHANGELOG.md CHANGED
@@ -5,55 +5,69 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.21.1] - 2026-09-04
9
+ ### Fixed
10
+ - The `inline` flag not getting picked up if it was set from within the webpack.config.js file
11
+ - Forward-port from `2.99.3`
12
+ - Inlined assets getting put in the registered assets list
13
+ - Forward-port from `2.99.3`
14
+ - An unnecessary call to `plaudit_webpack_extensions__resolve_base_uri` being emitted when a "registration" batch exclusively contains inlined assets
15
+ - Forward-port from `2.99.3`
16
+
17
+ ## [3.21.0] - 2026-09-03
18
+ ### Added
19
+ - Logic to associate inline scripts with non-inlined scripts that have the same handle for Plain entrypoints
20
+ - This is intended to make using the "inlined script that does early prep for a deferred script" pattern easier
21
+
8
22
  ## [3.20.2] - 2026-09-01
9
23
  ### Removed
10
24
  - The duplicated `isDistDevOutputPath` logic around the initialization of the `@plaudit/dev-webpack-plugin`
11
- - This comes from version `2.99.2`
25
+ - Forward-port from `2.99.2`
12
26
 
13
27
  ## [3.20.1] - 2026-08-26
14
28
  ### Internals
15
29
  - Updated to the 34.x line of `@wordpress/scripts`
16
- - This comes from version `2.99.1`
30
+ - Forward-port from `2.99.1`
17
31
  - Removed the `@types/wordpress` override
18
- - This comes from version `2.99.1`
32
+ - Forward-port from `2.99.1`
19
33
 
20
34
  ## [3.20.0] - 2026-08-24
21
35
  ### Added
22
36
  - Mixable versions of the `BiPhasicGroup...` plugins
23
- - This comes from version `2.99.0`
37
+ - Forward-port from `2.99.0`
24
38
  - Entrypoints to allow other code to reference some of the plugins and utilities
25
- - This comes from version `2.99.0`
39
+ - Forward-port from `2.99.0`
26
40
 
27
41
  ### Internals
28
42
  - Dropped unnecessary constructor parameters to make re-using the more general components easier
29
- - This comes from version `2.99.0`
43
+ - Forward-port from `2.99.0`
30
44
 
31
45
  ## [3.19.0] - 2026-08-18
32
46
  ### Added
33
47
  - Automatic sync of WordPress's bundled packages list
34
- - This comes from version `2.98.0`
48
+ - Forward-port from `2.98.0`
35
49
 
36
50
  ## [3.18.0] - 2026-08-18
37
51
  ### Added
38
52
  - David's improvements to build pipeline efficiency (Credit: David)
39
- - This comes from version `2.97.0`
53
+ - Forward-port from `2.97.0`
40
54
  - Support for David's `@plaudit/dev-webpack-plugin` (Credit: David)
41
- - This comes from version `2.97.0`
55
+ - Forward-port from `2.97.0`
42
56
 
43
57
  ### Changed
44
58
  - To Webpack's standard plugin interface (`WebpackPluginInstance`)
45
- - This comes from version `2.97.0`
59
+ - Forward-port from `2.97.0`
46
60
 
47
61
  ### Removed
48
62
  - Browsersync and its tests (Credit: David)
49
- - This comes from version `2.97.0`
63
+ - Forward-port from `2.97.0`
50
64
 
51
65
  ## [3.17.0] - 2026-08-18
52
66
  ### Added
53
67
  - A port of WordPress's Dependency Extraction Webpack Plugin because they keep breaking it
54
- - This comes from version `2.96.0`
68
+ - Forward-port from `2.96.0`
55
69
  - Warnings and additional info for entrypoints that are lazy-loaded and assigned to actual locations
56
- - This comes from version `2.96.0`
70
+ - Forward-port from `2.96.0`
57
71
  - An `externalize` that is not a string, an array, an object, or false is now rejected rather than silently ignored
58
72
  - This matches with what webpack's `output.library` config supports
59
73
 
@@ -73,7 +87,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
73
87
 
74
88
  ### Removed
75
89
  - `processTranslationConfigs` because it should not be used and didn't actually do anything
76
- - This comes from version `2.96.2`
90
+ - Forward-port from `2.96.2`
77
91
 
78
92
  ### Internals
79
93
  - Added more integration tests
@@ -82,9 +96,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
82
96
  ### Added
83
97
  - Logic so that files and directories with names equal to "example" or "examples" or that include "example" as a name segment are skipped
84
98
  - This is done to allow us to include example files
85
- - This comes from version `2.95.0`
99
+ - Forward-port from `2.95.0`
86
100
  - Updated the user guide with this information
87
- - This comes from version `2.95.0`
101
+ - Forward-port from `2.95.0`
88
102
 
89
103
  ### Fixed
90
104
  - The TOC in the user guide being out of date
@@ -92,25 +106,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
92
106
  ## [3.15.1] - 2026-07-20
93
107
  ### Fixed
94
108
  - A bug that caused all styles bound for editor use to be emitted as inline CSS
95
- - This comes from version `2.94.1`
109
+ - Forward-port from `2.94.1`
96
110
 
97
111
  ## [3.15.0] - 2026-07-17
98
112
  ### Changed
99
113
  - The `add_editor_style()` enqueue path to use `block_editor_settings_all` to avoid a litany of bugs courtesy of WordPress's high-quality code
100
- - This comes from version `2.94.0`
114
+ - Forward-port from `2.94.0`
101
115
 
102
116
  ## [3.14.1] - 2026-07-15
103
117
  ### Fixed
104
118
  - The new supported features code overriding unintended data in theme.json
105
- - This comes from version `2.93.1`
119
+ - Forward-port from `2.93.1`
106
120
 
107
121
  ## [3.14.0] - 2026-07-15
108
122
  ### Added
109
123
  - Logic to emit code that makes the supported features declared in block.json file the defaults for those blocks in the "theme.json" file
110
124
  - This uses filters to achieve the "defaulting", which means that it's plugin and theme agnostic
111
- - This comes from version `2.93.0`
125
+ - Forward-port from `2.93.0`
112
126
  - The `useBlockSupportsAsThemeJsonDefaults` flag to allow the new logic to be disabled
113
- - This comes from version `2.93.0`
127
+ - Forward-port from `2.93.0`
114
128
 
115
129
  ## [3.13.0] - 2026-07-14
116
130
  ### Added
@@ -162,45 +176,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
162
176
  ## [3.9.4] - 2026-06-10
163
177
  ### Fixed
164
178
  - Libraries externalizing in a way that does not account for the variable potentially being undeclared
165
- - This comes from version `2.92.4`
179
+ - Forward-port from `2.92.4`
166
180
 
167
181
  ## [3.9.3] - 2026-05-27
168
182
  ### Fixed
169
183
  - A couple more dependency snarls
170
- - This comes from version `2.92.3`
184
+ - Forward-port from `2.92.3`
171
185
 
172
186
  ## [3.9.2] - 2026-05-26
173
187
  ### Fixed
174
188
  - The `"supports-bindings": true` flag resulting in emission of invalid PHP code
175
- - This comes from version `2.92.2`
189
+ - Forward-port from `2.92.2`
176
190
 
177
191
  ## [3.9.1] - 2026-05-21
178
192
  ### Fixed
179
193
  - Compatibility issues with module-mode building
180
- - This comes from version `2.92.1`
194
+ - Forward-port from `2.92.1`
181
195
  - `module_dependencies` being set to `null` instead of being omitted
182
- - This comes from version `2.92.1`
196
+ - Forward-port from `2.92.1`
183
197
 
184
198
  ## [3.9.0] - 2026-05-20
185
199
  ### Added
186
200
  - Support for marking `block.json` attributes with `"supports-bindings": true` to enable block binding support in the editor
187
- - This comes from version `2.92.0`
201
+ - Forward-port from `2.92.0`
188
202
 
189
203
  ## [3.8.0] - 2026-05-20
190
204
  ### Added
191
205
  - Support for the `module_dependencies` property on `script` assets
192
- - This comes from version `2.91.0`
206
+ - Forward-port from `2.91.0`
193
207
 
194
208
  ## [3.7.0] - 2026-05-04
195
209
  ### Added
196
210
  - PNPM 11 compatibility
197
- - This comes from version `2.90.0`
211
+ - Forward-port from `2.90.0`
198
212
 
199
213
  ## [3.6.3] - 2026-04-27
200
214
  ### Fixed
201
215
  - An `ENOENT` error when the `srcDir` does not map to an actual directory on disk
202
216
  - It now matches the behavior of manually-declared sources and exits due to not having anything to build
203
- - This comes from version `2.89.2`
217
+ - Forward-port from `2.89.2`
204
218
 
205
219
  ## [3.6.2] - 2026-04-09
206
220
  ### Changed
@@ -209,44 +223,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
209
223
  ## [3.6.1] - 2026-04-06
210
224
  ### Fixed
211
225
  - The emitter for the Extensions v1 format including an extra path element
212
- - This comes from version `2.89.1`
226
+ - Forward-port from `2.89.1`
213
227
 
214
228
  ## [3.6.0] - 2026-03-31
215
229
  ### Changed
216
230
  - The block.json handling logic to use encoded location data in filenames that are enumerated within block.json
217
- - This comes from version `2.89.0`
231
+ - Forward-port from `2.89.0`
218
232
  - Inline scripts to not emit with a sourcemap outside of dev mode
219
- - This comes from version `2.89.0`
233
+ - Forward-port from `2.89.0`
220
234
 
221
235
  ### Fixed
222
236
  - Unnecessary `.asset.php` files being emitted for inlined scripts
223
- - This comes from version `2.89.0`
237
+ - Forward-port from `2.89.0`
224
238
 
225
239
  ## [3.5.2] - 2026-03-30
226
240
  ### Fixed
227
241
  - The conflicting handle detection logic in block.json handling
228
- - This comes from version `2.88.2`
242
+ - Forward-port from `2.88.2`
229
243
 
230
244
  ## [3.5.1] - 2026-03-30
231
245
  ### Fixed
232
246
  - The paths in package.json that were broken after switching to dist
233
- - This comes from version `2.88.1`
247
+ - Forward-port from `2.88.1`
234
248
 
235
249
  ## [3.5.0] - 2026-03-30
236
250
  ### Added
237
251
  - Support for explicitly setting the handle for block assets
238
- - This comes from version `2.88.0`
252
+ - Forward-port from `2.88.0`
239
253
 
240
254
  ## [3.4.1] - 2026-03-17
241
255
  ### Changed
242
256
  - The `blockdir-loader.php` generation logic to use static wp_register_* calls like `plain-entrypoints-loader.php`
243
- - This comes from version `2.87.1`
257
+ - Forward-port from `2.87.1`
244
258
 
245
259
  ## [3.4.0] - 2026-03-16
246
260
  ### Added
247
261
  - Support for a directory-based `extensions` layout
248
262
  - This only applies to sites using extensions v2 and higher
249
- - This comes from version `2.87.0`
263
+ - Forward-port from `2.87.0`
250
264
 
251
265
  ## [3.3.0] - 2026-03-16
252
266
  ### Added
@@ -263,25 +277,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
263
277
  ## [3.2.0] - 2026-03-16
264
278
  ### Added
265
279
  - Support for `Location-Encoding Filenames`
266
- - This comes from version `2.86.0`
280
+ - Forward-port from `2.86.0`
267
281
  - Support for standardized flag sets
268
- - This comes from version `2.86.0`
282
+ - Forward-port from `2.86.0`
269
283
 
270
284
  ## [3.1.2] - 2026-03-06
271
285
  ### Fixed
272
286
  - `defer` and `async` not being supported strategies in some pipelines
273
- - This comes from version `2.85.3`
287
+ - Forward-port from `2.85.3`
274
288
 
275
289
  ## [3.1.1] - 2026-03-06
276
290
  ### Fixed
277
291
  - Inlined scripts without any other path query parameters not being placed in the footer by default
278
- - This comes from version `2.85.2`
292
+ - Forward-port from `2.85.2`
279
293
 
280
294
  ## [3.1.0] - 2026-03-05
281
295
  ### Added
282
296
  - Support for inlining (and otherwise controlling the enqueuing of) assets
283
297
  - This only applies to plain entrypoints and assets declared within block.json files at present
284
- - This comes from version `2.85.0`
298
+ - Forward-port from `2.85.0`
285
299
 
286
300
  ## [3.0.1] - 2026-02-12
287
301
  ### Added
@@ -303,6 +317,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
303
317
  - Legacy PostCSS features that have been integrated into modern CSS
304
318
  - `@extends` support
305
319
 
320
+ ## [2.99.3] - 2026-09-04
321
+ ### Fixed
322
+ - The `inline` flag not getting picked up if it was set from within the webpack.config.js file
323
+ - Inlined assets getting put in the registered assets list
324
+ - An unnecessary call to `plaudit_webpack_extensions__resolve_base_uri` being emitted when a "registration" batch exclusively contains inlined assets
325
+
326
+ ### Internals
327
+ - Tweaked a few things to make adding new enqueue locations easier
328
+
306
329
  ## [2.99.2] - 2026-09-01
307
330
  ### Removed
308
331
  - The duplicated `isDistDevOutputPath` logic around the initialization of the `@plaudit/dev-webpack-plugin`
@@ -10,6 +10,8 @@ export declare class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractB
10
10
  private static readonly semaphore;
11
11
  constructor(config: VerifiedPlauditWordpressWebpackConfig, buildRoot: string, outputDir: string, dest: VerifiedAdvancedOutputConfig, useUnifiedLoader: boolean, context: string, entry: EntryProvider<BlockEntrypointInfo>);
12
12
  private generatePlainEntrypointsLoader;
13
+ private static writeHandleItem;
14
+ private static collatePotentiallyMergeableAssets;
13
15
  private static addHandlesToHandleLists;
14
16
  private static appendEnqueuingHandleLists;
15
17
  private static separateHandleListByPriority;
@@ -32,29 +32,12 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
32
32
  inline: [],
33
33
  ...Object.fromEntries((0, shared_1.constantKeys)(shared_1.standardLocationNamesMeta).map(sln => [sln, []]))
34
34
  };
35
- const usedHandleNames = { script: {}, script_module: {}, style: {} };
36
- const plainEntrypointsConfig = { scriptHandles: {}, script_moduleHandles: {}, styleHandles: {} };
37
- for (const { handles, handlePrefix } of assets) {
38
- for (const { src, rest, locations, type, handleName, lazyLoader, ...otherProps } of handles) {
39
- const cleanBasename = (0, node_path_1.basename)(src).replace(/_(?:script(?:-\d+)?\.js|style(?:-\d+)?\.css)$|(?<!_(script|style))\.(js|css)$/, "");
40
- let finalHandleName;
41
- const handleNameMap = usedHandleNames[type];
42
- const baseFinalHandleName = finalHandleName = (0, shared_1.convertUsageLocationsHandleToEmittableHandle)({ niceName: (0, shared_1.kebabCase)(cleanBasename) }, handlePrefix, cleanBasename);
43
- for (let count = 0; finalHandleName in handleNameMap && handleNameMap[finalHandleName] !== src;) {
44
- finalHandleName = `${baseFinalHandleName}-${++count}`;
45
- }
46
- if (handleName !== undefined) {
47
- finalHandleName = (0, shared_1.convertUsageLocationsHandleToEmittableHandle)(handleName, handlePrefix, finalHandleName.substring(handlePrefix.length + 1));
48
- }
49
- handleNameMap[finalHandleName] = src;
50
- plainEntrypointsConfig[`${type}Handles`][finalHandleName] = { src, rest, locations, type, lazyLoader, ...otherProps };
51
- }
52
- }
53
- PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists(compilation, 'script', Object.entries(plainEntrypointsConfig.scriptHandles)
35
+ const plainEntrypointsConfig = PlainEntrypointsConfigFileGeneratorPlugin.collatePotentiallyMergeableAssets(assets);
36
+ PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists(compilation, 'script', plainEntrypointsConfig.scriptHandles
54
37
  .toSorted(([a], [b]) => a.localeCompare(b)), handleLists);
55
- PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists(compilation, 'script_module', Object.entries(plainEntrypointsConfig.script_moduleHandles)
38
+ PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists(compilation, 'script_module', plainEntrypointsConfig.script_moduleHandles
56
39
  .toSorted(([a], [b]) => a.localeCompare(b)), handleLists);
57
- const sortedStyleHandles = Object.entries(plainEntrypointsConfig.styleHandles)
40
+ const sortedStyleHandles = plainEntrypointsConfig.styleHandles
58
41
  .toSorted(([a], [b]) => a.localeCompare(b));
59
42
  PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists(compilation, 'style', sortedStyleHandles, handleLists);
60
43
  const callItemSorter = (a, b) => a.handle.localeCompare(b.handle);
@@ -63,32 +46,25 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
63
46
  }
64
47
  const file = new php_writer_1.PHPFile();
65
48
  const writer = file.getWriter("");
66
- if (handleLists.register.length > 0) {
67
- if (!this.useUnifiedLoader) {
49
+ const hasRegisterScripts = handleLists.register.length > 0;
50
+ if (hasRegisterScripts || handleLists.inline.length > 0) {
51
+ if (hasRegisterScripts && !this.useUnifiedLoader) {
68
52
  (0, shared_1.emitResolveBaseUriFunction)(writer);
69
53
  }
70
54
  const baseUriVar = new expressions_1.Var("base_uri");
71
- for (const [priority, prioritizedHandleList] of PlainEntrypointsConfigFileGeneratorPlugin.separateHandleListByPriority(handleLists.register)) {
55
+ const inlineAndRegisterHandleLists = [...handleLists.register, ...handleLists.inline];
56
+ for (const [priority, prioritizedHandleList] of PlainEntrypointsConfigFileGeneratorPlugin.separateHandleListByPriority(inlineAndRegisterHandleLists)) {
72
57
  writer.action("init", writer => {
73
- writer.call("plaudit_webpack_extensions__resolve_base_uri", [expressions_1.Constants.__DIR__], { assignTo: baseUriVar });
74
- for (const { handle, type, data } of prioritizedHandleList) {
75
- if (data.inlinedAsset !== undefined) {
76
- writer.call(`wp_register_${type}`, [handle, false, ...data.rest]);
77
- (0, shared_1.appendAddInlineAssetCall)(compilation, writer, handle, type, data);
78
- }
79
- else {
80
- writer.call(`wp_register_${type}`, [handle, expressions_1.Op.concat(baseUriVar, (0, node_path_1.relative)(emitDir, data.src)), ...data.rest]);
81
- }
58
+ const state = { baseUriVar, emitDir, writer };
59
+ if (prioritizedHandleList.find(handleItem => handleItem.data.inlinedAsset === undefined)) {
60
+ writer.call("plaudit_webpack_extensions__resolve_base_uri", [expressions_1.Constants.__DIR__], { assignTo: baseUriVar });
82
61
  }
83
- }, { priority, accountForAlreadyDoing: this.config.includePostInitFallback });
84
- }
85
- for (const [priority, prioritizedHandleList] of PlainEntrypointsConfigFileGeneratorPlugin.separateHandleListByPriority(handleLists.inline)) {
86
- writer.action("init", writer => {
87
- writer.call("plaudit_webpack_extensions__resolve_base_uri", [expressions_1.Constants.__DIR__], { assignTo: baseUriVar });
88
- for (const { handle, type, data } of prioritizedHandleList) {
89
- writer.call(`wp_register_${type}`, [handle, false, ...data.rest]);
90
- if (data.inlinedAsset !== undefined) {
91
- (0, shared_1.appendAddInlineAssetCall)(compilation, writer, handle, type, data);
62
+ for (const handleItem of prioritizedHandleList) {
63
+ PlainEntrypointsConfigFileGeneratorPlugin.writeHandleItem(compilation, handleItem, state);
64
+ if (handleItem.data.associatedInlinedHandles !== undefined) {
65
+ for (const associatedHandle of handleItem.data.associatedInlinedHandles) {
66
+ PlainEntrypointsConfigFileGeneratorPlugin.writeHandleItem(compilation, { data: associatedHandle, handle: handleItem.handle, type: associatedHandle.type }, state);
67
+ }
92
68
  }
93
69
  }
94
70
  }, { priority, accountForAlreadyDoing: this.config.includePostInitFallback });
@@ -138,15 +114,88 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
138
114
  }
139
115
  (0, shared_1.emitPHPWriterAsAsset)(file, compilation, "plain-entrypoints-loader.php");
140
116
  }
117
+ static writeHandleItem(compilation, { data, handle, type }, { baseUriVar, emitDir, writer }) {
118
+ if (data.inlinedAsset !== undefined) {
119
+ if (!data.inlinedAsset.omitRegistration) {
120
+ writer.call(`wp_register_${type}`, [handle, false, ...data.rest]);
121
+ }
122
+ (0, shared_1.appendAddInlineAssetCall)(compilation, writer, handle, type, data);
123
+ }
124
+ else {
125
+ writer.call(`wp_register_${type}`, [handle, expressions_1.Op.concat(baseUriVar, (0, node_path_1.relative)(emitDir, data.src)), ...data.rest]);
126
+ }
127
+ }
128
+ static collatePotentiallyMergeableAssets(assets) {
129
+ const collatedHandles = { scriptHandles: {}, script_moduleHandles: {}, styleHandles: {} };
130
+ for (const { handles, handlePrefix } of assets) {
131
+ for (const { src, rest, locations, type, handleName, lazyLoader, ...otherProps } of handles) {
132
+ const cleanBasename = (0, node_path_1.basename)(src).replace(/_(?:script(?:-\d+)?\.js|style(?:-\d+)?\.css)$|(?<!_(script|style))\.(js|css)$/, "");
133
+ let finalHandleName = (0, shared_1.convertUsageLocationsHandleToEmittableHandle)({ niceName: (0, shared_1.kebabCase)(cleanBasename) }, handlePrefix, cleanBasename);
134
+ if (handleName !== undefined) {
135
+ finalHandleName = (0, shared_1.convertUsageLocationsHandleToEmittableHandle)(handleName, handlePrefix, finalHandleName.substring(handlePrefix.length + 1));
136
+ }
137
+ (collatedHandles[`${type}Handles`][finalHandleName] ??= []).push({ src, rest, locations, type, lazyLoader, ...otherProps });
138
+ }
139
+ }
140
+ const plainEntrypointsConfig = { scriptHandles: [], script_moduleHandles: [], styleHandles: [] };
141
+ for (const key of ['scriptHandles', 'script_moduleHandles', 'styleHandles']) {
142
+ for (const [baseFinalHandleName, handles] of Object.entries(collatedHandles[key])) {
143
+ if ((0, shared_1.arrayIsLength)(handles, 1)) {
144
+ plainEntrypointsConfig[key].push([baseFinalHandleName, handles[0]]);
145
+ }
146
+ else if ((0, shared_1.hasAtLeastOneItem)(handles)) {
147
+ const inlinedHandles = handles.filter(item => item.inlinedAsset !== undefined);
148
+ if (inlinedHandles.length === 0) {
149
+ plainEntrypointsConfig[key].push([baseFinalHandleName, handles[0]]);
150
+ let count = 1;
151
+ for (const handle of handles.slice(1)) {
152
+ plainEntrypointsConfig[key].push([`${baseFinalHandleName}-${count++}`, handle]);
153
+ }
154
+ }
155
+ else {
156
+ const emittedHandles = handles.filter(item => item.inlinedAsset === undefined);
157
+ inlinedHandlesLoop: for (const inlinedHandle of inlinedHandles) {
158
+ for (const emittedHandle of emittedHandles) {
159
+ const canMerge = (0, shared_1.canMergeHandles)(emittedHandle, inlinedHandle);
160
+ if (!canMerge) {
161
+ continue;
162
+ }
163
+ if ((0, shared_1.hasDeferringStrategy)(emittedHandle)) {
164
+ inlinedHandle.inlinedAsset.position = 'before';
165
+ }
166
+ if (canMerge === 'dependent') {
167
+ emittedHandle.rest[0].push(`${baseFinalHandleName}-${emittedHandles.length}`);
168
+ emittedHandles.push(inlinedHandle);
169
+ }
170
+ else {
171
+ (emittedHandle.associatedInlinedHandles ??= []).push(inlinedHandle);
172
+ }
173
+ continue inlinedHandlesLoop;
174
+ }
175
+ emittedHandles.push(inlinedHandle);
176
+ }
177
+ if ((0, shared_1.hasAtLeastOneItem)(emittedHandles)) {
178
+ plainEntrypointsConfig[key].push([baseFinalHandleName, emittedHandles[0]]);
179
+ let count = 1;
180
+ for (const handle of emittedHandles.slice(1)) {
181
+ plainEntrypointsConfig[key].push([`${baseFinalHandleName}-${count++}`, handle]);
182
+ }
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
+ return plainEntrypointsConfig;
189
+ }
141
190
  static addHandlesToHandleLists(compilation, type, handles, handleLists) {
142
191
  const defaultPriority = 10;
143
192
  for (const [handle, data] of handles) {
144
- if (data.locations.register !== false) {
145
- handleLists.register.push({ handle, type, data, priority: typeof data.locations.register === 'number' ? data.locations.register : 10 });
146
- }
147
- else if (data.inlinedAsset !== undefined) {
193
+ if (data.inlinedAsset !== undefined) {
148
194
  handleLists.inline.push({ handle, type, data, priority: typeof data.locations.inline === 'number' ? data.locations.inline : 10 });
149
195
  }
196
+ else if (data.locations.register !== false) {
197
+ handleLists.register.push({ handle, type, data, priority: typeof data.locations.register === 'number' ? data.locations.register : 10 });
198
+ }
150
199
  if (data.lazyLoader !== undefined) {
151
200
  // A lazily loaded handle is enqueued by its generated function and never by an action, so it
152
201
  // is deliberately kept out of the location lists. Those lists are also what the lazy function
@@ -203,7 +252,7 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
203
252
  }
204
253
  }
205
254
  static appendEnqueuingHandleLists(writer, handleLists) {
206
- for (const [sln, { action, supports_hook_name, additional_action_code }] of (0, shared_1.constantEntries)(shared_1.standardLocationNamesMeta)) {
255
+ for (const [sln, { action, supports_hook_name, additional_action_code }] of (0, shared_1.iterableStandardLocationNamesMeta)()) {
207
256
  const handleList = handleLists[sln];
208
257
  if (handleList.length > 0) {
209
258
  writer.linebreak();
@@ -214,7 +263,7 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
214
263
  const hook_name_var = new expressions_1.Var("hook_name", "?string");
215
264
  writer.action(action, writer => {
216
265
  additional_action_code?.before?.(writer);
217
- if (hookNamedHandleLists.global) {
266
+ if (hookNamedHandleLists.global.length > 0) {
218
267
  for (const handle of hookNamedHandleLists.global) {
219
268
  writer.call(`wp_enqueue_${handle.type}`, [handle.handle]);
220
269
  }
@@ -315,7 +364,7 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
315
364
  const { dependencies = [], module_dependencies = undefined } = isScript === entrypointChunkIsScript ? assetData : {};
316
365
  const { lazyLoader, locations } = this.dest;
317
366
  const { flags } = (0, path_query_and_related_helpers_1.unpackEnqueuingControlFlagsFromPathQueryParameters)(typeof locations.registerScriptArgs === 'object' ? locations.registerScriptArgs : { strategy: locations.registerScriptArgs }, file, "registerScriptArgs");
318
- const { assetMeta, scriptArgsObject } = (0, path_query_and_related_helpers_1.convertEnqueuingControlFlagsToScriptArgsObject)(compilation, file, (0, path_query_and_related_helpers_1.mergeTwoEnqueuingControlFlagSets)(file, flags, this.dest.enqueuingFlags), type === 'style' && (!!locations.clientEditor || locations.clientEditor === 0));
367
+ const { assetMeta, scriptArgsObject } = (0, path_query_and_related_helpers_1.convertEnqueuingControlFlagsToScriptArgsObject)(compilation, file, (0, path_query_and_related_helpers_1.mergeTwoEnqueuingControlFlagSets)(file, flags, this.dest.enqueuingFlags, this.dest.locations.inline !== undefined ? { inline: true } : undefined), type === 'style' && (!!locations.clientEditor || locations.clientEditor === 0));
319
368
  const completeScriptArgsObject = module_dependencies?.length ? { ...scriptArgsObject, module_dependencies } : scriptArgsObject;
320
369
  const rest = isScript && completeScriptArgsObject !== undefined ? [dependencies, assetData.version, completeScriptArgsObject] : [dependencies, assetData.version];
321
370
  const destPath = (0, node_path_1.join)(compilation.outputOptions.path, file);
package/dist/shared.d.ts CHANGED
@@ -35,21 +35,33 @@ export type ScriptArgsObject = {
35
35
  };
36
36
  export type InlinedAsset = {
37
37
  position?: 'before' | 'after';
38
+ omitRegistration?: boolean;
38
39
  };
39
40
  export type IAHandleData = BaseHandleData & AssetMetaSegment;
40
41
  export type HandleData = BaseHandleData & (AssetMetaSegment | {
41
42
  inlinedAsset?: undefined;
42
43
  assetContents?: string;
43
44
  });
45
+ type OptionalLocationMeta = {
46
+ supports_hook_name?: boolean;
47
+ additional_action_code?: {
48
+ before?(writer: PHPWriter): unknown;
49
+ after?(writer: PHPWriter): unknown;
50
+ };
51
+ alternate_names?: [string, ...string[]];
52
+ };
44
53
  export declare const standardLocationNamesMeta: {
45
54
  readonly clientView: {
46
55
  readonly action: "wp_enqueue_scripts";
56
+ readonly alternate_names: ["client-view", "view"];
47
57
  };
48
58
  readonly clientEditor: {
49
59
  readonly action: "enqueue_block_editor_assets";
60
+ readonly alternate_names: ["client-editor", "editor"];
50
61
  };
51
62
  readonly blockAssets: {
52
63
  readonly action: "enqueue_block_assets";
64
+ readonly alternate_names: ["block-assets"];
53
65
  };
54
66
  readonly admin: {
55
67
  readonly action: "admin_enqueue_scripts";
@@ -67,14 +79,11 @@ export declare const standardLocationNamesMeta: {
67
79
  };
68
80
  export type StandardLocationNameMeta = {
69
81
  action: typeof standardLocationNamesMeta[keyof typeof standardLocationNamesMeta]['action'];
70
- supports_hook_name?: boolean;
71
- additional_action_code?: {
72
- before?(writer: PHPWriter): unknown;
73
- after?(writer: PHPWriter): unknown;
74
- };
75
- };
82
+ } & OptionalLocationMeta;
76
83
  export type StandardLocationNames = keyof typeof standardLocationNamesMeta;
77
84
  export declare function isStandardLocationName(name: string): name is StandardLocationNames;
85
+ export declare function iterableStandardLocationNamesMeta(): [StandardLocationNames, StandardLocationNameMeta][];
86
+ export declare function normalizeLocationName(name: string): StandardLocationNames | 'register';
78
87
  type LocationWithHookNameSupport = boolean | number | string | string[] | {
79
88
  hook_name?: string | string[];
80
89
  priority?: number;
@@ -98,6 +107,20 @@ export type NormalizedUsageLocations = Omit<UsageLocations, 'registerScriptArgs'
98
107
  registerScriptArgs?: InputRegisterScriptArgs;
99
108
  };
100
109
  export declare function isNormalizedUsageLocations(usageLocations: UsageLocations): usageLocations is NormalizedUsageLocations;
110
+ export type EnqueuedAssetType = 'script' | 'script_module' | 'style';
111
+ export type ExtendedHandleData = HandleData & {
112
+ locations: UsageLocations;
113
+ handleName?: UsageLocations['handle'];
114
+ lazyLoader: string | undefined;
115
+ type: EnqueuedAssetType;
116
+ associatedInlinedHandles?: ExtendedHandleData[];
117
+ };
118
+ export declare function convertHookLocationToNamesAndPriority(hookLocation: NonNullable<Exclude<UsageLocations[keyof typeof standardLocationNamesMeta], false>>): [string[], number];
119
+ export declare function hasDeferringStrategy(handle: HandleData): boolean;
120
+ /**
121
+ * @return {@code true} -> "can share the same handle", {@code false} -> "cannot be merged", {@code 'dependent'} -> "one handle can be listed as a dependency of the other"
122
+ */
123
+ export declare function canMergeHandles(handleA: ExtendedHandleData, handleB: ExtendedHandleData): boolean | 'dependent';
101
124
  export declare function constantKeys<K extends string, V>(object: {
102
125
  [k in K]?: V;
103
126
  }): K[];
@@ -273,7 +296,7 @@ export declare function resolveLegacyBlockScriptsInFolder(folder: string): strin
273
296
  * @param type 'script_module' is NOT supported at this time; however, it is *handled* in this function
274
297
  * @param handleData
275
298
  */
276
- export declare function appendAddInlineAssetCall(compilation: Compilation, writer: PHPWriter, handle: string, type: 'script' | 'style' | 'script_module', handleData: IAHandleData): void;
299
+ export declare function appendAddInlineAssetCall(compilation: Compilation, writer: PHPWriter, handle: string, type: EnqueuedAssetType, handleData: IAHandleData): void;
277
300
  export declare function wrapInlineAssetContents(compilation: Compilation, wrapperIdPrefix: string, handle: string, contents: string): HereOrNowDoc;
278
301
  export declare function synchronousDirIterator(dirPath: string): Generator<import("node:fs").Dirent<string>, void, unknown>;
279
302
  /**
package/dist/shared.js CHANGED
@@ -20,8 +20,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
20
20
  exports.styleExtension = exports.scriptWithModuleExtension = exports.scriptWithoutModuleExtension = exports.scriptExtension = exports.entrypointFields = exports.standardLocationNamesMeta = void 0;
21
21
  exports.isParsedAssetsJson = isParsedAssetsJson;
22
22
  exports.isStandardLocationName = isStandardLocationName;
23
+ exports.iterableStandardLocationNamesMeta = iterableStandardLocationNamesMeta;
24
+ exports.normalizeLocationName = normalizeLocationName;
23
25
  exports.isRegisterScriptArgsShorthandName = isRegisterScriptArgsShorthandName;
24
26
  exports.isNormalizedUsageLocations = isNormalizedUsageLocations;
27
+ exports.convertHookLocationToNamesAndPriority = convertHookLocationToNamesAndPriority;
28
+ exports.hasDeferringStrategy = hasDeferringStrategy;
29
+ exports.canMergeHandles = canMergeHandles;
25
30
  exports.constantKeys = constantKeys;
26
31
  exports.constantEntries = constantEntries;
27
32
  exports.determineCurrentSourceType = determineCurrentSourceType;
@@ -76,9 +81,9 @@ function isParsedAssetsJson(thing) {
76
81
  return true;
77
82
  }
78
83
  exports.standardLocationNamesMeta = {
79
- clientView: { action: "wp_enqueue_scripts" },
80
- clientEditor: { action: "enqueue_block_editor_assets" },
81
- blockAssets: { action: "enqueue_block_assets" },
84
+ clientView: { action: "wp_enqueue_scripts", alternate_names: ['client-view', 'view'] },
85
+ clientEditor: { action: "enqueue_block_editor_assets", alternate_names: ['client-editor', 'editor'] },
86
+ blockAssets: { action: "enqueue_block_assets", alternate_names: ['block-assets'] },
82
87
  admin: { action: "admin_enqueue_scripts", supports_hook_name: true },
83
88
  login: { action: "login_enqueue_scripts" },
84
89
  customizer: { action: "customize_controls_enqueue_scripts" },
@@ -87,12 +92,115 @@ exports.standardLocationNamesMeta = {
87
92
  function isStandardLocationName(name) {
88
93
  return Object.hasOwn(exports.standardLocationNamesMeta, name);
89
94
  }
95
+ function iterableStandardLocationNamesMeta() {
96
+ return constantEntries(exports.standardLocationNamesMeta);
97
+ }
98
+ function normalizeLocationName(name) {
99
+ if (isStandardLocationName(name) || name === 'register') {
100
+ return name;
101
+ }
102
+ for (const [standardName, { alternate_names }] of iterableStandardLocationNamesMeta()) {
103
+ if (alternate_names?.includes(name)) {
104
+ return standardName;
105
+ }
106
+ }
107
+ throw new Error(`"${name}" is neither a standard nor alternate location name`);
108
+ }
90
109
  function isRegisterScriptArgsShorthandName(name) {
91
110
  return ['lazy', 'eager', 'inline'].includes(name);
92
111
  }
93
112
  function isNormalizedUsageLocations(usageLocations) {
94
113
  return typeof usageLocations.registerScriptArgs !== 'string';
95
114
  }
115
+ function convertHookLocationToNamesAndPriority(hookLocation) {
116
+ if (typeof hookLocation === 'string') {
117
+ return [[hookLocation], 10];
118
+ }
119
+ if (typeof hookLocation === 'number') {
120
+ return [[], hookLocation];
121
+ }
122
+ if (typeof hookLocation === 'boolean') {
123
+ return [[], 10];
124
+ }
125
+ if (Array.isArray(hookLocation)) {
126
+ return [hookLocation, 10];
127
+ }
128
+ // if it's in object-form
129
+ return [typeof hookLocation.hook_name === 'string' ? [hookLocation.hook_name] : hookLocation.hook_name ?? [], hookLocation.priority ?? 10];
130
+ }
131
+ function hasDeferringStrategy(handle) {
132
+ return handle.rest[2]?.strategy === 'async' || handle.rest[2]?.strategy === 'defer';
133
+ }
134
+ /**
135
+ * @return {@code true} -> "can share the same handle", {@code false} -> "cannot be merged", {@code 'dependent'} -> "one handle can be listed as a dependency of the other"
136
+ */
137
+ function canMergeHandles(handleA, handleB) {
138
+ if (handleA.inlinedAsset === undefined && handleB.inlinedAsset === undefined) {
139
+ return false; // We cannot merge handles for two non-inlined assets
140
+ }
141
+ if (handleA.lazyLoader !== handleB.lazyLoader) {
142
+ return false; // We cannot merge handles for assets that will be loaded under separate conditions
143
+ }
144
+ if (node_path_1.default.dirname(handleA.src) !== node_path_1.default.dirname(handleB.src)) {
145
+ return false; // We don't want assets from different locations to be able to have their handles overlap
146
+ }
147
+ const additionalArgsA = handleA.rest.length === 3 ? handleA.rest[2] : {};
148
+ const additionalArgsB = handleB.rest.length === 3 ? handleB.rest[2] : {};
149
+ if (additionalArgsA.module_dependencies !== additionalArgsB.module_dependencies) {
150
+ if (additionalArgsA.module_dependencies === undefined) {
151
+ return false;
152
+ }
153
+ if (additionalArgsB.module_dependencies === undefined) {
154
+ return false;
155
+ }
156
+ if (additionalArgsA.module_dependencies.length !== additionalArgsB.module_dependencies.length) {
157
+ return false;
158
+ }
159
+ for (const modDep of additionalArgsA.module_dependencies) {
160
+ if (!additionalArgsB.module_dependencies.includes(modDep)) {
161
+ return false;
162
+ }
163
+ }
164
+ }
165
+ if (additionalArgsA.in_footer !== additionalArgsB.in_footer) {
166
+ return 'dependent';
167
+ }
168
+ if (hasDeferringStrategy(handleA) && handleB.inlinedAsset?.position === 'after') {
169
+ return false;
170
+ }
171
+ if (hasDeferringStrategy(handleB) && handleA.inlinedAsset?.position === 'after') {
172
+ return false;
173
+ }
174
+ if (handleA.locations.register !== handleB.locations.register) {
175
+ return false; //TODO: Maybe make this more granular?
176
+ }
177
+ for (const standardLocation of constantKeys(exports.standardLocationNamesMeta)) {
178
+ const locA = handleA.locations[standardLocation];
179
+ const locB = handleB.locations[standardLocation];
180
+ if (locA === locB) {
181
+ continue;
182
+ }
183
+ if (locA === undefined || locA === false || locB === undefined || locB === false) {
184
+ return false;
185
+ }
186
+ const [locAHookNames, locAPriority] = convertHookLocationToNamesAndPriority(locA);
187
+ const [locBHookNames, locBPriority] = convertHookLocationToNamesAndPriority(locB);
188
+ if (locAHookNames.length !== locBHookNames.length) {
189
+ return false;
190
+ }
191
+ if (locAHookNames.length > 0) {
192
+ for (const hookName of locAHookNames) {
193
+ if (!locBHookNames.includes(hookName)) {
194
+ return false;
195
+ }
196
+ }
197
+ }
198
+ if (locAPriority !== locBPriority) {
199
+ return 'dependent'; // We cannot merge hooks across priority boundaries, but we can have one require the other
200
+ }
201
+ }
202
+ return true;
203
+ }
96
204
  function constantKeys(object) {
97
205
  return Object.keys(object);
98
206
  }
@@ -17,14 +17,14 @@ export declare function parseLocationEncodingFilenameForBlock(filename: string,
17
17
  handle: ParsedLocationEncodingFilename['locations']['handle'];
18
18
  }) | undefined;
19
19
  /**
20
- * This handles detecting all keys of standardLocationNamesMeta as well as "view", "client-view", "editor", "client-editor", and "block-assets".
20
+ * This handles detecting all keys of standardLocationNamesMeta as well as the values listed in their associated alternate_names properties
21
21
  * It MUST be kept in sync with standardLocationNamesMeta
22
22
  * @param segment
23
23
  */
24
24
  export declare function extractLocationFromPropertyEncodingFilenameSegment(segment: string): {
25
+ readonly locationName: false;
26
+ readonly priority?: undefined;
27
+ } | {
25
28
  readonly locationName: "admin" | "analytics" | "blockAssets" | "clientEditor" | "clientView" | "customizer" | "login" | "register";
26
29
  readonly priority: number | true;
27
- } | {
28
- readonly priority?: undefined;
29
- readonly locationName: false;
30
30
  };
@@ -98,27 +98,23 @@ function parseLocationEncodingFilenameForBlock(filename, errorBuilder = shared_1
98
98
  }
99
99
  return parsedFilename;
100
100
  }
101
- const standardLocationNamesAndPriorityPatternInFilenameSegment = /^(?:(?<view>clientView|client-view|view)|(?<editor>clientEditor|client-editor|editor)|(?<blockAssets>blockAssets|block-assets)|(?<locationName>admin|login|customizer|analytics|register))(?:[-=](?<priority>-?\d+))?$/;
101
+ let standardLocationNamesAndPriorityPatternInFilenameSegment;
102
102
  /**
103
- * This handles detecting all keys of standardLocationNamesMeta as well as "view", "client-view", "editor", "client-editor", and "block-assets".
103
+ * This handles detecting all keys of standardLocationNamesMeta as well as the values listed in their associated alternate_names properties
104
104
  * It MUST be kept in sync with standardLocationNamesMeta
105
105
  * @param segment
106
106
  */
107
107
  function extractLocationFromPropertyEncodingFilenameSegment(segment) {
108
- const { view, editor, blockAssets, locationName, priority: rawPriority } = standardLocationNamesAndPriorityPatternInFilenameSegment.exec(segment)
109
- ?.groups ?? {};
110
- const priority = rawPriority !== undefined ? parseInt(rawPriority) : true;
111
- if (view) {
112
- return { locationName: "clientView", priority };
113
- }
114
- if (editor) {
115
- return { locationName: "clientEditor", priority };
108
+ if (!standardLocationNamesAndPriorityPatternInFilenameSegment) {
109
+ const matchableLocationNames = (0, shared_1.iterableStandardLocationNamesMeta)()
110
+ .flatMap(([standardName, { alternate_names = [] }]) => [standardName, ...alternate_names])
111
+ .join("|");
112
+ standardLocationNamesAndPriorityPatternInFilenameSegment = new RegExp(`^(?<locationName>${matchableLocationNames}|register)(?:[-=](?<priority>-?\\d+))?$`);
116
113
  }
117
- if (blockAssets) {
118
- return { locationName: "blockAssets", priority };
114
+ const { locationName, priority: rawPriority } = standardLocationNamesAndPriorityPatternInFilenameSegment.exec(segment)?.groups ?? {};
115
+ if (!locationName) {
116
+ return { locationName: false };
119
117
  }
120
- if (locationName) {
121
- return { locationName, priority };
122
- }
123
- return { locationName: false };
118
+ const priority = rawPriority !== undefined ? parseInt(rawPriority) : true;
119
+ return { locationName: (0, shared_1.normalizeLocationName)(locationName), priority };
124
120
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plaudit/webpack-extensions",
3
- "version": "3.20.2",
3
+ "version": "3.21.1",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,19 +34,19 @@
34
34
  }
35
35
  },
36
36
  "devDependencies": {
37
- "@plaudit/dev-webpack-plugin": "^1.3.1",
37
+ "@plaudit/dev-webpack-plugin": "^1.5.0",
38
38
  "@plaudit/gutenberg-api-extensions": "^2.98.2",
39
39
  "@types/jsdom": "^30.0.0",
40
- "@types/node": "^26.3.0",
40
+ "@types/node": "^26.4.1",
41
41
  "@types/postcss-functions": "^4.0.4",
42
42
  "@types/postcss-import": "^14.0.3",
43
43
  "@types/tapable": "^2.3.0",
44
44
  "@types/webpack-sources": "^3.2.3",
45
- "@wordpress/dependency-extraction-webpack-plugin": "^6.53.0",
45
+ "@wordpress/dependency-extraction-webpack-plugin": "^6.54.0",
46
46
  "atob": "^2.1.2",
47
47
  "css-loader": "^6.11.0",
48
48
  "glob": "^7.2.3",
49
- "jest": "^30.4.2",
49
+ "jest": "^30.5.1",
50
50
  "lodash": "^4.18.1",
51
51
  "mini-css-extract-plugin": "^2.10.2",
52
52
  "mkdirp": "^3.0.1",
@@ -61,7 +61,7 @@
61
61
  "@plaudit/postcss-color-function": "^5.1.0",
62
62
  "@plaudit/postcss-strip-units": "^3.0.0",
63
63
  "@plaudit/postcss-variables": "^2.0.1",
64
- "@wordpress/scripts": "^34.1.0",
64
+ "@wordpress/scripts": "^34.2.0",
65
65
  "autoprefixer": "^10.5.4",
66
66
  "copy-webpack-plugin": "10.2.4",
67
67
  "css-minimizer-webpack-plugin": "^8.0.0",
@@ -69,7 +69,7 @@
69
69
  "fork-ts-checker-webpack-plugin": "^9.1.0",
70
70
  "jsdom": "^30.0.1",
71
71
  "json2php": "0.0.12",
72
- "postcss": "^8.5.26",
72
+ "postcss": "^8.5.28",
73
73
  "postcss-calc": "^10.1.1",
74
74
  "postcss-functions": "^4.0.2",
75
75
  "postcss-import": "^16.2.0",
@@ -79,7 +79,7 @@
79
79
  "postcss-property-lookup": "^3.0.0",
80
80
  "postcss-reporter": "^7.1.0",
81
81
  "postcss-url": "^10.1.4",
82
- "webpack": "^5.109.2",
82
+ "webpack": "^5.110.3",
83
83
  "webpack-remove-empty-scripts": "^1.1.1",
84
84
  "xml-formatter": "^3.7.0"
85
85
  },