@plaudit/webpack-extensions 2.61.2 → 2.62.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.
@@ -8,40 +8,27 @@ const node_path_1 = __importDefault(require("node:path"));
8
8
  const shared_1 = require("../shared");
9
9
  const php_writer_1 = require("../utils/php-writer");
10
10
  const pseduo_semaphore_1 = require("../utils/pseduo-semaphore");
11
- const webpack_1 = require("webpack");
11
+ const AbstractMultiPhaseLibraryPlugin_1 = require("./AbstractMultiPhaseLibraryPlugin");
12
12
  const UnifiedLoaderGenerator_1 = require("./UnifiedLoaderGenerator");
13
- class PlainEntrypointsConfigFileGeneratorPlugin {
13
+ const webpack_1 = require("webpack");
14
+ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryPlugin_1.AbstractMultiPhaseLibraryPlugin {
14
15
  buildRoot;
15
16
  outputDir;
16
17
  usageLocations;
17
18
  handlePrefix;
18
19
  useUnifiedLoader;
19
20
  static semaphore = new pseduo_semaphore_1.PseudoSemaphore([], "Plain");
20
- static phaseTwoAttached = false;
21
- id;
22
21
  constructor(buildRoot, outputDir, usageLocations, handlePrefix, useUnifiedLoader) {
22
+ super("plain-entrypoints-v2", [PlainEntrypointsConfigFileGeneratorPlugin.semaphore, UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore]);
23
23
  this.buildRoot = buildRoot;
24
24
  this.outputDir = outputDir;
25
25
  this.usageLocations = usageLocations;
26
26
  this.handlePrefix = handlePrefix;
27
27
  this.useUnifiedLoader = useUnifiedLoader;
28
- this.id = Math.random().toString();
29
- PlainEntrypointsConfigFileGeneratorPlugin.semaphore.register(this.id);
30
- UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore.register(this.id);
31
28
  }
32
29
  apply(compiler) {
30
+ super.apply(compiler);
33
31
  compiler.hooks.compilation.tap(this.constructor.name, compilation => {
34
- PlainEntrypointsConfigFileGeneratorPlugin.phaseTwoAttached = false;
35
- PlainEntrypointsConfigFileGeneratorPlugin.semaphore.reset(this.id);
36
- UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore.reset(this.id);
37
- compilation.hooks.beforeChunkIds.tap(this.constructor.name, () => {
38
- if (!PlainEntrypointsConfigFileGeneratorPlugin.phaseTwoAttached) {
39
- PlainEntrypointsConfigFileGeneratorPlugin.phaseTwoAttached = true;
40
- compilation.hooks.processAssets.tapPromise({ name: `${this.constructor.name}_CompileLoader`, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_REPORT }, async () => {
41
- this.afterProcessAssets(compilation, (await PlainEntrypointsConfigFileGeneratorPlugin.semaphore.wait()).flat());
42
- });
43
- }
44
- });
45
32
  compilation.hooks.processAssets.tapPromise({ name: this.constructor.name, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_ANALYSE, additionalAssets: true }, async (assets) => {
46
33
  if (!("assets.json" in assets)) {
47
34
  return;
@@ -82,17 +69,17 @@ class PlainEntrypointsConfigFileGeneratorPlugin {
82
69
  chunkFiles[0][1] = true;
83
70
  }
84
71
  for (const [file, useHandleName] of chunkFiles) {
85
- const isScript = file.toLowerCase().endsWith(".js");
72
+ const extension = node_path_1.default.extname(file).toLowerCase();
73
+ const type = extension === ".js" ? 'script' : (extension === ".mjs" ? 'script_module' : 'style');
74
+ const isScript = type !== 'style';
86
75
  const dependencies = isScript === entrypointChunkIsScript ? assetData.dependencies : [];
87
76
  const rest = isScript && this.usageLocations.registerScriptArgs !== undefined
88
77
  ? [dependencies, assetData.version, this.usageLocations.registerScriptArgs] : [dependencies, assetData.version];
89
78
  const destPath = node_path_1.default.join(compilation.outputOptions.path, file);
90
79
  handles.push({
91
- src: destPath,
92
- rest,
80
+ src: destPath, rest, type,
93
81
  locations: this.usageLocations,
94
- isScript,
95
- handleName: useHandleName ? this.usageLocations.handle : undefined
82
+ handleName: useHandleName ? this.usageLocations.handle : undefined,
96
83
  });
97
84
  }
98
85
  myAssetHandles.push({
@@ -101,10 +88,9 @@ class PlainEntrypointsConfigFileGeneratorPlugin {
101
88
  handlePrefix: this.handlePrefix
102
89
  });
103
90
  }
104
- compilation.deleteAsset("assets.json");
105
91
  PlainEntrypointsConfigFileGeneratorPlugin.semaphore.resolve(this.id, myAssetHandles);
106
92
  UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore.resolve(this.id, myAssetHandles.length
107
- ? { group: 'plain-entrypoints-v2', requiresBaseURI: true, action: writer => writer.append("require_once __DIR__.'/plain-entrypoints-loader.php';") }
93
+ ? { group: this.libraryType, requiresBaseURI: true, action: writer => writer.append("require_once __DIR__.'/plain-entrypoints-loader.php';") }
108
94
  : undefined);
109
95
  }
110
96
  catch (e) {
@@ -113,9 +99,12 @@ class PlainEntrypointsConfigFileGeneratorPlugin {
113
99
  throw e;
114
100
  }
115
101
  });
102
+ compilation.hooks.afterProcessAssets.tap(this.constructor.name, () => {
103
+ compilation.deleteAsset("assets.json");
104
+ });
116
105
  });
117
106
  }
118
- afterProcessAssets(compilation, assets) {
107
+ generatePlainEntrypointsLoader(compilation, assets) {
119
108
  const emitDir = node_path_1.default.join(this.buildRoot, this.outputDir);
120
109
  const handleLists = {
121
110
  register: [],
@@ -130,15 +119,13 @@ class PlainEntrypointsConfigFileGeneratorPlugin {
130
119
  .flatMap(({ handles }) => handles)
131
120
  .filter((handle) => !!handle.handleName)
132
121
  .sort((a, b) => a.src.localeCompare(b.src));
133
- const usedScriptHandleNames = Object.fromEntries(allNamedHandles
134
- .filter(handle => handle.isScript)
135
- .map(handle => [handle.handleName, handle.src]));
136
- const usedStyleHandleNames = Object.fromEntries(allNamedHandles
137
- .filter(handle => !handle.isScript)
138
- .map(handle => [handle.handleName, handle.src]));
139
- const plainEntrypointsConfig = { scriptHandles: {}, styleHandles: {} };
122
+ const usedHandleNames = Object.fromEntries(['script', 'script_module', 'style']
123
+ .map(type => [type, Object.fromEntries(allNamedHandles
124
+ .filter(handle => handle.type === 'script')
125
+ .map(handle => [handle.handleName, handle.src]))]));
126
+ const plainEntrypointsConfig = { scriptHandles: {}, script_moduleHandles: {}, styleHandles: {} };
140
127
  for (const { handles, handlePrefix } of assets) {
141
- for (const { src, rest, locations, isScript, handleName } of handles) {
128
+ for (const { src, rest, locations, type, handleName } of handles) {
142
129
  let finalHandleName;
143
130
  if (handleName) {
144
131
  finalHandleName = handleName;
@@ -146,46 +133,48 @@ class PlainEntrypointsConfigFileGeneratorPlugin {
146
133
  else {
147
134
  const basename = node_path_1.default.basename(src).replace(/_(?:script(?:-\d+)?\.js|style(?:-\d+)?\.css)$|(?<!_(script|style))\.(js|css)$/, "");
148
135
  const baseFinalHandleName = `${handlePrefix}.${(0, shared_1.kebabCase)(basename)}`;
149
- const handleNameMap = (isScript ? usedScriptHandleNames : usedStyleHandleNames);
136
+ const handleNameMap = usedHandleNames[type];
150
137
  finalHandleName = baseFinalHandleName;
151
138
  for (let count = 0; finalHandleName in handleNameMap && handleNameMap[finalHandleName] !== src;) {
152
139
  finalHandleName = `${baseFinalHandleName}-${++count}`;
153
140
  }
154
141
  handleNameMap[finalHandleName] = src;
155
142
  }
156
- plainEntrypointsConfig[isScript ? 'scriptHandles' : 'styleHandles'][finalHandleName] = {
143
+ plainEntrypointsConfig[`${type}Handles`][finalHandleName] = {
157
144
  src,
158
145
  rest,
159
146
  locations,
160
- isScript
147
+ type
161
148
  };
162
149
  }
163
150
  }
164
151
  PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists('script', Object.entries(plainEntrypointsConfig.scriptHandles)
165
152
  .toSorted(([a], [b]) => a.localeCompare(b)), handleLists);
153
+ PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists('script_module', Object.entries(plainEntrypointsConfig.script_moduleHandles)
154
+ .toSorted(([a], [b]) => a.localeCompare(b)), handleLists);
166
155
  const sortedStyleHandles = Object.entries(plainEntrypointsConfig.styleHandles)
167
156
  .toSorted(([a], [b]) => a.localeCompare(b));
168
157
  PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists('style', sortedStyleHandles, handleLists);
169
- //TODO: Do we want to sort by type first? Pro: all calls of the same type are together; Con: not all calls for the same block will be together
170
- const callItemSorter = (a, b) => /*a.type.localeCompare(b.type) || */ a.handle.localeCompare(b.handle);
158
+ const callItemSorter = (a, b) => a.handle.localeCompare(b.handle);
171
159
  for (const list of Object.values(handleLists)) {
172
160
  list.sort(callItemSorter);
173
161
  }
174
162
  const writer = new php_writer_1.PHPWriter();
175
163
  if (handleLists.register.length > 0) {
176
164
  if (!this.useUnifiedLoader) {
177
- PlainEntrypointsConfigFileGeneratorPlugin.emitResolveBaseUriFunction(writer);
165
+ (0, shared_1.emitResolveBaseUriFunction)(writer);
178
166
  }
167
+ const baseUriVar = new php_writer_1.Var("base_uri");
179
168
  for (const [priority, prioritizedHandleList] of PlainEntrypointsConfigFileGeneratorPlugin.separateHandleListByPriority(handleLists.register)) {
180
169
  writer.action("init", writer => {
181
- writer.call("plaudit_webpack_extensions__resolve_base_uri", [new php_writer_1.Expr('__DIR__')], { assignTo: "$base_uri" });
170
+ writer.call("plaudit_webpack_extensions__resolve_base_uri", [php_writer_1.Constants.__DIR__], { assignTo: baseUriVar });
182
171
  for (const { handle, type, data } of prioritizedHandleList) {
183
- writer.call(`wp_register_${type}`, [handle, new php_writer_1.Expr(`$base_uri.${php_writer_1.Expr.jsonToPHPConverter(node_path_1.default.relative(emitDir, data.src))}`), ...data.rest]);
172
+ writer.call(`wp_register_${type}`, [handle, php_writer_1.Op.join(baseUriVar, node_path_1.default.relative(emitDir, data.src)), ...data.rest]);
184
173
  }
185
174
  }, { priority, accountForAlreadyDoing: true });
186
175
  }
187
176
  const sortedEditorStyleHandles = sortedStyleHandles
188
- .filter(([_, { locations: { clientEditor }, isScript }]) => !isScript && (clientEditor || typeof clientEditor === 'number'))
177
+ .filter(([_, { locations: { clientEditor }, type }]) => type === 'style' && (clientEditor || typeof clientEditor === 'number'))
189
178
  .map(info => info[1]);
190
179
  if (sortedEditorStyleHandles.length > 0) {
191
180
  writer.linebreak();
@@ -249,25 +238,10 @@ class PlainEntrypointsConfigFileGeneratorPlugin {
249
238
  }
250
239
  return lists.entries().toArray().sort((a, b) => a[0] - b[0]);
251
240
  }
252
- /**
253
- * 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
254
- */
255
- static emitResolveBaseUriFunction(writer) {
256
- writer.function("plaudit_webpack_extensions__resolve_base_uri", ["$dir"], writer => {
257
- writer
258
- .static("$base_uris", { initializer: [] })
259
- .if("isset($base_uris[$dir])")
260
- .return(new php_writer_1.Expr("$base_uris[$dir]"))
261
- .elseIf("str_starts_with($dir, ABSPATH)")
262
- .append("$path = ltrim(substr($dir, strlen(ABSPATH)), '/');")
263
- .elseIf("str_starts_with($dir, '/workspace/website')")
264
- .append("$path = ltrim(substr($dir, 18), '/');")
265
- .else()
266
- .call("error_log", ["UNABLE TO FIGURE OUT WHAT THE RELATIVE PATH TO THE BUILT FILES DIRECTORY SHOULD BE"])
267
- .append("$path = '';")
268
- .endIf()
269
- .call("trailingslashit", [new php_writer_1.Expr("home_url($path)")], { return: true, assignTo: "$base_uris[$dir]" });
270
- }, { returnType: "string", includeExistenceCheck: true });
241
+ attachSecondPhase(compilation) {
242
+ compilation.hooks.processAssets.tapPromise({ name: `${this.constructor.name}_CompileLoader`, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_REPORT }, async () => {
243
+ this.generatePlainEntrypointsLoader(compilation, (await PlainEntrypointsConfigFileGeneratorPlugin.semaphore.wait()).flat());
244
+ });
271
245
  }
272
246
  }
273
247
  exports.PlainEntrypointsConfigFileGeneratorPlugin = PlainEntrypointsConfigFileGeneratorPlugin;
@@ -0,0 +1,25 @@
1
+ import { AbstractMultiPhaseLibraryPlugin } from "./AbstractMultiPhaseLibraryPlugin";
2
+ import type { VerifiedPlauditWordpressWebpackConfig } from "../utils/common-config-helpers";
3
+ import { Compilation, type Compiler } from "webpack";
4
+ import type WebpackRemoveEmptyScriptsPlugin from "webpack-remove-empty-scripts";
5
+ export declare class PlainEntrypointsStyleBlockJSONPlugin extends AbstractMultiPhaseLibraryPlugin {
6
+ private readonly config;
7
+ private readonly blocksDest;
8
+ private readonly webpackRemoveEmptyScriptsPlugin;
9
+ private static readonly semaphore;
10
+ constructor(config: VerifiedPlauditWordpressWebpackConfig, blocksDest: string, webpackRemoveEmptyScriptsPlugin: WebpackRemoveEmptyScriptsPlugin);
11
+ apply(compiler: Compiler): void;
12
+ private emitBlockLoaderFile;
13
+ private transformBlocks;
14
+ private static extractAssetSource;
15
+ private static convertToScriptHandles;
16
+ private static doFileOrHandleReplacements;
17
+ private stripOffBlocksDestPrefix;
18
+ private static hashThingForAsset;
19
+ private static stripFilePrefix;
20
+ static findCommonAncestor(...paths: string[]): string[];
21
+ static findRelativeRouteBetween(path1: string, path2: string): string;
22
+ private static remapReferencedPHPFilesOnKey;
23
+ private static normalizeRenderTemplate;
24
+ protected attachSecondPhase(compilation: Compilation): void;
25
+ }