@plaudit/webpack-extensions 2.30.1 → 2.31.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.
|
@@ -2,12 +2,13 @@ import { type Compilation, type Compiler, type WebpackPluginInstance } from "web
|
|
|
2
2
|
export default class BlockJSONManagingPlugin implements WebpackPluginInstance {
|
|
3
3
|
private readonly standaloneBlocks;
|
|
4
4
|
private readonly processingModules;
|
|
5
|
-
private static readonly
|
|
5
|
+
private static readonly sourceToOutputMappingCache;
|
|
6
6
|
private static readonly blockJsonToEntrypointsMap;
|
|
7
7
|
private static readonly blockJsonRawDependenciesMap;
|
|
8
|
-
private static readonly
|
|
8
|
+
private static readonly blockJSONAssetSourceDirs;
|
|
9
9
|
constructor(standaloneBlocks: boolean, processingModules: boolean);
|
|
10
10
|
static recordRawDependency(entrypoint: string, dependency: string): void;
|
|
11
|
+
static recordBlockJSONAssetSourceDir(entrypoint: string, source: string): void;
|
|
11
12
|
apply(compiler: Compiler): void;
|
|
12
13
|
static resolveDestinationBySourceExtension(srcPath: string, entrypoint: Compilation['asyncEntrypoints'][number]): string | undefined;
|
|
13
14
|
static findCommonAncestor(...paths: string[]): string[];
|
|
@@ -11,10 +11,10 @@ const php_serializer_1 = __importDefault(require("./php-serializer"));
|
|
|
11
11
|
class BlockJSONManagingPlugin {
|
|
12
12
|
standaloneBlocks;
|
|
13
13
|
processingModules;
|
|
14
|
-
static
|
|
14
|
+
static sourceToOutputMappingCache = new Map();
|
|
15
15
|
static blockJsonToEntrypointsMap = new Map();
|
|
16
16
|
static blockJsonRawDependenciesMap = new Map();
|
|
17
|
-
static
|
|
17
|
+
static blockJSONAssetSourceDirs = new Map();
|
|
18
18
|
constructor(standaloneBlocks, processingModules) {
|
|
19
19
|
this.standaloneBlocks = standaloneBlocks;
|
|
20
20
|
this.processingModules = processingModules;
|
|
@@ -26,56 +26,45 @@ class BlockJSONManagingPlugin {
|
|
|
26
26
|
}
|
|
27
27
|
deps.add(dependency);
|
|
28
28
|
}
|
|
29
|
+
static recordBlockJSONAssetSourceDir(entrypoint, source) {
|
|
30
|
+
BlockJSONManagingPlugin.blockJSONAssetSourceDirs.set(entrypoint, source);
|
|
31
|
+
}
|
|
29
32
|
apply(compiler) {
|
|
30
33
|
compiler.hooks.compilation.tap(this.constructor.name, compilation => {
|
|
31
|
-
compilation.hooks.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
currentEntrypoints.set(srcPath, entryMeta);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
BlockJSONManagingPlugin.blockJsonToEntrypointsMap.set(name, new Map([[srcPath, entryMeta]]));
|
|
62
|
-
}
|
|
34
|
+
compilation.hooks.afterProcessAssets.tap(`${this.constructor.name}_ProcessBlockJSONFiles`, compilationAssets => {
|
|
35
|
+
const currentBlockJSONAssets = BlockJSONManagingPlugin.blockJSONAssetSourceDirs.entries()
|
|
36
|
+
.filter(([name]) => name in compilationAssets)
|
|
37
|
+
.toArray();
|
|
38
|
+
for (const [name] of currentBlockJSONAssets) {
|
|
39
|
+
const dependencies = BlockJSONManagingPlugin.blockJsonRawDependenciesMap.get(name);
|
|
40
|
+
if (dependencies) {
|
|
41
|
+
for (const dependency of dependencies) {
|
|
42
|
+
const entrypoint = compilation.entrypoints.get(dependency);
|
|
43
|
+
if (!entrypoint) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const srcPath = entrypoint.origins.map(origin => origin.request)[0];
|
|
47
|
+
if (!srcPath) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const destPath = BlockJSONManagingPlugin.resolveDestinationBySourceExtension(srcPath, entrypoint);
|
|
51
|
+
if (!destPath) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const entryMeta = { hash: entrypoint.getEntrypointChunk().hash ?? destPath, path: destPath };
|
|
55
|
+
const currentEntrypoints = BlockJSONManagingPlugin.blockJsonToEntrypointsMap.get(name);
|
|
56
|
+
if (currentEntrypoints) {
|
|
57
|
+
currentEntrypoints.set(srcPath, entryMeta);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
BlockJSONManagingPlugin.blockJsonToEntrypointsMap.set(name, new Map([[srcPath, entryMeta]]));
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
63
|
}
|
|
66
64
|
}
|
|
67
|
-
});
|
|
68
|
-
compilation.hooks.afterProcessAssets.tap(`${this.constructor.name}_ProcessBlockJSONFiles`, compilationAssets => {
|
|
69
|
-
// We start by trimming away the unused metadata files that WebPack creates.
|
|
70
|
-
for (const name of Object.keys(compilationAssets)) {
|
|
71
|
-
if (name.endsWith("block.json.asset.php")) {
|
|
72
|
-
compilation.deleteAsset(name);
|
|
73
|
-
compilation.deleteAsset(name.substring(0, name.length - 10) + ".js"); // This removes the block.json.js and block.json.js.map files
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
65
|
if (this.processingModules) {
|
|
77
66
|
// We perform the processing in the non-modules half ONLY because we don't necessarily have all the information we need during the modules half.
|
|
78
|
-
for (const name of
|
|
67
|
+
for (const [name] of currentBlockJSONAssets) {
|
|
79
68
|
compilation.deleteAsset(name); // While the method is called, "deleteAsset", it doesn't actually delete it - just halts emission.
|
|
80
69
|
}
|
|
81
70
|
return;
|
|
@@ -84,31 +73,30 @@ class BlockJSONManagingPlugin {
|
|
|
84
73
|
const mappableKeys = ["editorStyle", "style", "viewStyle", "viewScript", "script", "editorScript", "viewScriptModule", "scriptModule"];
|
|
85
74
|
const remapValue = (value, name) => {
|
|
86
75
|
if (value.startsWith("file:")) {
|
|
87
|
-
let res = BlockJSONManagingPlugin.
|
|
76
|
+
let res = BlockJSONManagingPlugin.sourceToOutputMappingCache.get(`${name};${value}`);
|
|
88
77
|
if (res !== undefined) {
|
|
89
78
|
return res;
|
|
90
79
|
}
|
|
91
|
-
const sourceDir =
|
|
80
|
+
const sourceDir = BlockJSONManagingPlugin.blockJSONAssetSourceDirs.get(name) ?? node_path_1.default.dirname(name);
|
|
92
81
|
const inputPath = node_path_1.default.normalize(node_path_1.default.join(sourceDir, value.substring(5)));
|
|
93
82
|
const output = BlockJSONManagingPlugin.blockJsonToEntrypointsMap.get(name)?.get(inputPath);
|
|
94
83
|
if (output !== undefined) {
|
|
95
84
|
const prefix = value.startsWith("./", 5) ? "./" : "";
|
|
96
85
|
const relativePath = node_path_1.default.relative(node_path_1.default.dirname(name), output.path);
|
|
97
86
|
const res = [`file:${prefix}${relativePath}`, output.hash];
|
|
98
|
-
BlockJSONManagingPlugin.
|
|
87
|
+
BlockJSONManagingPlugin.sourceToOutputMappingCache.set(`${name};${value}`, res);
|
|
99
88
|
return res;
|
|
100
89
|
}
|
|
101
90
|
}
|
|
102
91
|
return [value, ""];
|
|
103
92
|
};
|
|
104
|
-
for (const [name,
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
if (!asset) {
|
|
93
|
+
for (const [name, sourceDir] of currentBlockJSONAssets) {
|
|
94
|
+
const assetContents = compilation.assets[name]?.buffer().toString();
|
|
95
|
+
if (!assetContents) {
|
|
108
96
|
continue;
|
|
109
97
|
}
|
|
110
98
|
blockDirConfigData[name] = true;
|
|
111
|
-
const json = JSON.parse(
|
|
99
|
+
const json = JSON.parse(assetContents);
|
|
112
100
|
let compositeHash = "";
|
|
113
101
|
for (const mappableKey of mappableKeys) {
|
|
114
102
|
if (mappableKey in json) {
|
|
@@ -6,6 +6,13 @@ interface AdvancedOutputConfig {
|
|
|
6
6
|
additionalDependencies?: string[];
|
|
7
7
|
directoryLayout?: 'blocks' | 'extensions';
|
|
8
8
|
}
|
|
9
|
+
type IndividualExternalDepConfig = string | {
|
|
10
|
+
import: string;
|
|
11
|
+
handle: string;
|
|
12
|
+
};
|
|
13
|
+
type Externals = {
|
|
14
|
+
[dep: string]: IndividualExternalDepConfig;
|
|
15
|
+
};
|
|
9
16
|
type PlauditWordpressWebpackConfig = {
|
|
10
17
|
standaloneBlocks?: boolean;
|
|
11
18
|
variables?: Record<string, any>;
|
|
@@ -15,12 +22,7 @@ type PlauditWordpressWebpackConfig = {
|
|
|
15
22
|
postcss?: {
|
|
16
23
|
functions?: (variables: (name: string) => unknown) => PostcssFunctionsOptions['functions'];
|
|
17
24
|
};
|
|
18
|
-
externals?:
|
|
19
|
-
[dep: string]: string | {
|
|
20
|
-
import: string;
|
|
21
|
-
handle: string;
|
|
22
|
-
};
|
|
23
|
-
};
|
|
25
|
+
externals?: Externals;
|
|
24
26
|
};
|
|
25
27
|
declare const _default: (config: PlauditWordpressWebpackConfig, webpackConfig?: Configuration[] | Configuration) => Configuration[];
|
|
26
28
|
export = _default;
|
|
@@ -232,6 +232,52 @@ function parseEntrypointsJSON(dir) {
|
|
|
232
232
|
});
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
|
+
function makeDependencyExtractionPlugin(externals) {
|
|
236
|
+
const exactExternals = {};
|
|
237
|
+
const suffixExternals = [];
|
|
238
|
+
for (const [key, value] of Object.entries(externals)) {
|
|
239
|
+
if (key.startsWith("*/")) {
|
|
240
|
+
suffixExternals.push([key.substring(1), typeof value === 'string' ? { import: value, handle: key.substring(2) } : value]);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
exactExternals[key] = value;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const resolvePossibleExternal = (request) => {
|
|
247
|
+
if (request in exactExternals) {
|
|
248
|
+
return exactExternals[request];
|
|
249
|
+
}
|
|
250
|
+
for (const [key, value] of suffixExternals) {
|
|
251
|
+
if (request.endsWith(key)) {
|
|
252
|
+
return value;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return undefined;
|
|
256
|
+
};
|
|
257
|
+
return new dependency_extraction_webpack_plugin_1.default({
|
|
258
|
+
requestToExternal(request) {
|
|
259
|
+
const possibleExternal = resolvePossibleExternal(request);
|
|
260
|
+
if (typeof possibleExternal === 'string') {
|
|
261
|
+
return possibleExternal;
|
|
262
|
+
}
|
|
263
|
+
else if (possibleExternal !== undefined) {
|
|
264
|
+
return possibleExternal['import'];
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
return undefined;
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
requestToHandle(request) {
|
|
271
|
+
const possibleExternal = resolvePossibleExternal(request);
|
|
272
|
+
if (possibleExternal !== undefined && typeof possibleExternal !== 'string') {
|
|
273
|
+
return possibleExternal.handle;
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
return request;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
235
281
|
function processIndividualWebpackConfig(config, webpackConfig, sources) {
|
|
236
282
|
let scriptExtension; // This is only used in non-block contexts. It might not actually be necessary, but it is good to have
|
|
237
283
|
let entrypointFields;
|
|
@@ -313,29 +359,7 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
|
|
|
313
359
|
console.error("Cannot apply externals when they have been disabled via CLI flag.");
|
|
314
360
|
}
|
|
315
361
|
else {
|
|
316
|
-
plugins[pluginIndex] =
|
|
317
|
-
requestToExternal(request) {
|
|
318
|
-
const possibleExternal = externals[request];
|
|
319
|
-
if (typeof possibleExternal === 'string') {
|
|
320
|
-
return possibleExternal;
|
|
321
|
-
}
|
|
322
|
-
else if (possibleExternal !== undefined) {
|
|
323
|
-
return possibleExternal['import'];
|
|
324
|
-
}
|
|
325
|
-
else {
|
|
326
|
-
return undefined;
|
|
327
|
-
}
|
|
328
|
-
},
|
|
329
|
-
requestToHandle(request) {
|
|
330
|
-
const possibleExternal = externals[request];
|
|
331
|
-
if (possibleExternal !== undefined && typeof possibleExternal !== 'string') {
|
|
332
|
-
return typeof possibleExternal.handle;
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
return request;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
});
|
|
362
|
+
plugins[pluginIndex] = makeDependencyExtractionPlugin(externals);
|
|
339
363
|
}
|
|
340
364
|
}
|
|
341
365
|
if (process.argv.includes('--browser-sync') || process.env['BROWSER_SYNC'] === 'true') {
|
|
@@ -367,7 +391,7 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
|
|
|
367
391
|
res.push(...mapToRealEntrypoints(blockJSON[key], dir, ep => ep.startsWith("file:") ? ep.substring(5) : ep, blockJSONChunkName));
|
|
368
392
|
}
|
|
369
393
|
}
|
|
370
|
-
|
|
394
|
+
BlockJSONManagingPlugin_1.default.recordBlockJSONAssetSourceDir(blockJSONChunkName, dir);
|
|
371
395
|
return res;
|
|
372
396
|
}
|
|
373
397
|
catch (e) {
|
|
@@ -460,16 +484,7 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
|
|
|
460
484
|
},
|
|
461
485
|
module: {
|
|
462
486
|
...webpackConfig.module,
|
|
463
|
-
rules:
|
|
464
|
-
test: /block\.json/i,
|
|
465
|
-
type: 'asset/resource',
|
|
466
|
-
generator: {
|
|
467
|
-
filename(pathData) {
|
|
468
|
-
// This mess of a name-generator accounts for WebPack's calculated name changing when block.json has dependents.
|
|
469
|
-
return node_path_1.default.join(node_path_1.default.basename(node_path_1.default.dirname(pathData.filename ?? pathData.runtime?.toString() ?? "[name]")), "[name][ext]");
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
}]
|
|
487
|
+
rules: fixedRules
|
|
473
488
|
},
|
|
474
489
|
resolve: {
|
|
475
490
|
...webpackConfig.resolve,
|
|
@@ -479,7 +494,7 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
|
|
|
479
494
|
stats: config.stats,
|
|
480
495
|
plugins: copyFiles
|
|
481
496
|
? plugins.map(plugin => plugin.constructor.name === 'CopyPlugin'
|
|
482
|
-
? new copy_webpack_plugin_1.default({ patterns: [{ from: standaloneBlocks ? '**/(
|
|
497
|
+
? new copy_webpack_plugin_1.default({ patterns: [{ from: standaloneBlocks ? '**/(block.json|*.(php|twig|svg))' : '**/(block.json|*.(asset\.php|svg))',
|
|
483
498
|
context: srcRoot, noErrorOnMissing: true }] })
|
|
484
499
|
: plugin)
|
|
485
500
|
: (srcIsDirectory
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plaudit/webpack-extensions",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.31.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prepublishOnly": "rm -rf build && mkdir build && tsc",
|
|
6
6
|
"build": "tsc",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"@plaudit/postcss-silent-extend": "^3.0.0",
|
|
37
37
|
"@plaudit/postcss-strip-units": "^3.0.0",
|
|
38
38
|
"@plaudit/postcss-variables": "^1.0.0",
|
|
39
|
+
"@wordpress/dependency-extraction-webpack-plugin": "^6.7.0",
|
|
39
40
|
"@wordpress/scripts": "^28.3.0",
|
|
40
41
|
"autoprefixer": "^10.4.19",
|
|
41
42
|
"browser-sync": "^3.0.2",
|