@plaudit/webpack-extensions 3.20.2 → 3.21.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.
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,11 @@ 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.0] - 2026-09-03
|
|
9
|
+
### Added
|
|
10
|
+
- Logic to associate inline scripts with non-inlined scripts that have the same handle for Plain entrypoints
|
|
11
|
+
- This is intended to make using the "inlined script that does early prep for a deferred script" pattern easier
|
|
12
|
+
|
|
8
13
|
## [3.20.2] - 2026-09-01
|
|
9
14
|
### Removed
|
|
10
15
|
- 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
|
|
36
|
-
|
|
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',
|
|
38
|
+
PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists(compilation, 'script_module', plainEntrypointsConfig.script_moduleHandles
|
|
56
39
|
.toSorted(([a], [b]) => a.localeCompare(b)), handleLists);
|
|
57
|
-
const sortedStyleHandles =
|
|
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);
|
|
@@ -71,13 +54,12 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
|
|
|
71
54
|
for (const [priority, prioritizedHandleList] of PlainEntrypointsConfigFileGeneratorPlugin.separateHandleListByPriority(handleLists.register)) {
|
|
72
55
|
writer.action("init", writer => {
|
|
73
56
|
writer.call("plaudit_webpack_extensions__resolve_base_uri", [expressions_1.Constants.__DIR__], { assignTo: baseUriVar });
|
|
74
|
-
for (const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
writer.call(`wp_register_${type}`, [handle, expressions_1.Op.concat(baseUriVar, (0, node_path_1.relative)(emitDir, data.src)), ...data.rest]);
|
|
57
|
+
for (const handleItem of prioritizedHandleList) {
|
|
58
|
+
PlainEntrypointsConfigFileGeneratorPlugin.writeHandleItem(compilation, handleItem, { baseUriVar, emitDir, writer });
|
|
59
|
+
if (handleItem.data.associatedInlinedHandles !== undefined) {
|
|
60
|
+
for (const associatedHandle of handleItem.data.associatedInlinedHandles) {
|
|
61
|
+
PlainEntrypointsConfigFileGeneratorPlugin.writeHandleItem(compilation, { data: associatedHandle, handle: handleItem.handle, type: associatedHandle.type }, { baseUriVar, emitDir, writer });
|
|
62
|
+
}
|
|
81
63
|
}
|
|
82
64
|
}
|
|
83
65
|
}, { priority, accountForAlreadyDoing: this.config.includePostInitFallback });
|
|
@@ -138,6 +120,79 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
|
|
|
138
120
|
}
|
|
139
121
|
(0, shared_1.emitPHPWriterAsAsset)(file, compilation, "plain-entrypoints-loader.php");
|
|
140
122
|
}
|
|
123
|
+
static writeHandleItem(compilation, { data, handle, type }, { baseUriVar, emitDir, writer }) {
|
|
124
|
+
if (data.inlinedAsset !== undefined) {
|
|
125
|
+
if (!data.inlinedAsset.omitRegistration) {
|
|
126
|
+
writer.call(`wp_register_${type}`, [handle, false, ...data.rest]);
|
|
127
|
+
}
|
|
128
|
+
(0, shared_1.appendAddInlineAssetCall)(compilation, writer, handle, type, data);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
writer.call(`wp_register_${type}`, [handle, expressions_1.Op.concat(baseUriVar, (0, node_path_1.relative)(emitDir, data.src)), ...data.rest]);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
static collatePotentiallyMergeableAssets(assets) {
|
|
135
|
+
const collatedHandles = { scriptHandles: {}, script_moduleHandles: {}, styleHandles: {} };
|
|
136
|
+
for (const { handles, handlePrefix } of assets) {
|
|
137
|
+
for (const { src, rest, locations, type, handleName, lazyLoader, ...otherProps } of handles) {
|
|
138
|
+
const cleanBasename = (0, node_path_1.basename)(src).replace(/_(?:script(?:-\d+)?\.js|style(?:-\d+)?\.css)$|(?<!_(script|style))\.(js|css)$/, "");
|
|
139
|
+
let finalHandleName = (0, shared_1.convertUsageLocationsHandleToEmittableHandle)({ niceName: (0, shared_1.kebabCase)(cleanBasename) }, handlePrefix, cleanBasename);
|
|
140
|
+
if (handleName !== undefined) {
|
|
141
|
+
finalHandleName = (0, shared_1.convertUsageLocationsHandleToEmittableHandle)(handleName, handlePrefix, finalHandleName.substring(handlePrefix.length + 1));
|
|
142
|
+
}
|
|
143
|
+
(collatedHandles[`${type}Handles`][finalHandleName] ??= []).push({ src, rest, locations, type, lazyLoader, ...otherProps });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const plainEntrypointsConfig = { scriptHandles: [], script_moduleHandles: [], styleHandles: [] };
|
|
147
|
+
for (const key of ['scriptHandles', 'script_moduleHandles', 'styleHandles']) {
|
|
148
|
+
for (const [baseFinalHandleName, handles] of Object.entries(collatedHandles[key])) {
|
|
149
|
+
if ((0, shared_1.arrayIsLength)(handles, 1)) {
|
|
150
|
+
plainEntrypointsConfig[key].push([baseFinalHandleName, handles[0]]);
|
|
151
|
+
}
|
|
152
|
+
else if ((0, shared_1.hasAtLeastOneItem)(handles)) {
|
|
153
|
+
const inlinedHandles = handles.filter(item => item.inlinedAsset !== undefined);
|
|
154
|
+
if (inlinedHandles.length === 0) {
|
|
155
|
+
plainEntrypointsConfig[key].push([baseFinalHandleName, handles[0]]);
|
|
156
|
+
let count = 1;
|
|
157
|
+
for (const handle of handles.slice(1)) {
|
|
158
|
+
plainEntrypointsConfig[key].push([`${baseFinalHandleName}-${count++}`, handle]);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
const emittedHandles = handles.filter(item => item.inlinedAsset === undefined);
|
|
163
|
+
inlinedHandlesLoop: for (const inlinedHandle of inlinedHandles) {
|
|
164
|
+
for (const emittedHandle of emittedHandles) {
|
|
165
|
+
const canMerge = (0, shared_1.canMergeHandles)(emittedHandle, inlinedHandle);
|
|
166
|
+
if (!canMerge) {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if ((0, shared_1.hasDeferringStrategy)(emittedHandle)) {
|
|
170
|
+
inlinedHandle.inlinedAsset.position = 'before';
|
|
171
|
+
}
|
|
172
|
+
if (canMerge === 'dependent') {
|
|
173
|
+
emittedHandle.rest[0].push(`${baseFinalHandleName}-${emittedHandles.length}`);
|
|
174
|
+
emittedHandles.push(inlinedHandle);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
(emittedHandle.associatedInlinedHandles ??= []).push(inlinedHandle);
|
|
178
|
+
}
|
|
179
|
+
continue inlinedHandlesLoop;
|
|
180
|
+
}
|
|
181
|
+
emittedHandles.push(inlinedHandle);
|
|
182
|
+
}
|
|
183
|
+
if ((0, shared_1.hasAtLeastOneItem)(emittedHandles)) {
|
|
184
|
+
plainEntrypointsConfig[key].push([baseFinalHandleName, emittedHandles[0]]);
|
|
185
|
+
let count = 1;
|
|
186
|
+
for (const handle of emittedHandles.slice(1)) {
|
|
187
|
+
plainEntrypointsConfig[key].push([`${baseFinalHandleName}-${count++}`, handle]);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return plainEntrypointsConfig;
|
|
195
|
+
}
|
|
141
196
|
static addHandlesToHandleLists(compilation, type, handles, handleLists) {
|
|
142
197
|
const defaultPriority = 10;
|
|
143
198
|
for (const [handle, data] of handles) {
|
package/dist/shared.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ 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 | {
|
|
@@ -98,6 +99,20 @@ export type NormalizedUsageLocations = Omit<UsageLocations, 'registerScriptArgs'
|
|
|
98
99
|
registerScriptArgs?: InputRegisterScriptArgs;
|
|
99
100
|
};
|
|
100
101
|
export declare function isNormalizedUsageLocations(usageLocations: UsageLocations): usageLocations is NormalizedUsageLocations;
|
|
102
|
+
export type EnqueuedAssetType = 'script' | 'script_module' | 'style';
|
|
103
|
+
export type ExtendedHandleData = HandleData & {
|
|
104
|
+
locations: UsageLocations;
|
|
105
|
+
handleName?: UsageLocations['handle'];
|
|
106
|
+
lazyLoader: string | undefined;
|
|
107
|
+
type: EnqueuedAssetType;
|
|
108
|
+
associatedInlinedHandles?: ExtendedHandleData[];
|
|
109
|
+
};
|
|
110
|
+
export declare function convertHookLocationToNamesAndPriority(hookLocation: NonNullable<Exclude<UsageLocations[keyof typeof standardLocationNamesMeta], false>>): [string[], number];
|
|
111
|
+
export declare function hasDeferringStrategy(handle: HandleData): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* @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"
|
|
114
|
+
*/
|
|
115
|
+
export declare function canMergeHandles(handleA: ExtendedHandleData, handleB: ExtendedHandleData): boolean | 'dependent';
|
|
101
116
|
export declare function constantKeys<K extends string, V>(object: {
|
|
102
117
|
[k in K]?: V;
|
|
103
118
|
}): K[];
|
|
@@ -273,7 +288,7 @@ export declare function resolveLegacyBlockScriptsInFolder(folder: string): strin
|
|
|
273
288
|
* @param type 'script_module' is NOT supported at this time; however, it is *handled* in this function
|
|
274
289
|
* @param handleData
|
|
275
290
|
*/
|
|
276
|
-
export declare function appendAddInlineAssetCall(compilation: Compilation, writer: PHPWriter, handle: string, type:
|
|
291
|
+
export declare function appendAddInlineAssetCall(compilation: Compilation, writer: PHPWriter, handle: string, type: EnqueuedAssetType, handleData: IAHandleData): void;
|
|
277
292
|
export declare function wrapInlineAssetContents(compilation: Compilation, wrapperIdPrefix: string, handle: string, contents: string): HereOrNowDoc;
|
|
278
293
|
export declare function synchronousDirIterator(dirPath: string): Generator<import("node:fs").Dirent<string>, void, unknown>;
|
|
279
294
|
/**
|
package/dist/shared.js
CHANGED
|
@@ -22,6 +22,9 @@ exports.isParsedAssetsJson = isParsedAssetsJson;
|
|
|
22
22
|
exports.isStandardLocationName = isStandardLocationName;
|
|
23
23
|
exports.isRegisterScriptArgsShorthandName = isRegisterScriptArgsShorthandName;
|
|
24
24
|
exports.isNormalizedUsageLocations = isNormalizedUsageLocations;
|
|
25
|
+
exports.convertHookLocationToNamesAndPriority = convertHookLocationToNamesAndPriority;
|
|
26
|
+
exports.hasDeferringStrategy = hasDeferringStrategy;
|
|
27
|
+
exports.canMergeHandles = canMergeHandles;
|
|
25
28
|
exports.constantKeys = constantKeys;
|
|
26
29
|
exports.constantEntries = constantEntries;
|
|
27
30
|
exports.determineCurrentSourceType = determineCurrentSourceType;
|
|
@@ -93,6 +96,95 @@ function isRegisterScriptArgsShorthandName(name) {
|
|
|
93
96
|
function isNormalizedUsageLocations(usageLocations) {
|
|
94
97
|
return typeof usageLocations.registerScriptArgs !== 'string';
|
|
95
98
|
}
|
|
99
|
+
function convertHookLocationToNamesAndPriority(hookLocation) {
|
|
100
|
+
if (typeof hookLocation === 'string') {
|
|
101
|
+
return [[hookLocation], 10];
|
|
102
|
+
}
|
|
103
|
+
if (typeof hookLocation === 'number') {
|
|
104
|
+
return [[], hookLocation];
|
|
105
|
+
}
|
|
106
|
+
if (typeof hookLocation === 'boolean') {
|
|
107
|
+
return [[], 10];
|
|
108
|
+
}
|
|
109
|
+
if (Array.isArray(hookLocation)) {
|
|
110
|
+
return [hookLocation, 10];
|
|
111
|
+
}
|
|
112
|
+
// if it's in object-form
|
|
113
|
+
return [typeof hookLocation.hook_name === 'string' ? [hookLocation.hook_name] : hookLocation.hook_name ?? [], hookLocation.priority ?? 10];
|
|
114
|
+
}
|
|
115
|
+
function hasDeferringStrategy(handle) {
|
|
116
|
+
return handle.rest[2]?.strategy === 'async' || handle.rest[2]?.strategy === 'defer';
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* @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"
|
|
120
|
+
*/
|
|
121
|
+
function canMergeHandles(handleA, handleB) {
|
|
122
|
+
if (handleA.inlinedAsset === undefined && handleB.inlinedAsset === undefined) {
|
|
123
|
+
return false; // We cannot merge handles for two non-inlined assets
|
|
124
|
+
}
|
|
125
|
+
if (handleA.lazyLoader !== handleB.lazyLoader) {
|
|
126
|
+
return false; // We cannot merge handles for assets that will be loaded under separate conditions
|
|
127
|
+
}
|
|
128
|
+
if (node_path_1.default.dirname(handleA.src) !== node_path_1.default.dirname(handleB.src)) {
|
|
129
|
+
return false; // We don't want assets from different locations to be able to have their handles overlap
|
|
130
|
+
}
|
|
131
|
+
const additionalArgsA = handleA.rest.length === 3 ? handleA.rest[2] : {};
|
|
132
|
+
const additionalArgsB = handleB.rest.length === 3 ? handleB.rest[2] : {};
|
|
133
|
+
if (additionalArgsA.module_dependencies !== additionalArgsB.module_dependencies) {
|
|
134
|
+
if (additionalArgsA.module_dependencies === undefined) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
if (additionalArgsB.module_dependencies === undefined) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
if (additionalArgsA.module_dependencies.length !== additionalArgsB.module_dependencies.length) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
for (const modDep of additionalArgsA.module_dependencies) {
|
|
144
|
+
if (!additionalArgsB.module_dependencies.includes(modDep)) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (additionalArgsA.in_footer !== additionalArgsB.in_footer) {
|
|
150
|
+
return 'dependent';
|
|
151
|
+
}
|
|
152
|
+
if (hasDeferringStrategy(handleA) && handleB.inlinedAsset?.position === 'after') {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
if (hasDeferringStrategy(handleB) && handleA.inlinedAsset?.position === 'after') {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
if (handleA.locations.register !== handleB.locations.register) {
|
|
159
|
+
return false; //TODO: Maybe make this more granular?
|
|
160
|
+
}
|
|
161
|
+
for (const standardLocation of constantKeys(exports.standardLocationNamesMeta)) {
|
|
162
|
+
const locA = handleA.locations[standardLocation];
|
|
163
|
+
const locB = handleB.locations[standardLocation];
|
|
164
|
+
if (locA === locB) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (locA === undefined || locA === false || locB === undefined || locB === false) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
const [locAHookNames, locAPriority] = convertHookLocationToNamesAndPriority(locA);
|
|
171
|
+
const [locBHookNames, locBPriority] = convertHookLocationToNamesAndPriority(locB);
|
|
172
|
+
if (locAHookNames.length !== locBHookNames.length) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
if (locAHookNames.length > 0) {
|
|
176
|
+
for (const hookName of locAHookNames) {
|
|
177
|
+
if (!locBHookNames.includes(hookName)) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (locAPriority !== locBPriority) {
|
|
183
|
+
return 'dependent'; // We cannot merge hooks across priority boundaries, but we can have one require the other
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
96
188
|
function constantKeys(object) {
|
|
97
189
|
return Object.keys(object);
|
|
98
190
|
}
|