@plaudit/webpack-extensions 2.44.4 → 2.44.6

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.
@@ -33,4 +33,9 @@ export default class BlockJSONManagingPlugin implements WebpackPluginInstance {
33
33
  private registerBlockJsonProcessor;
34
34
  private static normalizeRenderTemplate;
35
35
  private static getSyncs;
36
+ private static makeSync;
37
+ private static getAssetDetails;
38
+ private static getAssetDataAccountingForCSS;
39
+ private static findFirstChunkFileWithExtension;
40
+ private static getChunkFilesByRuntimeName;
36
41
  }
@@ -169,20 +169,20 @@ class BlockJSONManagingPlugin {
169
169
  if (value.startsWith("file:")) {
170
170
  const sourceDir = BlockJSONManagingPlugin.blockJSONAssetSourceDirs.get(name) ?? node_path_1.default.dirname(name);
171
171
  const inputPath = node_path_1.default.normalize(node_path_1.default.join(sourceDir, value.substring(5)));
172
- const outputAndAdditionalFiles = BlockJSONManagingPlugin.blockJsonToEntrypointsMap.get(name)?.get(inputPath);
173
- if (outputAndAdditionalFiles !== undefined) {
174
- const { output, additionalFiles } = outputAndAdditionalFiles;
172
+ const outputAndDerivedFiles = BlockJSONManagingPlugin.blockJsonToEntrypointsMap.get(name)?.get(inputPath);
173
+ if (outputAndDerivedFiles !== undefined) {
174
+ const { entryMeta, derivedFiles } = outputAndDerivedFiles;
175
175
  const prefix = value.startsWith("./", 5) ? "./" : "";
176
- const relativePath = node_path_1.default.relative(node_path_1.default.dirname(name), output.path);
177
- const res = [`file:${prefix}${relativePath}`, output.hash];
178
- if (BlockJSONManagingPlugin.styleExtensionPattern.test(output.path)) {
176
+ const relativePath = node_path_1.default.relative(node_path_1.default.dirname(name), entryMeta.path);
177
+ const res = [`file:${prefix}${relativePath}`, entryMeta.hash];
178
+ if (BlockJSONManagingPlugin.styleExtensionPattern.test(entryMeta.path)) {
179
179
  return [res,
180
- additionalFiles.filter(additionalFile => !BlockJSONManagingPlugin.scriptExtensionPattern.test(additionalFile))
181
- .map(additionalFile => `file:./${node_path_1.default.relative(node_path_1.default.dirname(name), additionalFile)}`)
180
+ derivedFiles.filter(derivedFile => !BlockJSONManagingPlugin.scriptExtensionPattern.test(derivedFile))
181
+ .map(derivedFile => `file:./${node_path_1.default.relative(node_path_1.default.dirname(name), derivedFile)}`)
182
182
  ];
183
183
  }
184
184
  else {
185
- return [res, additionalFiles.map(additionalFile => `file:./${node_path_1.default.relative(node_path_1.default.dirname(name), additionalFile)}`)];
185
+ return [res, derivedFiles.map(derivedFile => `file:./${node_path_1.default.relative(node_path_1.default.dirname(name), derivedFile)}`)];
186
186
  }
187
187
  }
188
188
  }
@@ -294,19 +294,16 @@ class BlockJSONManagingPlugin {
294
294
  continue;
295
295
  }
296
296
  const entrypointChunk = entrypoint.getEntrypointChunk();
297
- const additionalFiles = [];
298
- for (const entrypointChunkFile of entrypointChunk.files) {
299
- if (!entrypointChunkFile.endsWith(".asset.php") && entrypointChunkFile !== destPath) {
300
- additionalFiles.push(entrypointChunkFile);
301
- }
302
- }
297
+ const derivedFiles = entrypointChunk.name
298
+ ? BlockJSONManagingPlugin.getChunkFilesByRuntimeName(entrypointChunk.name, compilation).filter(file => file !== destPath)
299
+ : [...entrypointChunk.files].filter(file => !file.endsWith(".asset.php") && file !== destPath);
303
300
  const entryMeta = { hash: entrypointChunk.hash ?? destPath, path: destPath };
304
301
  const currentEntrypoints = BlockJSONManagingPlugin.blockJsonToEntrypointsMap.get(name);
305
302
  if (currentEntrypoints) {
306
- currentEntrypoints.set(srcPath, { output: entryMeta, additionalFiles });
303
+ currentEntrypoints.set(srcPath, { entryMeta, derivedFiles });
307
304
  }
308
305
  else {
309
- BlockJSONManagingPlugin.blockJsonToEntrypointsMap.set(name, new Map([[srcPath, { output: entryMeta, additionalFiles }]]));
306
+ BlockJSONManagingPlugin.blockJsonToEntrypointsMap.set(name, new Map([[srcPath, { entryMeta, derivedFiles }]]));
310
307
  }
311
308
  }
312
309
  }
@@ -379,34 +376,47 @@ class BlockJSONManagingPlugin {
379
376
  const blockDirConfigs = Object.entries(blockDirConfigData).sort(([a], [b]) => a.localeCompare(b));
380
377
  const rawAssetDataSource = compilation.assets["assets.json"]?.source();
381
378
  if (typeof rawAssetDataSource === 'string') {
379
+ const derivedFilesMap = new Map();
380
+ for (const epMap of BlockJSONManagingPlugin.blockJsonToEntrypointsMap.values()) { // For each block.json file's entry point map
381
+ for (const epMapValue of epMap.values()) { // For each recorded entry point
382
+ const progenitorFile = epMapValue.entryMeta.path;
383
+ for (const derivedFile of epMapValue.derivedFiles) { // For each derived (non-auxiliary) file generated by that entry point
384
+ derivedFilesMap.set(derivedFile, progenitorFile); // Record a mapping from each derived file to its progenitor
385
+ }
386
+ }
387
+ }
388
+ const rawAssetData = JSON.parse(rawAssetDataSource);
389
+ for (const chunk of compilation.chunks) {
390
+ if (compilation.chunkGraph.getChunkModulesIterableBySourceType(chunk, 'css/mini-extract')) {
391
+ const output = BlockJSONManagingPlugin.findFirstChunkFileWithExtension(chunk, ".css");
392
+ if (output) {
393
+ rawAssetData[output] = { dependencies: [], version: chunk.contentHash['css/mini-extract'] ?? chunk.hash ?? "" };
394
+ }
395
+ }
396
+ }
382
397
  const scriptHandles = {};
383
398
  const styleHandles = {};
384
- const additionalFilesMap = new Map([...BlockJSONManagingPlugin.blockJsonToEntrypointsMap.values()] // Extract the recorded block.json files into an array
385
- .flatMap(epMap => [...epMap.values()]) // Extract the recorded entrypoints for all block.json files into a single array
386
- .flatMap(epMapValue => {
387
- return epMapValue.additionalFiles.map(af => [af, epMapValue.output.path]); // Pair each additionalFile with its progenitor
388
- }) // Flatten the per-entrypoint [additionalFile, progenitor] pairs into a single array
389
- );
390
- const rawAssetData = JSON.parse(rawAssetDataSource);
391
- const usedHandles = {};
399
+ const usedHandles = { css: {}, js: {} };
392
400
  for (const [blockFolder, config] of blockDirConfigs) {
393
401
  for (const mappableKey of BlockJSONManagingPlugin.mappableKeys) {
394
402
  const cfg = config[mappableKey];
395
403
  if (cfg) {
396
404
  if (Array.isArray(cfg)) {
397
405
  for (let i = 0; i < cfg.length; i++) {
398
- const assetDetails = getAssetDetails(blockFolder, cfg[i], rawAssetData, additionalFilesMap, mappableKey, usedHandles);
406
+ const assetDetails = BlockJSONManagingPlugin
407
+ .getAssetDetails(blockFolder, cfg[i], rawAssetData, derivedFilesMap, mappableKey, usedHandles);
399
408
  if (assetDetails) {
400
- (assetDetails[0] ? styleHandles : scriptHandles)[assetDetails[1]] = assetDetails[2];
401
- cfg[i] = assetDetails[1];
409
+ (assetDetails.isCss ? styleHandles : scriptHandles)[assetDetails.handle] = assetDetails.handleData;
410
+ cfg[i] = assetDetails.handle;
402
411
  }
403
412
  }
404
413
  }
405
414
  else {
406
- const assetDetails = getAssetDetails(blockFolder, cfg, rawAssetData, additionalFilesMap, mappableKey, usedHandles);
415
+ const assetDetails = BlockJSONManagingPlugin
416
+ .getAssetDetails(blockFolder, cfg, rawAssetData, derivedFilesMap, mappableKey, usedHandles);
407
417
  if (assetDetails) {
408
- (assetDetails[0] ? styleHandles : scriptHandles)[assetDetails[1]] = assetDetails[2];
409
- config[mappableKey] = assetDetails[1];
418
+ (assetDetails.isCss ? styleHandles : scriptHandles)[assetDetails.handle] = assetDetails.handleData;
419
+ config[mappableKey] = assetDetails.handle;
410
420
  }
411
421
  }
412
422
  }
@@ -488,56 +498,90 @@ class BlockJSONManagingPlugin {
488
498
  if (res) {
489
499
  return res;
490
500
  }
491
- BlockJSONManagingPlugin.blockJsonAssetKeyReadinessMapping.set(name, { nonModule: makeSync(), module: makeSync() });
501
+ BlockJSONManagingPlugin.blockJsonAssetKeyReadinessMapping.set(name, { nonModule: BlockJSONManagingPlugin.makeSync(), module: BlockJSONManagingPlugin.makeSync() });
492
502
  return BlockJSONManagingPlugin.blockJsonAssetKeyReadinessMapping.get(name);
493
503
  }
494
- }
495
- exports.default = BlockJSONManagingPlugin;
496
- function makeSync() {
497
- const res = { done: false };
498
- res.sync = new Promise((resolve, reject) => {
499
- res.resolve = (v) => resolve(v);
500
- res.reject = () => reject();
501
- });
502
- return res;
503
- }
504
- function getAssetDetails(blockFolder, asset, rawAssetData, additionalFilesMap, mappableKey, usedHandles) {
505
- if (!asset.startsWith("file:./")) {
506
- return undefined;
507
- }
508
- const src = `${blockFolder}/${asset.substring(7)}`;
509
- const isCss = src.endsWith(".css");
510
- let assetData;
511
- const lookupSrc = additionalFilesMap.get(src);
512
- if (lookupSrc) {
513
- const tempAssetData = getAssetDataAccountingForCSS(lookupSrc, rawAssetData);
514
- assetData = tempAssetData ? { ...tempAssetData, dependencies: [] } : undefined;
504
+ static makeSync() {
505
+ const res = { done: false };
506
+ res.sync = new Promise((resolve, reject) => {
507
+ res.resolve = (v) => resolve(v);
508
+ res.reject = () => reject();
509
+ });
510
+ return res;
515
511
  }
516
- else {
517
- assetData = getAssetDataAccountingForCSS(src, rawAssetData);
512
+ static getAssetDetails(blockFolder, asset, rawAssetData, derivedFilesMap, mappableKey, usedHandles) {
513
+ if (!asset.startsWith("file:./")) {
514
+ return undefined;
515
+ }
516
+ const src = `${blockFolder}/${asset.substring(7)}`;
517
+ const isCss = src.endsWith(".css");
518
+ let assetData;
519
+ if (rawAssetData[src]) {
520
+ assetData = rawAssetData[src];
521
+ }
522
+ else {
523
+ const progenitorSrc = derivedFilesMap.get(src);
524
+ if (progenitorSrc) {
525
+ const tempAssetData = BlockJSONManagingPlugin.getAssetDataAccountingForCSS(progenitorSrc, rawAssetData);
526
+ if (tempAssetData) {
527
+ assetData = progenitorSrc.endsWith(".css") === isCss
528
+ ? tempAssetData
529
+ : { ...tempAssetData, dependencies: [] }; // derived files cannot inherit dependencies from their progenitors if they are of a different type
530
+ }
531
+ else {
532
+ assetData = undefined;
533
+ }
534
+ assetData = tempAssetData ? { ...tempAssetData, dependencies: [] } : undefined;
535
+ }
536
+ else {
537
+ assetData = BlockJSONManagingPlugin.getAssetDataAccountingForCSS(src, rawAssetData);
538
+ }
539
+ }
540
+ if (!assetData) {
541
+ return undefined;
542
+ }
543
+ let handle = src.substring(0, src.length - (isCss ? 4 : 3));
544
+ if (usedHandles[isCss ? 'css' : 'js'][handle] !== undefined) {
545
+ handle += "-" + (++usedHandles[isCss ? 'css' : 'js'][handle]);
546
+ }
547
+ else {
548
+ usedHandles[isCss ? 'css' : 'js'][handle] = 0;
549
+ }
550
+ const rest = isCss || mappableKey.startsWith("editor")
551
+ ? [assetData.dependencies, assetData.version]
552
+ : [assetData.dependencies, assetData.version, { strategy: 'defer' }];
553
+ return { isCss, handle, handleData: { src, rest } };
518
554
  }
519
- if (!assetData) {
555
+ static getAssetDataAccountingForCSS(src, rawAssetData) {
556
+ if (rawAssetData[src]) {
557
+ return rawAssetData[src];
558
+ }
559
+ if (src.endsWith(".css")) {
560
+ return rawAssetData[src.substring(0, src.length - 3) + "js"] // A simple style dependency that isn't named "style"
561
+ ?? rawAssetData[src.substring(0, src.length - 3).replace("style-style", "style") + "js"]; // A simple style dependency that IS named style
562
+ }
520
563
  return undefined;
521
564
  }
522
- let handle = src.substring(0, src.length - (isCss ? 4 : 3));
523
- if (usedHandles[handle] !== undefined) {
524
- handle += "-" + (++usedHandles[handle]);
525
- }
526
- else {
527
- usedHandles[handle] = 0;
528
- }
529
- return [
530
- isCss, handle,
531
- { src, rest: isCss || mappableKey.startsWith("editor") ? [assetData.dependencies, assetData.version] : [assetData.dependencies, assetData.version, { strategy: 'defer' }] }
532
- ];
533
- }
534
- function getAssetDataAccountingForCSS(src, rawAssetData) {
535
- if (rawAssetData[src]) {
536
- return rawAssetData[src];
565
+ static findFirstChunkFileWithExtension(chunk, extension) {
566
+ for (const file of chunk.files) {
567
+ if (file.endsWith(extension)) {
568
+ return file;
569
+ }
570
+ }
571
+ return undefined;
537
572
  }
538
- if (src.endsWith(".css")) {
539
- return rawAssetData[src.substring(0, src.length - 3) + "js"] // A simple style dependency that isn't named "style"
540
- ?? rawAssetData[src.substring(0, src.length - 3).replace("style-style", "style") + "js"]; // A simple style dependency that IS named style
573
+ static getChunkFilesByRuntimeName(runtimeName, compilation) {
574
+ const files = new Set();
575
+ for (const chunk of compilation.chunks) {
576
+ if (typeof chunk.runtime === 'string' ? chunk.runtime === runtimeName : chunk.runtime?.has(runtimeName)) {
577
+ for (const file of chunk.files) {
578
+ if (!file.endsWith(".asset.php")) {
579
+ files.add(file);
580
+ }
581
+ }
582
+ }
583
+ }
584
+ return [...files];
541
585
  }
542
- return undefined;
543
586
  }
587
+ exports.default = BlockJSONManagingPlugin;
@@ -279,7 +279,20 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
279
279
  }
280
280
  const copyFiles = srcIsDirectory && src !== dest;
281
281
  const plugins = webpackConfig.plugins?.filter(v => !!v)
282
- .filter(plugin => plugin.constructor.name !== 'RtlCssPlugin') ?? [];
282
+ .filter(plugin => plugin.constructor.name !== 'RtlCssPlugin')
283
+ .map(plugin => {
284
+ if (plugin.constructor.name === 'MiniCssExtractPlugin') {
285
+ return new plugin.constructor({
286
+ filename(pd) {
287
+ const name = pd.chunk?.name?.replaceAll(/__[a-zA-Z0-9]+__/g, ""); // This removes the prefix that the cache group adds
288
+ return name ? `${name}.css` : "[name].css";
289
+ },
290
+ layer: ""
291
+ });
292
+ }
293
+ return plugin;
294
+ })
295
+ ?? [];
283
296
  if (process.env["NO_TS_CHECKER"] !== "true") {
284
297
  const include = (Array.isArray(srcRoot) ? srcRoot : [srcRoot])
285
298
  .filter(sr => node_path_1.default.extname(sr).length === 0 || scriptOrStyleTest(sr, scriptExtension) === "script")
@@ -513,6 +526,26 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
513
526
  publicPath: publicPath,
514
527
  library: outputLibrary
515
528
  },
529
+ optimization: {
530
+ ...webpackConfig.optimization,
531
+ splitChunks: {
532
+ ...(webpackConfig.optimization?.splitChunks || {}),
533
+ cacheGroups: {
534
+ style: {
535
+ // This is a flagrant abuse of cache groups, but it fixes a persistent problem wherein the dependencies and versions of scripts and styles were bleeding into each-other
536
+ type: 'css/mini-extract',
537
+ chunks: 'all',
538
+ enforce: true,
539
+ name(_, chunks, cacheGroupKey) {
540
+ const chunkName = chunks.find(chunk => chunk.name)?.name;
541
+ // We use "__${cacheGroupKey}__" instead of "${cacheGroupKey}-" to make it easier to remove when generating the filename
542
+ return `${node_path_1.default.dirname(chunkName)}/__${cacheGroupKey}__${node_path_1.default.basename(chunkName)}`;
543
+ }
544
+ },
545
+ default: false
546
+ }
547
+ }
548
+ },
516
549
  module: {
517
550
  ...webpackConfig.module,
518
551
  rules: fixedRules
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plaudit/webpack-extensions",
3
- "version": "2.44.4",
3
+ "version": "2.44.6",
4
4
  "license": "UNLICENSED",
5
5
  "scripts": {
6
6
  "prepublishOnly": "rm -rf build && mkdir build && tsc",
@@ -45,7 +45,6 @@
45
45
  "clean-webpack-plugin": "^4.0.0",
46
46
  "copy-webpack-plugin": "^10.2.4",
47
47
  "cssnano": "^6.1.2",
48
- "eslint": "^8.57.1",
49
48
  "eslint-plugin-jsdoc": "^48.11.0",
50
49
  "fork-ts-checker-webpack-plugin": "^9.1.0",
51
50
  "http-proxy-middleware": "^3.0.5",