@plaudit/webpack-extensions 2.55.0 → 2.56.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.
@@ -5,8 +5,6 @@ export declare class BlockJSONManagingPlugin implements WebpackPluginInstance {
5
5
  private readonly blocksDest;
6
6
  static readonly mappableModuleKeys: readonly ["viewScriptModule", "scriptModule"];
7
7
  static readonly mappableNonModuleKeys: readonly ["editorScript", "script", "viewScript", "editorStyle", "style", "viewStyle"];
8
- private static readonly styleExtensionPattern;
9
- private static readonly scriptExtensionPattern;
10
8
  private static readonly mappableKeys;
11
9
  private static readonly blockJsonToEntrypointsMap;
12
10
  private static readonly blockJsonRawDependenciesMap;
@@ -15,8 +15,6 @@ class BlockJSONManagingPlugin {
15
15
  blocksDest;
16
16
  static mappableModuleKeys = ["viewScriptModule", "scriptModule"];
17
17
  static mappableNonModuleKeys = ["editorScript", "script", "viewScript", "editorStyle", "style", "viewStyle"];
18
- static styleExtensionPattern = /\.(p?c|sa)ss$/i;
19
- static scriptExtensionPattern = /\.m?[tj]sx?$/i;
20
18
  static mappableKeys = [...BlockJSONManagingPlugin.mappableNonModuleKeys, ...BlockJSONManagingPlugin.mappableModuleKeys];
21
19
  static blockJsonToEntrypointsMap = new Map();
22
20
  static blockJsonRawDependenciesMap = new Map();
@@ -178,9 +176,9 @@ class BlockJSONManagingPlugin {
178
176
  const prefix = value.startsWith("./", 5) ? "./" : "";
179
177
  const relativePath = node_path_1.default.relative(node_path_1.default.dirname(name), entryMeta.path);
180
178
  const res = [`file:${prefix}${relativePath}`, entryMeta.hash];
181
- if (BlockJSONManagingPlugin.styleExtensionPattern.test(entryMeta.path)) {
179
+ if (shared_1.styleExtension.test(entryMeta.path)) {
182
180
  return [res,
183
- derivedFiles.filter(derivedFile => !BlockJSONManagingPlugin.scriptExtensionPattern.test(derivedFile))
181
+ derivedFiles.filter(derivedFile => !shared_1.scriptExtension.test(derivedFile))
184
182
  .map(derivedFile => `file:./${node_path_1.default.relative(node_path_1.default.dirname(name), derivedFile)}`)
185
183
  ];
186
184
  }
@@ -116,10 +116,33 @@ class PlainEntrypointsConfigFileGeneratorPlugin {
116
116
  customizer: [],
117
117
  analytics: []
118
118
  };
119
+ const allNamedHandles = (PlainEntrypointsConfigFileGeneratorPlugin.cache?.assets ?? [])
120
+ .flatMap(({ handles }) => handles)
121
+ .filter((handle) => !!handle.handleName)
122
+ .sort((a, b) => a.src.localeCompare(b.src));
123
+ const usedScriptHandleNames = Object.fromEntries(allNamedHandles
124
+ .filter(handle => handle.isScript)
125
+ .map(handle => [handle.handleName, handle.src]));
126
+ const usedStyleHandleNames = Object.fromEntries(allNamedHandles
127
+ .filter(handle => !handle.isScript)
128
+ .map(handle => [handle.handleName, handle.src]));
119
129
  const plainEntrypointsConfig = { scriptHandles: {}, styleHandles: {} };
120
130
  for (const { handles, handlePrefix } of PlainEntrypointsConfigFileGeneratorPlugin.cache?.assets ?? []) {
121
131
  for (const { src, rest, locations, isScript, handleName } of handles) {
122
- const finalHandleName = handleName || `${handlePrefix}.${kebabCase(node_path_1.default.basename(src))}`;
132
+ let finalHandleName;
133
+ if (handleName) {
134
+ finalHandleName = handleName;
135
+ }
136
+ else {
137
+ const basename = node_path_1.default.basename(src).replace(/_(?:script|style)(?:-\d+)?\.(?:css|js)$/, "");
138
+ const baseFinalHandleName = `${handlePrefix}.${kebabCase(basename)}`;
139
+ const handleNameMap = (isScript ? usedScriptHandleNames : usedStyleHandleNames);
140
+ finalHandleName = baseFinalHandleName;
141
+ for (let count = 0; finalHandleName in handleNameMap && handleNameMap[finalHandleName] !== src;) {
142
+ finalHandleName = `${baseFinalHandleName}-${++count}`;
143
+ }
144
+ handleNameMap[finalHandleName] = src;
145
+ }
123
146
  plainEntrypointsConfig[isScript ? 'scriptHandles' : 'styleHandles'][finalHandleName] = {
124
147
  src,
125
148
  rest,
package/build/shared.d.ts CHANGED
@@ -39,7 +39,7 @@ export type Externals = {
39
39
  [dep: string]: IndividualExternalDepConfig;
40
40
  };
41
41
  export type AdvancedOutputConfig = {
42
- destination: string;
42
+ destination?: string;
43
43
  withLegacyBlocksIn?: string | undefined;
44
44
  additionalDependencies?: string[];
45
45
  directoryLayout?: SourceType;
@@ -48,11 +48,12 @@ export type AdvancedOutputConfig = {
48
48
  bundleAnalyzer?: boolean;
49
49
  locations?: UsageLocations;
50
50
  };
51
+ export type VerifiedAdvancedOutputConfig = Omit<AdvancedOutputConfig, 'destination'> & Required<Pick<AdvancedOutputConfig, 'destination'>>;
51
52
  export type PlauditWordpressWebpackConfig = {
52
53
  standaloneBlocks?: boolean;
53
54
  variables?: Record<string, any>;
54
55
  verbose?: boolean;
55
- src: string[] | Record<string, string | AdvancedOutputConfig>;
56
+ src: string[] | Record<string, string | AdvancedOutputConfig | boolean>;
56
57
  stats?: Configuration['stats'];
57
58
  postcss?: {
58
59
  functions?: (variables: (name: string) => unknown) => PostcssFunctionsOptions['functions'];
@@ -67,6 +68,7 @@ export type PlauditWordpressWebpackConfig = {
67
68
  plainEntrypointsHandlePrefix?: string;
68
69
  plainEntrypointsVersion?: 1 | 2;
69
70
  srcDir?: string;
71
+ srcPrefixes?: string[];
70
72
  };
71
73
  export declare function makeEmittableConfigPHP(data: any): string;
72
74
  export type Sync<V> = {
@@ -85,4 +87,9 @@ export declare class SyncsManager<V> {
85
87
  private makeSync;
86
88
  }
87
89
  export declare function leadingSlashIt(pathOrSomething: string): string;
90
+ export declare const scriptExtension: RegExp;
91
+ export declare const scriptWithoutModuleExtension: RegExp;
92
+ export declare const scriptWithModuleExtension: RegExp;
93
+ export declare const styleExtension: RegExp;
94
+ export declare function scriptOrStyleTest(entryPath: string, scriptExtension: RegExp): "" | "script" | "style";
88
95
  export {};
package/build/shared.js CHANGED
@@ -3,11 +3,12 @@ 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.SyncsManager = exports.standardLocationNames = void 0;
6
+ exports.styleExtension = exports.scriptWithModuleExtension = exports.scriptWithoutModuleExtension = exports.scriptExtension = exports.SyncsManager = exports.standardLocationNames = void 0;
7
7
  exports.isRawAssetData = isRawAssetData;
8
8
  exports.determineCurrentSourceType = determineCurrentSourceType;
9
9
  exports.makeEmittableConfigPHP = makeEmittableConfigPHP;
10
10
  exports.leadingSlashIt = leadingSlashIt;
11
+ exports.scriptOrStyleTest = scriptOrStyleTest;
11
12
  const json_to_php_but_with____injection_1 = __importDefault(require("./utils/json-to-php-but-with-__-injection"));
12
13
  function isRawAssetData(thing) {
13
14
  if (!thing || typeof thing !== 'object') {
@@ -70,3 +71,10 @@ exports.SyncsManager = SyncsManager;
70
71
  function leadingSlashIt(pathOrSomething) {
71
72
  return pathOrSomething.startsWith('/') ? pathOrSomething : ('/' + pathOrSomething);
72
73
  }
74
+ exports.scriptExtension = /(?<filename>.+)(?<extension>\.m?[jt]sx?)$/i;
75
+ exports.scriptWithoutModuleExtension = /(?<filename>.+)(?<extension>\.[jt]sx?)$/i;
76
+ exports.scriptWithModuleExtension = /(?<filename>.+)(?<extension>\.m[jt]sx?)$/i;
77
+ exports.styleExtension = /(?<filename>.+)(?<extension>\.(p?c|sa)ss)$/i;
78
+ function scriptOrStyleTest(entryPath, scriptExtension) {
79
+ return scriptExtension.test(entryPath) ? "script" : (exports.styleExtension.test(entryPath) ? "style" : "");
80
+ }
@@ -1,4 +1,4 @@
1
- import type { AdvancedOutputConfig, PlauditWordpressWebpackConfig } from "../shared";
1
+ import { 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'>> & {
@@ -16,11 +16,7 @@ export type CommonConfigProcessingResult = {
16
16
  scriptExtension: RegExp;
17
17
  updateCurrentVariables: (value: VerifiedPlauditWordpressWebpackConfig['currentVariables']) => unknown;
18
18
  };
19
- export declare const scriptWithoutModuleExtension: RegExp;
20
- export declare const scriptWithModuleExtension: RegExp;
21
- export declare const styleExtension: RegExp;
22
- export declare function scriptOrStyleTest(entryPath: string, scriptExtension: RegExp): "" | "script" | "style";
23
19
  export declare function joinPossiblyAbsolutePaths(...paths: (string | undefined)[]): string;
24
20
  export declare function groupEntrypointsByAssetFile<T>(entrypoints: T[], entrypointNameExtractor: (t: T) => string): Map<string, T[]>;
25
- export declare function resolveEntryFromDirectory(commonConfig: CommonConfigProcessingResult, srcRoot: string, dest: AdvancedOutputConfig): () => Promise<EntryObject>;
26
- export declare function commonMakeWebpackConfig(config: VerifiedPlauditWordpressWebpackConfig, commonConfig: CommonConfigProcessingResult, webpackConfig: Configuration, srcIsDirectory: boolean, dest: string | AdvancedOutputConfig, src: string, srcRoot: string | string[], entry: () => Promise<EntryObject> | EntryObject, plugins: CommonPluginConfig['plugins']): Configuration;
21
+ export declare function resolveEntryFromDirectory(commonConfig: CommonConfigProcessingResult, srcRoot: string, dest: VerifiedAdvancedOutputConfig): () => Promise<EntryObject>;
22
+ export declare function commonMakeWebpackConfig(config: VerifiedPlauditWordpressWebpackConfig, commonConfig: CommonConfigProcessingResult, webpackConfig: Configuration, srcIsDirectory: boolean, dest: VerifiedAdvancedOutputConfig, src: string, srcRoot: string | string[], entry: () => Promise<EntryObject> | EntryObject, plugins: CommonPluginConfig['plugins']): Configuration;
@@ -3,23 +3,16 @@ 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 = void 0;
7
- exports.scriptOrStyleTest = scriptOrStyleTest;
8
6
  exports.joinPossiblyAbsolutePaths = joinPossiblyAbsolutePaths;
9
7
  exports.groupEntrypointsByAssetFile = groupEntrypointsByAssetFile;
10
8
  exports.resolveEntryFromDirectory = resolveEntryFromDirectory;
11
9
  exports.commonMakeWebpackConfig = commonMakeWebpackConfig;
12
10
  const node_fs_1 = __importDefault(require("node:fs"));
13
11
  const node_path_1 = __importDefault(require("node:path"));
12
+ const shared_1 = require("../shared");
14
13
  const copy_webpack_plugin_1 = __importDefault(require("copy-webpack-plugin"));
15
14
  const promises_1 = __importDefault(require("node:fs/promises"));
16
15
  const BlockJSONManagingPlugin_1 = require("../plugins/BlockJSONManagingPlugin");
17
- exports.scriptWithoutModuleExtension = /\.[jt]sx?$/;
18
- exports.scriptWithModuleExtension = /\.m[jt]sx?$/;
19
- exports.styleExtension = /\.(p?c|sa)ss$/;
20
- function scriptOrStyleTest(entryPath, scriptExtension) {
21
- return scriptExtension.test(entryPath) ? "script" : (exports.styleExtension.test(entryPath) ? "style" : "");
22
- }
23
16
  let isInThemeCache = undefined;
24
17
  function isInTheme() {
25
18
  return isInThemeCache ?? (isInThemeCache = node_fs_1.default.existsSync(node_path_1.default.join(process.cwd(), "theme.json")));
@@ -77,21 +70,21 @@ function parseEntrypointsJSON(dir, dest) {
77
70
  }
78
71
  }
79
72
  function determineEntrypointType(entrypoint, scriptExtension) {
80
- let res = scriptOrStyleTest(entrypoint[0], scriptExtension);
73
+ let res = (0, shared_1.scriptOrStyleTest)(entrypoint[0], scriptExtension);
81
74
  if (res) {
82
75
  return res;
83
76
  }
84
77
  if (typeof entrypoint[1] === 'string') {
85
- return scriptOrStyleTest(entrypoint[1], scriptExtension);
78
+ return (0, shared_1.scriptOrStyleTest)(entrypoint[1], scriptExtension);
86
79
  }
87
80
  else if (Array.isArray(entrypoint[1])) {
88
- return entrypoint[1].reduce((prior, ep) => prior || scriptOrStyleTest(ep, scriptExtension), "");
81
+ return entrypoint[1].reduce((prior, ep) => prior || (0, shared_1.scriptOrStyleTest)(ep, scriptExtension), "");
89
82
  }
90
83
  else if (typeof entrypoint[1].import === 'string') {
91
- return scriptOrStyleTest(entrypoint[1].import, scriptExtension);
84
+ return (0, shared_1.scriptOrStyleTest)(entrypoint[1].import, scriptExtension);
92
85
  }
93
86
  else {
94
- return entrypoint[1].import.reduce((prior, ep) => prior || scriptOrStyleTest(ep, scriptExtension), "");
87
+ return entrypoint[1].import.reduce((prior, ep) => prior || (0, shared_1.scriptOrStyleTest)(ep, scriptExtension), "");
95
88
  }
96
89
  }
97
90
  function injectTypeAndCountToEntrypointName(entrypointName, type, typeCounts) {
@@ -260,13 +253,13 @@ function commonMakeWebpackConfig(config, commonConfig, webpackConfig, srcIsDirec
260
253
  else {
261
254
  outputLibrary = webpackConfig.output?.library;
262
255
  }
263
- const canCopyFiles = srcIsDirectory && src !== dest;
256
+ const canCopyFiles = srcIsDirectory && src !== dest.destination;
264
257
  const possiblePlugins = canCopyFiles
265
258
  ? plugins.map(plugin => !processingModules && plugin.constructor.name === 'CopyPlugin'
266
259
  ? new copy_webpack_plugin_1.default({
267
260
  patterns: [{
268
261
  from: standaloneBlocks ? '**/(block.json|*.(php|twig|svg))' : '**/(block.json|*.(asset\.php|svg))',
269
- to: typeof dest === 'string' ? dest : dest.destination,
262
+ to: dest.destination,
270
263
  context: srcRoot /* canCopyFiles can only be true if srcRoot is a string, so this is safe */, noErrorOnMissing: true
271
264
  }]
272
265
  })
@@ -22,7 +22,7 @@ class Expr {
22
22
  exports.Expr = Expr;
23
23
  class PHPWriter {
24
24
  inlineFirstLine;
25
- buffer = "";
25
+ buffer = [];
26
26
  indentation = "";
27
27
  printingInPHP = true;
28
28
  fileNamespace = "";
@@ -40,7 +40,7 @@ class PHPWriter {
40
40
  }
41
41
  append(...lines) {
42
42
  for (const line of lines) {
43
- this.buffer += `\n${this.indentation}${line}`;
43
+ this.buffer.push(`${this.indentation}${line}`);
44
44
  }
45
45
  return this;
46
46
  }
@@ -57,7 +57,7 @@ class PHPWriter {
57
57
  return this;
58
58
  }
59
59
  linebreak() {
60
- this.buffer += '\n';
60
+ this.buffer.push("");
61
61
  return this;
62
62
  }
63
63
  call(func, args, opts = {}) {
@@ -166,21 +166,25 @@ class PHPWriter {
166
166
  return this;
167
167
  }
168
168
  toString() {
169
- let fileContents = "";
169
+ const fileContents = [];
170
+ let canInline = true;
170
171
  if (this.fileNamespace) {
171
- fileContents += `\nnamespace ${this.fileNamespace};\n`;
172
+ canInline = false;
173
+ fileContents.push(`namespace ${this.fileNamespace};`);
172
174
  }
173
- if (this.useList) {
174
- for (const use of this.useList.toSorted()) {
175
- fileContents += `\nuse ${use};`;
176
- }
177
- fileContents += "\n";
175
+ if (this.useList.length) {
176
+ canInline = false;
177
+ fileContents.push(...this.useList.map(use => `use ${use};`));
178
+ }
179
+ fileContents.push(...this.buffer);
180
+ if (this.inlineFirstLine && canInline) {
181
+ return `<?php ${fileContents.join("\n")}`;
178
182
  }
179
- if (this.inlineFirstLine && !fileContents) {
180
- return `<?php ${this.buffer.trimStart()}`;
183
+ else if (fileContents.find(line => line.length > 0)) {
184
+ return "<?php\n" + fileContents.join("\n");
181
185
  }
182
186
  else {
183
- return "<?php" + fileContents + this.buffer;
187
+ return "<?php";
184
188
  }
185
189
  }
186
190
  emitAsset(compilation, file, assetInfo) {
@@ -36,8 +36,10 @@ function resolveLegacyBlockScriptsInFolder(folder) {
36
36
  }
37
37
  return blockScriptEntrypoints;
38
38
  }
39
- function testForDuplicatedEntryPaths(config) {
40
- const seenPaths = (0, common_config_helpers_1.groupEntrypointsByAssetFile)(Array.isArray(config.src) ? config.src : Object.values(config.src).map(bn => typeof bn === 'string' ? bn : bn.destination), bn => bn);
39
+ function testForDuplicatedEntryPaths(sources) {
40
+ const seenPaths = (0, common_config_helpers_1.groupEntrypointsByAssetFile)(Array.isArray(sources)
41
+ ? sources.map(s => typeof s === 'string' ? s : s[1].destination)
42
+ : Object.values(sources).map(bn => typeof bn === 'string' ? bn : bn.destination), bn => bn);
41
43
  let projectPrefix = undefined;
42
44
  let duplicatedPaths = "";
43
45
  for (const sameNamePaths of seenPaths.values()) {
@@ -166,8 +168,15 @@ function injectSupportForInliningSVGsAsStrings(rules) {
166
168
  });
167
169
  }
168
170
  function buildVerifiedConfig(config) {
169
- testForDuplicatedEntryPaths(config);
170
171
  const { standaloneBlocks = false, stats = 'errors-warnings', variables: rawVariables, verbose = process.argv.includes('--verbose') || process.env['VERBOSE'] === 'true', postcss = {}, externals, assumeGlobalizedPlauditLibraries = true, processTranslationConfigs = true, combineAssetMetadata = true, useWebpackResourceFiltering = true, outputDir = "", extensionsVersion = 1, plainEntrypointsHandlePrefix = "", plainEntrypointsVersion = 1, srcDir = "" } = config;
172
+ let srcPrefixes;
173
+ const trailingSlashedSrcDir = srcDir && !srcDir.endsWith("/") ? srcDir + "/" : srcDir;
174
+ if (config.srcPrefixes === undefined) {
175
+ srcPrefixes = srcDir ? [trailingSlashedSrcDir] : ["src/"];
176
+ }
177
+ else {
178
+ srcPrefixes = (srcDir && !config.srcPrefixes.includes(trailingSlashedSrcDir) ? [...config.srcPrefixes, trailingSlashedSrcDir] : config.srcPrefixes);
179
+ }
171
180
  if (plainEntrypointsVersion > 1) {
172
181
  if (!plainEntrypointsHandlePrefix) {
173
182
  throw new Error("Plain Entrypoints V2 and higher require 'plainEntrypointsHandlePrefix' to be set");
@@ -176,6 +185,47 @@ function buildVerifiedConfig(config) {
176
185
  throw new Error("Plain Entrypoints V2 and higher require 'outputDir' to be set");
177
186
  }
178
187
  }
188
+ const normalizeSrcAndDestination = ([src, dest]) => {
189
+ if (srcDir) {
190
+ src = node_path_1.default.join(srcDir, src);
191
+ }
192
+ src = node_path_1.default.isAbsolute(src) ? node_path_1.default.relative(process.cwd(), src) : src;
193
+ if (dest.destination !== undefined && node_path_1.default.isAbsolute(dest.destination)) {
194
+ dest = { ...dest, destination: node_path_1.default.relative(process.cwd(), dest.destination) };
195
+ }
196
+ return [src, dest];
197
+ };
198
+ const rawSources = Array.isArray(config.src)
199
+ ? config.src.map(s => normalizeSrcAndDestination([s, { destination: s }]))
200
+ : Object.entries(config.src)
201
+ .map(([k, v]) => {
202
+ return normalizeSrcAndDestination([k, typeof v === 'boolean' ? {} : (typeof v === 'string' ? { destination: v } : v)]);
203
+ });
204
+ // Destination -> source map
205
+ const allocatedDestinations = {};
206
+ const partiallyVerifiedSources = rawSources.map(rawSource => {
207
+ const destination = rawSource[1].destination;
208
+ if (destination !== undefined) {
209
+ const effectiveDestination = toEffectiveWebpackDestination(destination);
210
+ allocatedDestinations[effectiveDestination] = rawSource[0]; // We need to pre-populate the allocatedDestinations map with statically-declared destinations
211
+ return [rawSource[0], { ...rawSource[1], destination, effectiveDestination, staticallyDeclaredDestination: true }];
212
+ }
213
+ else {
214
+ const naiveDestination = deriveNaiveDestinationFromUnverifiedSourceEntry(rawSource, srcPrefixes);
215
+ const effectiveDestination = toEffectiveWebpackDestination(naiveDestination);
216
+ return [rawSource[0], { ...rawSource[1], destination: naiveDestination, effectiveDestination, staticallyDeclaredDestination: false }];
217
+ }
218
+ });
219
+ const dynamicEffectiveDestinationsWithExpectedNaiveDuplicates = partiallyVerifiedSources
220
+ .filter(entry => !entry[1].staticallyDeclaredDestination)
221
+ .map(entry => entry[1].effectiveDestination)
222
+ .reduce((a, dest) => {
223
+ a[dest] = (a[dest] !== undefined); // 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
224
+ return a;
225
+ }, {});
226
+ const sources = partiallyVerifiedSources
227
+ .map(entry => finalizeEntryDestination(entry, dynamicEffectiveDestinationsWithExpectedNaiveDuplicates, allocatedDestinations));
228
+ testForDuplicatedEntryPaths(sources);
179
229
  let variablesFilePath = undefined;
180
230
  const currentVariables = rawVariables ?? {};
181
231
  if (!rawVariables) {
@@ -183,22 +233,53 @@ function buildVerifiedConfig(config) {
183
233
  }
184
234
  const cfg = {
185
235
  currentVariables, postcss, standaloneBlocks, stats, variablesFilePath, verbose, externals, assumeGlobalizedPlauditLibraries, processTranslationConfigs, combineAssetMetadata,
186
- useWebpackResourceFiltering, outputDir, extensionsVersion, plainEntrypointsVersion, plainEntrypointsHandlePrefix, srcDir
236
+ useWebpackResourceFiltering, outputDir, extensionsVersion, plainEntrypointsVersion, plainEntrypointsHandlePrefix, srcDir, srcPrefixes
187
237
  };
188
- const sources = (Array.isArray(config.src) ? config.src.map(s => [s, s]) : Object.entries(config.src))
189
- .map(entry => {
190
- let dest = typeof entry[1] === 'string' ? { destination: entry[1] } : entry[1];
191
- if (srcDir) {
192
- return [node_path_1.default.join(srcDir, entry[0]), dest];
193
- }
194
- const relativeSrc = node_path_1.default.isAbsolute(entry[0]) ? node_path_1.default.relative(process.cwd(), entry[0]) : entry[0];
195
- if (node_path_1.default.isAbsolute(dest.destination)) {
196
- dest = { ...dest, destination: node_path_1.default.relative(process.cwd(), dest.destination) };
197
- }
198
- return [relativeSrc, dest];
199
- });
200
238
  return cfg.outputDir ? { cfg, sources } : withDerivedOutputDir(cfg, sources);
201
239
  }
240
+ function toEffectiveWebpackDestination(destination) {
241
+ const pathParts = node_path_1.default.parse(destination);
242
+ return node_path_1.default.join(pathParts.dir, pathParts.name);
243
+ }
244
+ function deriveNaiveDestinationFromUnverifiedSourceEntry([src, { destination }], srcPrefixes) {
245
+ if (destination !== undefined) {
246
+ return destination;
247
+ }
248
+ const commaIndex = src.indexOf(',');
249
+ const primarySource = stripSrcPrefix(commaIndex > -1 ? src.substring(0, commaIndex).trim() : src, srcPrefixes);
250
+ const scriptParts = shared_1.scriptExtension.exec(primarySource);
251
+ if (scriptParts !== null) {
252
+ return `${scriptParts.groups['filename']}.js`; // filename is always defined here
253
+ }
254
+ const styleParts = shared_1.styleExtension.exec(primarySource);
255
+ if (styleParts !== null) {
256
+ return `${styleParts.groups['filename']}.css`; // filename is always defined here
257
+ }
258
+ return primarySource;
259
+ }
260
+ function stripSrcPrefix(src, srcPrefixes) {
261
+ const prefix = srcPrefixes.find(sp => src.startsWith(sp));
262
+ if (!prefix) {
263
+ return src;
264
+ }
265
+ return src[prefix.length] === '/' ? src.substring(prefix.length + 1) : src.substring(prefix.length);
266
+ }
267
+ function finalizeEntryDestination(entry, dynamicEffectiveDestinationsWithExpectedNaiveDuplicates, allocatedDestinations) {
268
+ if (entry[1].staticallyDeclaredDestination) {
269
+ return entry;
270
+ }
271
+ //TODO: Maybe try to figure out a way to avoid generated handles unnecessarily including "_script" and "_style"
272
+ const extension = node_path_1.default.extname(entry[1].destination);
273
+ const filename = dynamicEffectiveDestinationsWithExpectedNaiveDuplicates[entry[1].effectiveDestination]
274
+ ? entry[1].effectiveDestination + (extension === '.css' ? "_script" : "_style")
275
+ : entry[1].effectiveDestination;
276
+ let count = 0, derivedDestination = filename + extension;
277
+ while (derivedDestination in allocatedDestinations && allocatedDestinations[derivedDestination] !== entry[0]) {
278
+ derivedDestination = `${filename}_${++count}${extension}`; // We don't want to add deduplication indexes unless absolutely necessary
279
+ }
280
+ allocatedDestinations[derivedDestination] = entry[0];
281
+ return [entry[0], { ...entry[1], destination: derivedDestination }];
282
+ }
202
283
  function withDerivedOutputDir(cfg, sources) {
203
284
  const destinations = sources.map(([_, { destination }]) => destination.split(/[\/\\]/g));
204
285
  if (destinations.length < 2) {
@@ -220,7 +301,7 @@ function withDerivedOutputDir(cfg, sources) {
220
301
  function handleDisablingTSCheckerIfNecessary(srcRoot, scriptExtension, plugins) {
221
302
  if (process.env["NO_TS_CHECKER"] !== "true") {
222
303
  const include = (Array.isArray(srcRoot) ? srcRoot : [srcRoot])
223
- .filter(sr => node_path_1.default.extname(sr).length === 0 || (0, common_config_helpers_1.scriptOrStyleTest)(sr, scriptExtension) === "script")
304
+ .filter(sr => node_path_1.default.extname(sr).length === 0 || (0, shared_1.scriptOrStyleTest)(sr, scriptExtension) === "script")
224
305
  .map(sr => node_path_1.default.extname(sr).length > 0 ? sr : node_path_1.default.join(sr, "**", "*"));
225
306
  if (include.length > 0) {
226
307
  plugins.push(new fork_ts_checker_webpack_plugin_1.default({
@@ -264,7 +345,7 @@ function buildCommonPluginConfig(srcRoot, scriptExtension, webpackConfig, dest,
264
345
  })
265
346
  ?? [];
266
347
  plugins.splice(0, 0, new PackageConfigSanityChecker_1.PackageConfigSanityChecker());
267
- if (typeof dest !== 'string' && dest.bundleAnalyzer) {
348
+ if (dest.bundleAnalyzer) {
268
349
  plugins.splice(0, 0, new (require("webpack-bundle-analyzer").BundleAnalyzerPlugin)({ analyzerMode: 'static' }));
269
350
  }
270
351
  handleDisablingTSCheckerIfNecessary(srcRoot, scriptExtension, plugins);
@@ -279,19 +360,19 @@ function buildCommonPluginConfig(srcRoot, scriptExtension, webpackConfig, dest,
279
360
  if (variablesFilePath) {
280
361
  plugins.push(new VariablesJSMonitorPlugin_1.VariablesJSMonitorPlugin(variablesFilePath));
281
362
  }
282
- const pluginIndex = plugins.findIndex(plugin => plugin instanceof dependency_extraction_webpack_plugin_1.default);
283
- if (pluginIndex === -1) {
363
+ const dependencyExtractionPluginIndex = plugins.findIndex(plugin => plugin instanceof dependency_extraction_webpack_plugin_1.default);
364
+ if (dependencyExtractionPluginIndex === -1) {
284
365
  console.error("Cannot apply externals when they have been disabled via CLI flag. This will greatly increase bundle size and will likely cause the build to fail");
285
366
  }
286
367
  else {
287
- const localAssumeGlobalizedPlauditLibraries = (typeof dest !== 'string' ? dest.assumeGlobalizedPlauditLibraries : undefined) ?? assumeGlobalizedPlauditLibraries;
368
+ const localAssumeGlobalizedPlauditLibraries = dest.assumeGlobalizedPlauditLibraries ?? assumeGlobalizedPlauditLibraries;
288
369
  const wantsGroupedDepData = combineAssetMetadata
289
370
  && ((!processingModules && sourceType === "blocks" /* SourceType.blocks */)
290
371
  || (extensionsVersion > 1 && sourceType === "extensions" /* SourceType.extensions */)
291
372
  || (plainEntrypointsVersion > 1 && sourceType === "plain" /* SourceType.plain */));
292
- const builtDependencyExtractionWebpackPlugin = (0, dependency_extraction_webpack_plugin_config_builder_1.makeDependencyExtractionPlugin)(externals, localAssumeGlobalizedPlauditLibraries, wantsGroupedDepData, typeof dest !== 'string' ? dest.externalize : undefined);
293
- plugins[pluginIndex] = builtDependencyExtractionWebpackPlugin.instance;
294
- plugins.push(new AdditionalDependencyInjectorPlugin_1.AdditionalDependencyInjectorPlugin(typeof dest !== 'string' && dest.additionalDependencies ? dest.additionalDependencies : [], processingModules, builtDependencyExtractionWebpackPlugin.addExternalizedDep));
373
+ const builtDependencyExtractionWebpackPlugin = (0, dependency_extraction_webpack_plugin_config_builder_1.makeDependencyExtractionPlugin)(externals, localAssumeGlobalizedPlauditLibraries, wantsGroupedDepData, dest.externalize);
374
+ plugins[dependencyExtractionPluginIndex] = builtDependencyExtractionWebpackPlugin.instance;
375
+ plugins.push(new AdditionalDependencyInjectorPlugin_1.AdditionalDependencyInjectorPlugin(dest.additionalDependencies ? dest.additionalDependencies : [], processingModules, builtDependencyExtractionWebpackPlugin.addExternalizedDep));
295
376
  }
296
377
  if (process.argv.includes('--browser-sync') || process.env['BROWSER_SYNC'] === 'true') {
297
378
  plugins.push(new BrowserSyncPlugin_1.BrowserSyncPlugin());
@@ -303,11 +384,11 @@ function commonConfigProcessingPrep(config, webpackConfig) {
303
384
  let entrypointFields;
304
385
  const processingModules = webpackConfig.output?.module;
305
386
  if (processingModules) {
306
- scriptExtension = common_config_helpers_1.scriptWithModuleExtension;
387
+ scriptExtension = shared_1.scriptWithModuleExtension;
307
388
  entrypointFields = ["viewScriptModule", "scriptModule"];
308
389
  }
309
390
  else {
310
- scriptExtension = common_config_helpers_1.scriptWithoutModuleExtension;
391
+ scriptExtension = shared_1.scriptWithoutModuleExtension;
311
392
  entrypointFields = ["editorStyle", "viewStyle", "style", "editorScript", "viewScript", "script"];
312
393
  }
313
394
  let currentVariables = config.currentVariables;
@@ -333,6 +414,7 @@ function commonConfigProcessingPrep(config, webpackConfig) {
333
414
  updateCurrentVariables: (value) => currentVariables = value
334
415
  };
335
416
  }
417
+ //TODO: Implement path deduplication w/ the same code we use for block.json (only for plain v2 w/ specified handles
336
418
  //TODO: Try using context to avoid needing to cobble dest paths together?
337
419
  function processIndividualWebpackConfig(config, webpackConfig, sources) {
338
420
  const commonConfig = commonConfigProcessingPrep(config, webpackConfig);
@@ -340,7 +422,7 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
340
422
  return sources.map(([src, dest]) => {
341
423
  const srcRoots = (dest.withLegacyBlocksIn
342
424
  ? [...src.split(','), ...resolveLegacyBlockScriptsInFolder(node_path_1.default.join(config.srcDir, dest.withLegacyBlocksIn))]
343
- : src.split(',')).filter(s => s.endsWith(".json") || !s.substring(s.lastIndexOf('/')).includes('.') || processingModules === common_config_helpers_1.scriptWithModuleExtension.test(s));
425
+ : src.split(',')).filter(s => s.endsWith(".json") || !s.substring(s.lastIndexOf('/')).includes('.') || processingModules === shared_1.scriptWithModuleExtension.test(s));
344
426
  const srcRoot = srcRoots.length < 2 ? (0, common_config_helpers_1.joinPossiblyAbsolutePaths)(process.cwd(), src) : srcRoots.map(s => (0, common_config_helpers_1.joinPossiblyAbsolutePaths)(process.cwd(), s));
345
427
  const srcIsDirectory = !Array.isArray(srcRoot) && node_fs_1.default.lstatSync(srcRoot, { throwIfNoEntry: false })?.isDirectory();
346
428
  if (srcIsDirectory === undefined) {
@@ -387,7 +469,7 @@ function makeExtensionsWebpackConfig(config, commonConfig, webpackConfig, dest,
387
469
  const rawEntrypoints = [];
388
470
  for await (const dirent of await promises_1.default.opendir(srcRoot)) {
389
471
  if (dirent.isFile() && !dirent.name.startsWith("~")) {
390
- if (commonConfig.scriptExtension.test(dirent.name) || common_config_helpers_1.styleExtension.test(dirent.name)) {
472
+ if (commonConfig.scriptExtension.test(dirent.name) || shared_1.styleExtension.test(dirent.name)) {
391
473
  const file = (0, common_config_helpers_1.joinPossiblyAbsolutePaths)(srcRoot, dirent.name);
392
474
  rawEntrypoints.push([node_path_1.default.join(dest.destination, node_path_1.default.basename(file, node_path_1.default.extname(file))), file]);
393
475
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plaudit/webpack-extensions",
3
- "version": "2.55.0",
3
+ "version": "2.56.0",
4
4
  "license": "UNLICENSED",
5
5
  "files": [
6
6
  "/build"