@plaudit/webpack-extensions 2.29.0 → 2.30.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.
@@ -1,12 +1,15 @@
1
- import { type Compiler, type WebpackPluginInstance } from "webpack";
1
+ import { type Compilation, type Compiler, type WebpackPluginInstance } from "webpack";
2
2
  export default class BlockJSONManagingPlugin implements WebpackPluginInstance {
3
3
  private readonly standaloneBlocks;
4
4
  private readonly processingModules;
5
5
  private static readonly sourceToOutputMapping;
6
6
  private static readonly blockJsonToEntrypointsMap;
7
+ private static readonly blockJsonRawDependenciesMap;
7
8
  private static readonly blockJSONAssetSources;
8
9
  constructor(standaloneBlocks: boolean, processingModules: boolean);
10
+ static recordRawDependency(entrypoint: string, dependency: string): void;
9
11
  apply(compiler: Compiler): void;
12
+ static resolveDestinationBySourceExtension(srcPath: string, entrypoint: Compilation['asyncEntrypoints'][number]): string | undefined;
10
13
  static findCommonAncestor(...paths: string[]): string[];
11
14
  static findRelativeRouteBetween(path1: string, path2: string): string;
12
15
  private static hashThingForAsset;
@@ -6,18 +6,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const node_crypto_1 = __importDefault(require("node:crypto"));
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
- const php_serializer_1 = __importDefault(require("./php-serializer"));
10
9
  const webpack_1 = require("webpack");
10
+ const php_serializer_1 = __importDefault(require("./php-serializer"));
11
11
  class BlockJSONManagingPlugin {
12
12
  standaloneBlocks;
13
13
  processingModules;
14
14
  static sourceToOutputMapping = new Map();
15
15
  static blockJsonToEntrypointsMap = new Map();
16
+ static blockJsonRawDependenciesMap = new Map();
16
17
  static blockJSONAssetSources = new Map();
17
18
  constructor(standaloneBlocks, processingModules) {
18
19
  this.standaloneBlocks = standaloneBlocks;
19
20
  this.processingModules = processingModules;
20
21
  }
22
+ static recordRawDependency(entrypoint, dependency) {
23
+ let deps = BlockJSONManagingPlugin.blockJsonRawDependenciesMap.get(entrypoint);
24
+ if (deps === undefined) {
25
+ BlockJSONManagingPlugin.blockJsonRawDependenciesMap.set(entrypoint, deps = new Set());
26
+ }
27
+ deps.add(dependency);
28
+ }
21
29
  apply(compiler) {
22
30
  compiler.hooks.compilation.tap(this.constructor.name, compilation => {
23
31
  compilation.hooks.processAssets.tap({ name: this.constructor.name, stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ANALYSE }, () => {
@@ -29,7 +37,7 @@ class BlockJSONManagingPlugin {
29
37
  continue;
30
38
  }
31
39
  BlockJSONManagingPlugin.blockJSONAssetSources.set(name, source);
32
- const dependencies = blockEntrypoint.getEntrypointChunk().getEntryOptions()?.dependOn;
40
+ const dependencies = BlockJSONManagingPlugin.blockJsonRawDependenciesMap.get(blockEntrypoint.name);
33
41
  if (dependencies) {
34
42
  for (const dependency of dependencies) {
35
43
  const entrypoint = compilation.entrypoints.get(dependency);
@@ -40,9 +48,7 @@ class BlockJSONManagingPlugin {
40
48
  if (!srcPath) {
41
49
  continue;
42
50
  }
43
- const destPath = /m?[jt]sx?$/i.test(node_path_1.default.extname(srcPath))
44
- ? entrypoint.getFiles().find(file => file.endsWith(".mjs")) ?? entrypoint.getFiles().find(file => file.endsWith(".js"))
45
- : entrypoint.getFiles().find(file => file.endsWith(".css"));
51
+ const destPath = BlockJSONManagingPlugin.resolveDestinationBySourceExtension(srcPath, entrypoint);
46
52
  if (!destPath) {
47
53
  continue;
48
54
  }
@@ -210,6 +216,18 @@ class BlockJSONManagingPlugin {
210
216
  });
211
217
  });
212
218
  }
219
+ static resolveDestinationBySourceExtension(srcPath, entrypoint) {
220
+ const extensionMatch = /(m?)[jt]sx?$/i.exec(node_path_1.default.extname(srcPath));
221
+ if (extensionMatch === null) {
222
+ return entrypoint.getFiles().find(file => file.endsWith(".css"));
223
+ }
224
+ else if (extensionMatch[1]) {
225
+ return entrypoint.getFiles().find(file => file.endsWith(".mjs")) ?? entrypoint.getFiles().find(file => file.endsWith(".js"));
226
+ }
227
+ else {
228
+ return entrypoint.getFiles().find(file => file.endsWith(".js"));
229
+ }
230
+ }
213
231
  static findCommonAncestor(...paths) {
214
232
  return paths.map(p => node_path_1.default.normalize(p).split(node_path_1.default.sep)).reduce((prior, current) => {
215
233
  for (let i = 0, limit = Math.min(prior.length, current.length); i < limit; i++) {
@@ -30,9 +30,6 @@ let isInThemeCache = undefined;
30
30
  function isInTheme() {
31
31
  return isInThemeCache ?? (isInThemeCache = node_fs_1.default.existsSync(node_path_1.default.join(process.cwd(), "theme.json")));
32
32
  }
33
- function isTruthy(value) {
34
- return !!value;
35
- }
36
33
  function groupEntrypointsByAssetFile(entrypoints, entrypointNameExtractor) {
37
34
  const seenPaths = new Map();
38
35
  for (const entrypoint of entrypoints) {
@@ -129,64 +126,86 @@ function testForDuplicatedEntryPaths(config) {
129
126
  process.exit(1);
130
127
  }
131
128
  }
132
- function replaceDefaultURLProcessing(webpackConfig) {
129
+ function replaceDefaultURLProcessing(rules) {
133
130
  const cssLoader = require.resolve('css-loader');
134
- if (cssLoader && webpackConfig.module?.rules) {
135
- for (const rule of webpackConfig.module.rules) {
136
- if (isTruthy(rule) && typeof rule === 'object' && "use" in rule && Array.isArray(rule.use)) {
137
- for (const useElement of rule.use) {
138
- if (isTruthy(useElement) && typeof useElement === 'object' && useElement.loader === cssLoader && typeof useElement.options === 'object') {
139
- useElement.options['url'] = {
140
- filter(url) {
141
- return !url.startsWith("/") && !!url.match(/\.(woff|woff2|eot|ttf|otf|png|jpe?g|svg|webp|avif|gif)[^.]*?(\?.*)?/i);
142
- }
143
- };
144
- }
145
- }
131
+ if (cssLoader) {
132
+ return rules.map(rule => {
133
+ if (rule && typeof rule === 'object' && "use" in rule && Array.isArray(rule.use)) {
134
+ return {
135
+ ...rule,
136
+ use: rule.use.map(useElement => {
137
+ if (useElement && typeof useElement === 'object' && useElement.loader === cssLoader && typeof useElement.options === 'object') {
138
+ return {
139
+ ...useElement,
140
+ options: {
141
+ ...useElement.options,
142
+ url: {
143
+ filter(url) {
144
+ return !url.startsWith("/") && !!url.match(/\.(woff|woff2|eot|ttf|otf|png|jpe?g|svg|webp|avif|gif)[^.]*?(\?.*)?/i);
145
+ }
146
+ }
147
+ }
148
+ };
149
+ }
150
+ return useElement;
151
+ })
152
+ };
146
153
  }
147
- }
154
+ return rule;
155
+ });
148
156
  }
157
+ return rules;
149
158
  }
150
- function injectPostcssConfigOverrides(webpackConfig, variables, postcssFunctionsConfig, verbose) {
151
- if (webpackConfig.module?.rules) {
152
- const postcssConfig = (0, static_configs_1.postcssConfigBuilder)(verbose, name => variables(name) ?? (name === 'ENV' ? '' : undefined), postcssFunctionsConfig);
153
- return webpackConfig.module.rules.map(rule => {
154
- if (isTruthy(rule) && typeof rule === 'object') {
155
- if (Array.isArray(rule.use)) {
156
- for (const useItem of rule.use) {
157
- if (isTruthy(useItem) && typeof useItem === 'object' && typeof useItem.options === 'object') {
158
- if (useItem.options["sourceMap"] === false) {
159
- useItem.options["sourceMap"] = true;
159
+ function injectPostcssConfigOverrides(rules, variables, postcssFunctionsConfig, verbose) {
160
+ const postcssConfig = (0, static_configs_1.postcssConfigBuilder)(verbose, name => variables(name) ?? (name === 'ENV' ? '' : undefined), postcssFunctionsConfig);
161
+ return rules.map(rule => {
162
+ if (rule && typeof rule === 'object') {
163
+ if (Array.isArray(rule.use)) {
164
+ for (const useItem of rule.use) {
165
+ if (useItem && typeof useItem === 'object' && typeof useItem.options === 'object') {
166
+ if (useItem.options["sourceMap"] === false) {
167
+ useItem.options["sourceMap"] = true;
168
+ }
169
+ if (useItem.loader?.includes('postcss-loader')) {
170
+ if (useItem.options["postcssOptions"]) {
171
+ useItem.options["postcssOptions"] = { ...useItem.options["postcssOptions"], ...postcssConfig, sourceMap: true };
160
172
  }
161
- if (useItem.loader?.includes('postcss-loader')) {
162
- if (useItem.options["postcssOptions"]) {
163
- useItem.options["postcssOptions"] = { ...useItem.options["postcssOptions"], ...postcssConfig, sourceMap: true };
164
- }
165
- else {
166
- useItem.options["postcssOptions"] = { ...postcssConfig, sourceMap: true };
167
- }
173
+ else {
174
+ useItem.options["postcssOptions"] = { ...postcssConfig, sourceMap: true };
168
175
  }
169
176
  }
170
177
  }
171
- if (rule.test instanceof RegExp && (rule.test.test("index.ts") || rule.test.test("index.mts"))) { // Then this is the javascript and typescript rule
172
- rule.test = /\.m?[jt]sx?$/; // This hacks in support for mjs and mts files
173
- }
174
178
  }
175
- if (rule.type === "asset/inline" && rule.test instanceof RegExp && rule.issuer instanceof RegExp && rule.test.test("test.svg") && rule.issuer.test("test.pcss")) {
176
- rule.type = "asset/resource";
177
- rule.generator = { filename: "images/[name].[hash:8][ext]" };
179
+ if (rule.test instanceof RegExp && (rule.test.test("index.ts") || rule.test.test("index.mts"))) { // Then this is the javascript and typescript rule
180
+ rule.test = /\.m?[jt]sx?$/; // This hacks in support for mjs and mts files
178
181
  }
179
- if (typeof rule.generator === 'object') {
180
- const ruleGeneratorFilename = rule.generator["filename"];
181
- if (typeof ruleGeneratorFilename === 'string' && (ruleGeneratorFilename.startsWith("images/") || ruleGeneratorFilename.startsWith("fonts/"))) {
182
- rule.generator["filename"] = `../${ruleGeneratorFilename}`;
183
- }
182
+ }
183
+ if (rule.type === "asset/inline" && rule.test instanceof RegExp && rule.issuer instanceof RegExp && rule.test.test("test.svg") && rule.issuer.test("test.pcss")) {
184
+ rule.type = "asset/resource";
185
+ rule.generator = { filename: "images/[name].[hash:8][ext]" };
186
+ }
187
+ if (typeof rule.generator === 'object') {
188
+ const ruleGeneratorFilename = rule.generator["filename"];
189
+ if (typeof ruleGeneratorFilename === 'string' && (ruleGeneratorFilename.startsWith("images/") || ruleGeneratorFilename.startsWith("fonts/"))) {
190
+ rule.generator["filename"] = `../${ruleGeneratorFilename}`;
184
191
  }
185
192
  }
186
- return rule;
187
- });
188
- }
189
- return undefined;
193
+ }
194
+ return rule;
195
+ });
196
+ }
197
+ function injectSupportForInliningSVGsAsStrings(rules) {
198
+ const svgRLoader = require.resolve('@svgr/webpack');
199
+ return rules.map(rule => {
200
+ if (rule && typeof rule === 'object' && "use" in rule && Array.isArray(rule.use) && (rule.use.includes('@svgr/webpack') || rule.use.includes(svgRLoader))) {
201
+ const { test, issuer, ...reactSpecific } = rule;
202
+ return { test, issuer, oneOf: [
203
+ { type: 'asset/source', resourceQuery: /string/ }, // *.svg?string
204
+ reactSpecific
205
+ ] };
206
+ }
207
+ return rule;
208
+ });
190
209
  }
191
210
  function parseEntrypointsJSON(dir) {
192
211
  const entrypointsJSON = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(dir, 'entrypoints.json'), 'utf8'));
@@ -227,8 +246,13 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
227
246
  }
228
247
  const { standaloneBlocks, variablesFilePath, verbose, externals } = config;
229
248
  let currentVariables = config.currentVariables;
230
- replaceDefaultURLProcessing(webpackConfig);
231
- const fixedRules = injectPostcssConfigOverrides(webpackConfig, name => currentVariables[name], config.postcss.functions ?? (() => ({})), verbose) ?? [];
249
+ const fixedRules = [
250
+ replaceDefaultURLProcessing,
251
+ (rules) => {
252
+ return injectPostcssConfigOverrides(rules, name => currentVariables[name], config.postcss.functions ?? (() => ({})), verbose);
253
+ },
254
+ injectSupportForInliningSVGsAsStrings
255
+ ].reduce((r, a) => a(r), webpackConfig.module?.rules ?? []);
232
256
  return sources.map(([src, dest]) => {
233
257
  const srcRoots = (typeof dest !== 'string' && dest.withLegacyBlocksIn
234
258
  ? [...src.split(','), ...resolveLegacyBlockScriptsInFolder(dest.withLegacyBlocksIn)]
@@ -240,7 +264,8 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
240
264
  return undefined;
241
265
  }
242
266
  const copyFiles = srcIsDirectory && src !== dest;
243
- const plugins = webpackConfig.plugins?.filter(isTruthy).filter(plugin => plugin.constructor.name !== 'RtlCssPlugin') ?? [];
267
+ const plugins = webpackConfig.plugins?.filter(v => !!v)
268
+ .filter(plugin => plugin.constructor.name !== 'RtlCssPlugin') ?? [];
244
269
  if (process.env["NO_TS_CHECKER"] !== "true") {
245
270
  const include = (Array.isArray(srcRoot) ? srcRoot : [srcRoot])
246
271
  .filter(sr => node_path_1.default.extname(sr).length === 0 || scriptOrStyleTest(sr, scriptExtension) === "script")
@@ -378,22 +403,7 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
378
403
  // This is used to allow for block.json dependencies to correctly account for name-deduplication
379
404
  for (const [key, entry] of Object.entries(currentEntry)) {
380
405
  if (typeof entry === 'object' && !Array.isArray(entry) && 'lazyDependent' in entry && typeof entry.lazyDependent === 'string') {
381
- const target = currentEntry[entry.lazyDependent];
382
- if (typeof target === 'object' && !Array.isArray(target)) {
383
- let dependOn;
384
- if (target.dependOn === undefined) {
385
- dependOn = target.dependOn = [];
386
- }
387
- else if (typeof target.dependOn === 'string') {
388
- dependOn = target.dependOn = [target.dependOn];
389
- }
390
- else {
391
- dependOn = target.dependOn;
392
- }
393
- if (!dependOn.includes(key)) {
394
- dependOn.push(key);
395
- }
396
- }
406
+ BlockJSONManagingPlugin_1.default.recordRawDependency(entry.lazyDependent, key);
397
407
  }
398
408
  }
399
409
  return currentEntry;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plaudit/webpack-extensions",
3
- "version": "2.29.0",
3
+ "version": "2.30.1",
4
4
  "scripts": {
5
5
  "prepublishOnly": "rm -rf build && mkdir build && tsc",
6
6
  "build": "tsc",