@plaudit/webpack-extensions 2.61.2 → 2.62.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/build/shared.d.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import { PHPWriter } from "./utils/php-writer";
1
2
  import type { Options as PostcssFunctionsOptions } from "postcss-functions";
2
- import type { Configuration } from "webpack";
3
+ import { type Configuration, type EntryOptions, WebpackError } from "webpack";
3
4
  export type RawAssetData = Record<string, {
4
5
  dependencies: string[];
5
6
  version: string;
@@ -71,7 +72,27 @@ export type PlauditWordpressWebpackConfig = {
71
72
  srcPrefixes?: string[];
72
73
  useUnifiedLoader?: boolean;
73
74
  };
74
- export declare function makeEmittableConfigPHP(data: any): string;
75
+ export type SmuggledBlockEntrypointInfo = [
76
+ string,
77
+ EntrypointFields[number],
78
+ string,
79
+ string,
80
+ string
81
+ ];
82
+ export type UnpackedBlockEntrypointInfo = {
83
+ blockJsonOrigin: string;
84
+ entrypointField: EntrypointFields[number];
85
+ originalValue: string;
86
+ entrypointName: string;
87
+ handle: string;
88
+ };
89
+ export declare function packBlockEntrypointInfoForSmuggling(info: UnpackedBlockEntrypointInfo): SmuggledBlockEntrypointInfo;
90
+ export declare function unpackSmuggledBlockEntrypointInfo(library: EntryOptions['library']): UnpackedBlockEntrypointInfo | undefined;
91
+ export declare function isSmuggledLibraryInfo(libraryName: NonNullable<EntryOptions['library']>['name'] | undefined): libraryName is SmuggledBlockEntrypointInfo;
92
+ export declare function makeEmittableConfigPHP(data: any, asFullFile: boolean, parentIndent?: string): string;
93
+ export type EntrypointFields = ["viewScriptModule", "scriptModule"] | ["editorStyle", "viewStyle", "style", "editorScript", "viewScript", "script"];
94
+ export declare const entrypointFields: ReadonlyArray<EntrypointFields[number]>;
95
+ export declare function convertEntrypointFieldForAssetType(entrypointField: EntrypointFields[number], assetType: 'script' | 'style'): EntrypointFields[number];
75
96
  export type Sync<V> = {
76
97
  sync: Promise<V>;
77
98
  resolve(v: V): void;
@@ -92,9 +113,19 @@ export declare const scriptExtension: RegExp;
92
113
  export declare const scriptWithoutModuleExtension: RegExp;
93
114
  export declare const scriptWithModuleExtension: RegExp;
94
115
  export declare const styleExtension: RegExp;
95
- export declare function scriptOrStyleTest(entryPath: string, scriptExtension: RegExp): "" | "script" | "style";
116
+ export declare function scriptOrStyleTest(entryPath: string, scriptExtension: RegExp): "" | "style" | "script";
117
+ export declare function isStyleField(field: string): boolean;
118
+ export declare function isScriptModuleField(field: string): boolean;
96
119
  export declare function hasAtLeastOneItem<T>(list: T[]): list is [T, ...T[]];
120
+ export type TupleOf<T, N extends number> = N extends N ? number extends N ? T[] : _TupleOf<T, N, []> : never;
121
+ type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>;
122
+ export declare function arrayIsLength<T, N extends number>(arr: T[] | null | undefined, length: N): arr is TupleOf<T, N>;
97
123
  export declare function kebabCase(value: string): string;
98
124
  export declare function loadEnvFile(filePath: string): Promise<Record<string, string>>;
99
125
  export declare function parseEnvFile(contents: string): Record<string, string>;
126
+ export declare function newWebpackErrorForFile(error: string, file: string): WebpackError;
127
+ /**
128
+ * The primary benefit of emitting a function instead of baking its contents into each function that uses it is that it allows us to avoid recomputing the base uri multiple times
129
+ */
130
+ export declare function emitResolveBaseUriFunction(writer: PHPWriter): void;
100
131
  export {};
package/build/shared.js CHANGED
@@ -3,18 +3,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.styleExtension = exports.scriptWithModuleExtension = exports.scriptWithoutModuleExtension = exports.scriptExtension = exports.SyncsManager = exports.standardLocationNames = void 0;
6
+ exports.styleExtension = exports.scriptWithModuleExtension = exports.scriptWithoutModuleExtension = exports.scriptExtension = exports.SyncsManager = exports.entrypointFields = exports.standardLocationNames = void 0;
7
7
  exports.isRawAssetData = isRawAssetData;
8
8
  exports.determineCurrentSourceType = determineCurrentSourceType;
9
+ exports.packBlockEntrypointInfoForSmuggling = packBlockEntrypointInfoForSmuggling;
10
+ exports.unpackSmuggledBlockEntrypointInfo = unpackSmuggledBlockEntrypointInfo;
11
+ exports.isSmuggledLibraryInfo = isSmuggledLibraryInfo;
9
12
  exports.makeEmittableConfigPHP = makeEmittableConfigPHP;
13
+ exports.convertEntrypointFieldForAssetType = convertEntrypointFieldForAssetType;
10
14
  exports.leadingSlashIt = leadingSlashIt;
11
15
  exports.scriptOrStyleTest = scriptOrStyleTest;
16
+ exports.isStyleField = isStyleField;
17
+ exports.isScriptModuleField = isScriptModuleField;
12
18
  exports.hasAtLeastOneItem = hasAtLeastOneItem;
19
+ exports.arrayIsLength = arrayIsLength;
13
20
  exports.kebabCase = kebabCase;
14
21
  exports.loadEnvFile = loadEnvFile;
15
22
  exports.parseEnvFile = parseEnvFile;
16
- const json_to_php_but_with____injection_1 = __importDefault(require("./utils/json-to-php-but-with-__-injection"));
23
+ exports.newWebpackErrorForFile = newWebpackErrorForFile;
24
+ exports.emitResolveBaseUriFunction = emitResolveBaseUriFunction;
17
25
  const promises_1 = __importDefault(require("node:fs/promises"));
26
+ const json_to_php_but_with____injection_1 = __importDefault(require("./utils/json-to-php-but-with-__-injection"));
27
+ const php_writer_1 = require("./utils/php-writer");
28
+ const webpack_1 = require("webpack");
18
29
  function isRawAssetData(thing) {
19
30
  if (!thing || typeof thing !== 'object') {
20
31
  return false;
@@ -45,13 +56,36 @@ function determineCurrentSourceType(dest, srcIsDirectory) {
45
56
  return dest.directoryLayout;
46
57
  }
47
58
  }
48
- function makeEmittableConfigPHP(data) {
49
- return "<?php return "
50
- + json_to_php_but_with____injection_1.default.make({ indent: "\t", linebreak: "\n", shortArraySyntax: true })(data, "")
51
- .replaceAll(/(\n\t*)\[\s+],/gs, "$1[],")
52
- .replaceAll(/\[\n\t+([^\n]+)\n\t+]/gs, (_, inner) => `[${inner.trim()}]`)
53
- .replaceAll(/'rest' => \[\n\t+(\[(?:'[^']+')?]),\n\t+('[^']+')(?:,\n\t+(\[[^\n]+]))?\n\t+]/gs, (_, deps, hash, args) => `'rest' => [${[deps, hash, args].filter(value => !!value).join(", ")}]`)
54
- + ";";
59
+ function packBlockEntrypointInfoForSmuggling(info) {
60
+ return [info.blockJsonOrigin, info.entrypointField, info.originalValue, info.entrypointName, info.handle];
61
+ }
62
+ function unpackSmuggledBlockEntrypointInfo(library) {
63
+ const libraryName = library?.name;
64
+ if (!isSmuggledLibraryInfo(libraryName)) {
65
+ return undefined;
66
+ }
67
+ return { blockJsonOrigin: libraryName[0], entrypointField: libraryName[1], originalValue: libraryName[2], entrypointName: libraryName[3], handle: libraryName[4] };
68
+ }
69
+ function isSmuggledLibraryInfo(libraryName) {
70
+ if (!Array.isArray(libraryName) || !arrayIsLength(libraryName, 5) || libraryName.some(item => typeof item !== 'string')) {
71
+ return false;
72
+ }
73
+ return libraryName[0].endsWith("/block.json") && exports.entrypointFields.includes(libraryName[1]);
74
+ }
75
+ function makeEmittableConfigPHP(data, asFullFile, parentIndent = "") {
76
+ const prettyPrintedMetadata = json_to_php_but_with____injection_1.default.make({ indent: "\t", linebreak: "\n", shortArraySyntax: true })(data, parentIndent)
77
+ .replaceAll(/(\n\t*)\[\s+],/gs, "$1[],")
78
+ .replaceAll(/\[\n\t+([^\n]+)\n\t+]/gs, (_, inner) => `[${inner.trim()}]`)
79
+ .replaceAll(/'rest' => \[\n\t+(\[(?:'[^']+')?]),\n\t+('[^']+')(?:,\n\t+(\[[^\n]+]))?\n\t+]/gs, (_, deps, hash, args) => `'rest' => [${[deps, hash, args].filter(value => !!value).join(", ")}]`);
80
+ return asFullFile ? `<?php return ${prettyPrintedMetadata};` : prettyPrintedMetadata.trim();
81
+ }
82
+ exports.entrypointFields = [
83
+ "editorStyle", "viewStyle", "style", "editorScript", "viewScript", "script", "viewScriptModule", "scriptModule"
84
+ ];
85
+ function convertEntrypointFieldForAssetType(entrypointField, assetType) {
86
+ // Using these word fragments instead of the full words allows us to avoid having to deal with the capitalization of the first letter
87
+ const searchRep = assetType === 'script' ? ['tyle', 'cript'] : ['cript', 'tyle'];
88
+ return entrypointField.replace(...searchRep);
55
89
  }
56
90
  class SyncsManager {
57
91
  readinessMapping = new Map();
@@ -83,9 +117,18 @@ exports.styleExtension = /(?<filename>.+)(?<extension>\.(p?c|sa)ss)$/i;
83
117
  function scriptOrStyleTest(entryPath, scriptExtension) {
84
118
  return scriptExtension.test(entryPath) ? "script" : (exports.styleExtension.test(entryPath) ? "style" : "");
85
119
  }
120
+ function isStyleField(field) {
121
+ return field.endsWith("tyle");
122
+ }
123
+ function isScriptModuleField(field) {
124
+ return field.includes("odule");
125
+ }
86
126
  function hasAtLeastOneItem(list) {
87
127
  return list.length > 0;
88
128
  }
129
+ function arrayIsLength(arr, length) {
130
+ return !!arr && arr.length === length;
131
+ }
89
132
  function kebabCase(value) {
90
133
  const kebabCaseRegexes = [[/([a-z])([A-Z])/g, "$1-$2"], [/[\s_.\-]+/g, "-"]];
91
134
  return kebabCaseRegexes.reduce((str, [pattern, replacement]) => str.replace(pattern, replacement), value).toLowerCase();
@@ -101,3 +144,29 @@ function parseEnvFile(contents) {
101
144
  return equalsPos === -1 ? [line, ""] : [line.substring(0, equalsPos), line.substring(equalsPos + 1)];
102
145
  }));
103
146
  }
147
+ function newWebpackErrorForFile(error, file) {
148
+ const res = new webpack_1.WebpackError(error);
149
+ res.hideStack = true;
150
+ res.file = file;
151
+ return res;
152
+ }
153
+ /**
154
+ * The primary benefit of emitting a function instead of baking its contents into each function that uses it is that it allows us to avoid recomputing the base uri multiple times
155
+ */
156
+ function emitResolveBaseUriFunction(writer) {
157
+ writer.function("plaudit_webpack_extensions__resolve_base_uri", ["$dir"], writer => {
158
+ writer
159
+ .static("$base_uris", { initializer: [] })
160
+ .if("isset($base_uris[$dir])")
161
+ .return(new php_writer_1.Expr("$base_uris[$dir]"))
162
+ .elseIf("str_starts_with($dir, ABSPATH)")
163
+ .append("$path = ltrim(substr($dir, strlen(ABSPATH)), '/');")
164
+ .elseIf("str_starts_with($dir, '/workspace/website')")
165
+ .append("$path = ltrim(substr($dir, 18), '/');")
166
+ .else()
167
+ .call("error_log", ["UNABLE TO FIGURE OUT WHAT THE RELATIVE PATH TO THE BUILT FILES DIRECTORY SHOULD BE"])
168
+ .append("$path = '';")
169
+ .endIf()
170
+ .call("trailingslashit", [new php_writer_1.Expr("home_url($path)")], { return: true, assignTo: "$base_uris[$dir]" });
171
+ }, { returnType: "string", includeExistenceCheck: true });
172
+ }
@@ -1,4 +1,4 @@
1
- import { PlauditWordpressWebpackConfig, VerifiedAdvancedOutputConfig } from "../shared";
1
+ import { EntrypointFields, PlauditWordpressWebpackConfig, VerifiedAdvancedOutputConfig } from "../shared";
2
2
  import type { Compiler, Configuration, EntryObject, WebpackPluginInstance } from "webpack";
3
3
  import type WebpackRemoveEmptyScriptsPlugin from "webpack-remove-empty-scripts";
4
4
  export type VerifiedPlauditWordpressWebpackConfig = Required<Omit<PlauditWordpressWebpackConfig, 'variables' | 'src' | 'externals'>> & {
@@ -10,7 +10,7 @@ export type CommonPluginConfig = {
10
10
  removeEmptyScriptsPlugin: WebpackRemoveEmptyScriptsPlugin;
11
11
  };
12
12
  export type CommonConfigProcessingResult = {
13
- entrypointFields: string[];
13
+ entrypointFields: EntrypointFields;
14
14
  fixedRules: NonNullable<Configuration['module']>['rules'];
15
15
  processingModules: boolean;
16
16
  scriptExtension: RegExp;
@@ -10,7 +10,6 @@ exports.commonMakeWebpackConfig = commonMakeWebpackConfig;
10
10
  const node_fs_1 = __importDefault(require("node:fs"));
11
11
  const promises_1 = __importDefault(require("node:fs/promises"));
12
12
  const node_path_1 = __importDefault(require("node:path"));
13
- const BlockJSONManagingPlugin_1 = require("../plugins/BlockJSONManagingPlugin");
14
13
  const shared_1 = require("../shared");
15
14
  const copy_webpack_plugin_1 = __importDefault(require("copy-webpack-plugin"));
16
15
  let isInThemeCache = undefined;
@@ -34,20 +33,20 @@ function groupEntrypointsByAssetFile(entrypoints, entrypointNameExtractor) {
34
33
  }
35
34
  return seenPaths;
36
35
  }
37
- function mapToRealEntrypoints(entrypoint, dir, args = {}) {
38
- const { mapper = ep => ep, lazyDependent, associatedQuery, destDir } = args;
36
+ function mapToRealEntrypoints(entrypoint, dir, supportedExtensions, args = {}) {
37
+ const { mapper = ep => ep, destDir } = args;
39
38
  return (Array.isArray(entrypoint) ? entrypoint : [entrypoint])
40
39
  .map(ep => joinPossiblyAbsolutePaths(dir, mapper(ep)))
41
- .filter(ep => node_fs_1.default.statSync(ep, { throwIfNoEntry: false })?.isFile())
40
+ .filter(ep => supportedExtensions(ep) && node_fs_1.default.statSync(ep, { throwIfNoEntry: false })?.isFile())
42
41
  .map(ep => {
43
42
  const parsedEntrypoint = node_path_1.default.parse(ep);
44
- return [joinPossiblyAbsolutePaths(destDir, node_path_1.default.basename(parsedEntrypoint.dir), parsedEntrypoint.name), { import: ep, lazyDependent, associatedQuery }];
43
+ return [joinPossiblyAbsolutePaths(destDir, node_path_1.default.basename(parsedEntrypoint.dir), parsedEntrypoint.name), { import: ep }];
45
44
  });
46
45
  }
47
- function parseEntrypointsJSON(dir, dest) {
46
+ function parseEntrypointsJSON(dir, dest, supportedExtensions) {
48
47
  const entrypointsJSON = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(dir, 'entrypoints.json'), 'utf8'));
49
48
  if (Array.isArray(entrypointsJSON)) {
50
- return mapToRealEntrypoints(entrypointsJSON, dir, { destDir: dest.destination });
49
+ return mapToRealEntrypoints(entrypointsJSON, dir, supportedExtensions, { destDir: dest.destination });
51
50
  }
52
51
  else {
53
52
  return Object.entries(entrypointsJSON).map(([name, config]) => {
@@ -115,31 +114,95 @@ function resolveEntryFromDirectory(commonConfig, srcRoot, dest) {
115
114
  if (!dirent.isDirectory()) {
116
115
  continue;
117
116
  }
118
- //TODO: Instead of doing all of this in a precalc phase, add block.json "entrypoints" with their library type set to "block-json"
117
+ //TODO: It should be possible to handle all block.json files simultaneously, which would allow for better detection of repeated code
119
118
  const dir = joinPossiblyAbsolutePaths(srcRoot, dirent.name);
120
119
  loadingEntrypoints.push(new Promise(async (resolve) => {
121
120
  const rawEntrypoints = [];
122
121
  const wpmlFiles = [];
123
122
  try {
124
- const blockJSON = JSON.parse(await promises_1.default.readFile(node_path_1.default.join(dir, 'block.json'), 'utf8'));
125
- const blockJSONChunkName = node_path_1.default.join(dest.destination, node_path_1.default.relative(srcRoot, dir), "block.json");
126
- for (const key of entrypointFields) {
127
- if (key in blockJSON) {
128
- rawEntrypoints.push(...mapToRealEntrypoints(blockJSON[key], dir, { mapper: ep => ep.startsWith("file:") ? ep.substring(5) : ep, lazyDependent: blockJSONChunkName, destDir: dest.destination }));
123
+ const blockJsonOrigin = node_path_1.default.join(dir, 'block.json');
124
+ const blockJson = JSON.parse(await promises_1.default.readFile(blockJsonOrigin, 'utf8'));
125
+ const blockJsonChunkName = node_path_1.default.join(dest.destination, node_path_1.default.relative(srcRoot, dir), "block");
126
+ const presentEntrypoints = (await Promise.all(entrypointFields
127
+ .filter(entrypointField => entrypointField in blockJson)
128
+ .flatMap(entrypointField => {
129
+ return (Array.isArray(blockJson[entrypointField]) ? blockJson[entrypointField] : [blockJson[entrypointField]])
130
+ .filter(originalValue => originalValue.startsWith("file:"))
131
+ .map(originalValue => {
132
+ const entrypointPath = originalValue.substring(5);
133
+ const absoluteSrc = node_path_1.default.normalize(node_path_1.default.join(dir, entrypointPath));
134
+ return promises_1.default.stat(absoluteSrc)
135
+ .then(stats => {
136
+ if (stats.isFile()) {
137
+ const parsedEntrypoint = node_path_1.default.parse(node_path_1.default.normalize(node_path_1.default.join(dest.destination, node_path_1.default.relative(srcRoot, dir), entrypointPath)));
138
+ const extensionlessExpectedSrc = node_path_1.default.normalize(node_path_1.default.join(parsedEntrypoint.dir, parsedEntrypoint.name));
139
+ const entrypointName = node_path_1.default.normalize(joinPossiblyAbsolutePaths(parsedEntrypoint.dir, parsedEntrypoint.name));
140
+ return { entrypointField, originalValue, entrypointName, extensionlessExpectedSrc, absoluteSrc };
141
+ }
142
+ else {
143
+ return undefined;
144
+ }
145
+ }, () => undefined);
146
+ });
147
+ }))).filter(pe => pe !== undefined);
148
+ const entrypointNamesWithEffectiveDuplicates = presentEntrypoints
149
+ .map(entry => entry.entrypointName)
150
+ .reduce((a, dest) => {
151
+ // If it's undefined, then this is the first instance, otherwise, it's not the first instance and, therefore, is expected to be a duplicate
152
+ a[dest] = (a[dest] !== undefined);
153
+ return a;
154
+ }, {});
155
+ const handlePrefix = blockJson['name']?.toString() ?? `__UNKNOWN_PREFIX__/${dirent.name}`;
156
+ const allocatedDestinations = {};
157
+ const resolvedBlockEntrypoints = presentEntrypoints
158
+ .map(presentEntrypoint => {
159
+ const overallSource = node_path_1.default.dirname(blockJsonOrigin);
160
+ const overallSourceRelativeName = node_path_1.default.relative(overallSource, node_path_1.default.normalize(node_path_1.default.join(blockJsonOrigin, node_path_1.default.relative(overallSource, presentEntrypoint.extensionlessExpectedSrc))));
161
+ if (!entrypointNamesWithEffectiveDuplicates[presentEntrypoint.entrypointName]) {
162
+ return { blockJsonOrigin, ...presentEntrypoint, handle: `${handlePrefix}/${overallSourceRelativeName}` };
129
163
  }
130
- }
164
+ const baseSuffix = `_${(0, shared_1.isStyleField)(presentEntrypoint.entrypointField) ? "style" : "script"}`;
165
+ let count = 0, suffix = baseSuffix, deduplicatedEntrypointName;
166
+ while (((deduplicatedEntrypointName = (presentEntrypoint.entrypointName + suffix)) in allocatedDestinations)
167
+ && allocatedDestinations[deduplicatedEntrypointName] !== presentEntrypoint.originalValue) {
168
+ suffix = baseSuffix + "_" + (++count);
169
+ }
170
+ allocatedDestinations[deduplicatedEntrypointName] = presentEntrypoint.originalValue;
171
+ const deduplicatedExtensionlessExpectedSrc = presentEntrypoint.extensionlessExpectedSrc + suffix;
172
+ return {
173
+ blockJsonOrigin,
174
+ ...presentEntrypoint,
175
+ entrypointName: deduplicatedEntrypointName,
176
+ extensionlessExpectedSrc: deduplicatedExtensionlessExpectedSrc,
177
+ handle: `${handlePrefix}/${count ? overallSourceRelativeName + "_" + count : overallSourceRelativeName}`
178
+ };
179
+ });
180
+ rawEntrypoints.push(...resolvedBlockEntrypoints
181
+ .map(resolvedBlockEntrypoint => {
182
+ return [
183
+ resolvedBlockEntrypoint.entrypointName,
184
+ {
185
+ import: resolvedBlockEntrypoint.absoluteSrc,
186
+ library: { name: (0, shared_1.packBlockEntrypointInfoForSmuggling)(resolvedBlockEntrypoint), type: `block-json-${dest.destination}` }
187
+ }
188
+ ];
189
+ }));
190
+ rawEntrypoints.push([blockJsonChunkName, { import: blockJsonOrigin, library: { name: "block-json-inclusion-assurance", type: `block-json-${dest.destination}` } }]);
131
191
  wpmlFiles.push(node_path_1.default.join(dir, 'block.json'));
132
- BlockJSONManagingPlugin_1.BlockJSONManagingPlugin.recordBlockJSONAssetSourceDir(blockJSONChunkName, dir);
133
192
  }
134
193
  catch (e) {
135
194
  try {
136
195
  const packageJSON = JSON.parse(await promises_1.default.readFile(node_path_1.default.join(dir, 'package.json'), 'utf8'));
137
- rawEntrypoints.push(...mapToRealEntrypoints(packageJSON['main'], dir, { destDir: dest.destination }));
138
- rawEntrypoints.push(...mapToRealEntrypoints(packageJSON['style'], dir, { destDir: dest.destination }));
196
+ if (packageJSON['main']) {
197
+ rawEntrypoints.push(...mapToRealEntrypoints(packageJSON['main'], dir, commonConfig.scriptExtension.test, { destDir: dest.destination }));
198
+ }
199
+ if (!processingModules && packageJSON['style']) {
200
+ rawEntrypoints.push(...mapToRealEntrypoints(packageJSON['style'], dir, shared_1.styleExtension.test, { destDir: dest.destination }));
201
+ }
139
202
  }
140
203
  catch (e) {
141
204
  try {
142
- rawEntrypoints.push(...parseEntrypointsJSON(dir, dest));
205
+ rawEntrypoints.push(...parseEntrypointsJSON(dir, dest, ep => commonConfig.scriptExtension.test(ep) || shared_1.styleExtension.test(ep)));
143
206
  }
144
207
  catch (e) {
145
208
  // This just means that the directory doesn't contain any declared entrypoints.
@@ -173,22 +236,16 @@ function resolveEntryFromDirectory(commonConfig, srcRoot, dest) {
173
236
  }
174
237
  }
175
238
  }
176
- // This is used to allow for block.json dependencies to correctly account for name-deduplication
177
- for (const [key, entry] of Object.entries(currentEntry)) {
178
- if (typeof entry === 'object' && !Array.isArray(entry) && 'lazyDependent' in entry && typeof entry.lazyDependent === 'string') {
179
- BlockJSONManagingPlugin_1.BlockJSONManagingPlugin.recordRawDependency(entry.lazyDependent, key);
180
- }
181
- }
182
239
  if (!processingModules) {
183
240
  const wpmlEntrypointFiles = allEntrypoints.flatMap(e => e[1]);
184
241
  try {
185
242
  await promises_1.default.access(node_path_1.default.join(srcRoot, "wpml-config.xml"));
186
- currentEntry["wpml-config.xml"] = { import: [node_path_1.default.join(srcRoot, "wpml-config.xml"), ...wpmlEntrypointFiles] };
243
+ currentEntry["wpml-config.xml"] = { import: [node_path_1.default.join(srcRoot, "wpml-config.xml"), ...wpmlEntrypointFiles], library: { type: `block-json-${dest.destination}` } };
187
244
  }
188
245
  catch (e) {
189
246
  // If the wpml-config.xml file does not exist, just "import" the other files that will be used to build the emitted version
190
247
  if (wpmlEntrypointFiles.length) {
191
- currentEntry["wpml-config.xml"] = { import: wpmlEntrypointFiles };
248
+ currentEntry["wpml-config.xml"] = { import: wpmlEntrypointFiles, library: { type: `block-json-${dest.destination}` } };
192
249
  }
193
250
  }
194
251
  }
@@ -260,7 +317,7 @@ function commonMakeWebpackConfig(config, commonConfig, webpackConfig, srcIsDirec
260
317
  .map(plugin => !processingModules && plugin.constructor.name === 'CopyPlugin'
261
318
  ? new copy_webpack_plugin_1.default({
262
319
  patterns: [{
263
- from: standaloneBlocks ? '**/(block.json|*.(php|twig|svg))' : '**/(block.json|*.(asset\.php|svg))',
320
+ from: standaloneBlocks ? '**/*.(php|twig|svg)' : '**/*.(asset\.php|svg)',
264
321
  to: dest.destination,
265
322
  context: srcRoot /* canCopyFiles can only be true if srcRoot is a string, so this is safe */, noErrorOnMissing: true
266
323
  }]
@@ -4,6 +4,8 @@ export declare class Expr {
4
4
  private readonly raw;
5
5
  static readonly jsonToPHPConverter: (obj: unknown, parentIndent?: string) => string;
6
6
  static readonly convertJsonToPHP: (obj: unknown) => string;
7
+ static readonly __FILE__: Expr;
8
+ static readonly __DIR__: Expr;
7
9
  constructor(value: string, raw?: boolean);
8
10
  toString(): string;
9
11
  }
@@ -11,6 +11,8 @@ class Expr {
11
11
  raw;
12
12
  static jsonToPHPConverter = json_to_php_but_with____injection_1.default.make({ shortArraySyntax: true });
13
13
  static convertJsonToPHP = (obj) => obj instanceof Expr ? obj.toString() : Expr.jsonToPHPConverter(obj);
14
+ static __FILE__ = new Expr("__FILE__");
15
+ static __DIR__ = new Expr("__DIR__");
14
16
  constructor(value, raw = true) {
15
17
  this.value = value;
16
18
  this.raw = raw;
@@ -281,7 +283,7 @@ class PHPWriter {
281
283
  for (const scopeItem of scope) {
282
284
  this.allocatedGeneratedFunctionNames.delete(scopeItem);
283
285
  }
284
- return this.call("unset", scope.map(v => new Expr(v)));
286
+ return this.append(`unset(${scope.join(", ")});`); // This is equivalent to calling this.call("unset", scope.map(v => new Expr(v))), but creates fewer objects
285
287
  }
286
288
  /**
287
289
  * Pops the top scope from the stack WITHOUT calling unset for the variables that were assigned within it.
@@ -8,12 +8,12 @@ const node_path_1 = __importDefault(require("node:path"));
8
8
  const shared_1 = require("./shared");
9
9
  const common_config_helpers_1 = require("./utils/common-config-helpers");
10
10
  const AdditionalDependencyInjectorPlugin_1 = require("./plugins/AdditionalDependencyInjectorPlugin");
11
- const BlockJSONManagingPlugin_1 = require("./plugins/BlockJSONManagingPlugin");
12
11
  const BrowserSyncPlugin_1 = require("./plugins/BrowserSyncPlugin");
13
12
  const ExtensionsConfigFileGeneratorPlugin_1 = require("./plugins/ExtensionsConfigFileGeneratorPlugin");
14
13
  const MiniCSSExtractPluginErrorCleaner_1 = require("./plugins/MiniCSSExtractPluginErrorCleaner");
15
14
  const PackageConfigSanityChecker_1 = require("./plugins/PackageConfigSanityChecker");
16
15
  const PlainEntrypointsConfigFileGeneratorPlugin_1 = require("./plugins/PlainEntrypointsConfigFileGeneratorPlugin");
16
+ const PlainEntrypointsStyleBlockJSONPlugin_1 = require("./plugins/PlainEntrypointsStyleBlockJSONPlugin");
17
17
  const SpecialAssetHandlingPlugin_1 = require("./plugins/SpecialAssetHandlingPlugin");
18
18
  const VariablesJSMonitorPlugin_1 = require("./plugins/VariablesJSMonitorPlugin");
19
19
  const WPMLConfigBuilder_1 = require("./plugins/WPMLConfigBuilder");
@@ -377,7 +377,8 @@ function buildCommonPluginConfig(srcRoot, scriptExtension, webpackConfig, dest,
377
377
  handleDisablingTSCheckerIfNecessary(srcRoot, scriptExtension, plugins);
378
378
  const removeEmptyScriptsPlugin = new webpack_remove_empty_scripts_1.default({
379
379
  stage: webpack_remove_empty_scripts_1.default.STAGE_AFTER_PROCESS_PLUGINS,
380
- extensions: ['css', 'scss', 'sass', 'less', 'styl', 'pcss']
380
+ extensions: ['css', 'scss', 'sass', 'less', 'styl', 'pcss'],
381
+ ignore: /block\.json/
381
382
  });
382
383
  plugins.push(removeEmptyScriptsPlugin, new MiniCSSExtractPluginErrorCleaner_1.MiniCSSExtractPluginErrorCleaner());
383
384
  plugins.push(new UnifiedLoaderGenerator_1.UnifiedLoaderGenerator(config));
@@ -390,7 +391,7 @@ function buildCommonPluginConfig(srcRoot, scriptExtension, webpackConfig, dest,
390
391
  else {
391
392
  const localAssumeGlobalizedPlauditLibraries = dest.assumeGlobalizedPlauditLibraries ?? assumeGlobalizedPlauditLibraries;
392
393
  const wantsGroupedDepData = combineAssetMetadata
393
- && ((!processingModules && sourceType === "blocks" /* SourceType.blocks */)
394
+ && ((sourceType === "blocks" /* SourceType.blocks */)
394
395
  || (extensionsVersion > 1 && sourceType === "extensions" /* SourceType.extensions */)
395
396
  || (plainEntrypointsVersion > 1 && sourceType === "plain" /* SourceType.plain */));
396
397
  const builtDependencyExtractionWebpackPlugin = (0, dependency_extraction_webpack_plugin_config_builder_1.makeDependencyExtractionPlugin)(externals, localAssumeGlobalizedPlauditLibraries, wantsGroupedDepData, dest.externalize);
@@ -430,6 +431,17 @@ function commonConfigProcessingPrep(config, webpackConfig) {
430
431
  }
431
432
  });
432
433
  }
434
+ fixedRules.push({
435
+ test: /block\.json$/i,
436
+ resourceQuery: /for-resource-tracking/i,
437
+ type: 'asset/resource',
438
+ generator: {
439
+ binary: false,
440
+ filename(pathData) {
441
+ return `${node_path_1.default.dirname(pathData.runtime)}/block[ext]`;
442
+ }
443
+ }
444
+ });
433
445
  return {
434
446
  entrypointFields, fixedRules, processingModules, scriptExtension,
435
447
  updateCurrentVariables: (value) => currentVariables = value
@@ -465,7 +477,6 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
465
477
  }
466
478
  case "plain" /* SourceType.plain */:
467
479
  if (!srcIsDirectory) {
468
- //TODO: We need to filter this when in directory mode as well
469
480
  const primarySrcRoot = typeof srcRoot === 'string' ? srcRoot : srcRoot[0];
470
481
  if (!scriptExtension.test(primarySrcRoot) && !shared_1.styleExtension.test(primarySrcRoot)) {
471
482
  return undefined;
@@ -481,10 +492,10 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
481
492
  }
482
493
  function makeBlocksWebpackConfig(config, commonConfig, webpackConfig, dest, src, srcRoot, plugins) {
483
494
  const { processingModules } = commonConfig;
484
- const blockJSONManagingPlugin = new BlockJSONManagingPlugin_1.BlockJSONManagingPlugin(config.standaloneBlocks, processingModules, dest.destination);
495
+ const blockJSONManagingPlugin = new PlainEntrypointsStyleBlockJSONPlugin_1.PlainEntrypointsStyleBlockJSONPlugin(config, dest.destination, plugins.find(p => p instanceof webpack_remove_empty_scripts_1.default));
485
496
  plugins.push(blockJSONManagingPlugin);
486
497
  if (config.processTranslationConfigs && !processingModules) {
487
- plugins.push(new WPMLConfigBuilder_1.WPMLConfigBuilderPlugin(blockJSONManagingPlugin, dest.destination));
498
+ plugins.push(new WPMLConfigBuilder_1.WPMLConfigBuilderPlugin(dest.destination));
488
499
  }
489
500
  return (0, common_config_helpers_1.commonMakeWebpackConfig)(config, commonConfig, webpackConfig, true, dest, src, srcRoot, (0, common_config_helpers_1.resolveEntryFromDirectory)(commonConfig, srcRoot, dest), plugins);
490
501
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plaudit/webpack-extensions",
3
- "version": "2.61.2",
3
+ "version": "2.62.0",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "files": [
6
6
  "/build"
@@ -1,40 +0,0 @@
1
- import { Compilation, type Compiler, type WebpackPluginInstance } from "webpack";
2
- export declare class BlockJSONManagingPlugin implements WebpackPluginInstance {
3
- private readonly standaloneBlocks;
4
- private readonly processingModules;
5
- private readonly blocksDest;
6
- static readonly mappableModuleKeys: readonly ["viewScriptModule", "scriptModule"];
7
- static readonly mappableNonModuleKeys: readonly ["editorScript", "script", "viewScript", "editorStyle", "style", "viewStyle"];
8
- private static readonly mappableKeys;
9
- private static readonly blockJsonToEntrypointsMap;
10
- private static readonly blockJsonRawDependenciesMap;
11
- private static readonly blockJSONAssetSourceDirs;
12
- private static readonly blockJsonAssetKeyMapping;
13
- private static readonly syncsManager;
14
- readonly additionalMetadata: Map<string, any>;
15
- private readonly id;
16
- constructor(standaloneBlocks: boolean, processingModules: boolean | undefined, blocksDest: string);
17
- static recordRawDependency(entrypoint: string, dependency: string): void;
18
- static recordBlockJSONAssetSourceDir(entrypoint: string, source: string): void;
19
- apply(compiler: Compiler): void;
20
- static resolveDestinationBySourceExtension(srcPath: string, entrypoint: Compilation['asyncEntrypoints'][number]): string | undefined;
21
- static findCommonAncestor(...paths: string[]): string[];
22
- static findRelativeRouteBetween(path1: string, path2: string): string;
23
- private static remapReferencedPHPFilesOnKey;
24
- private static hashThingForAsset;
25
- private static stripFilePrefix;
26
- private static buildFakeCompilationAssets;
27
- private static incorporateRemappedAsset;
28
- private static remapReferencedAssetFile;
29
- private static getReferencedFileSlot;
30
- private static addAssetToBlockJsonKey;
31
- private registerAssetProcessor;
32
- private static populateEntrypointsMap;
33
- private registerBlockJsonProcessor;
34
- private static normalizeRenderTemplate;
35
- private getAssetDetails;
36
- private static getAssetDataAccountingForCSS;
37
- private static findFirstChunkFileWithExtension;
38
- private static getChunkFilesByRuntimeName;
39
- private stripBlocksDest;
40
- }