@plaudit/webpack-extensions 2.96.2 → 2.97.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/CHANGELOG.md CHANGED
@@ -60,6 +60,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
60
60
  - Legacy PostCSS features that have been integrated into modern CSS
61
61
  - `@extends` support
62
62
 
63
+ ## [2.97.0] - 2026-08-18
64
+ ### Added
65
+ - David's improvements to build pipeline efficiency
66
+ - Support for David's `@plaudit/dev-webpack-plugin`
67
+
68
+ ### Changed
69
+ - To Webpack's standard plugin interface (`WebpackPluginInstance`)
70
+
71
+ ### Removed
72
+ - Browsersync tests
73
+
74
+ ## [2.96.3] - 2026-08-11
75
+ ### Added
76
+ - A few more validation checks
77
+
63
78
  ## [2.96.2] - 2026-08-11
64
79
  ### Removed
65
80
  - `processTranslationConfigs` because it should not be used and didn't actually do anything
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Plaudit Webpack Extensions
2
- A webpack configuration and plugin suite designed specifically for WordPress development workflows. This package extends `@wordpress/scripts` with custom webpack plugins, PostCSS configurations, and build optimizations tailored for Plaudit's WordPress projects. It includes specialized handling for Gutenberg blocks, asset management, internationalization (WPML), and development tooling like BrowserSync integration.
2
+ A webpack configuration and plugin suite designed specifically for WordPress development workflows. This package extends `@wordpress/scripts` with custom webpack plugins, PostCSS configurations, and build optimizations tailored for Plaudit's WordPress projects. It includes specialized handling for Gutenberg blocks, asset management, internationalization (WPML), and a same-origin CSS-inject / live-reload client for `wp-scripts start`.
3
3
 
4
4
  # Requirements
5
5
  - All block- and extension-related capabilities require that the `plaudit/plaudit-common` composer library be installed.
@@ -23,7 +23,27 @@ This suite generates loader code that uses the most efficient mechanisms availab
23
23
  The same file structure (both in the webpack.config.js file and the actual directory tree) can be used in plugins and themes.
24
24
 
25
25
  # Usage
26
- Check out the [User Guide](USER-GUIDE.md) file.
26
+ Config, entry types, and handles: [User Guide](USER-GUIDE.md).
27
+
28
+ ## `dist` vs `dist-dev`
29
+
30
+ With the unified loader (site `standard`), `outputDir` is `dist`. When `SERVER_MODE` is `development` (the default if unset on the host) and `omitDistDev` is off, webpack writes **`dist-dev`**. WordPress in development loads that folder via `dist/unified-loader.php` when `dist-dev/unified-loader.php` exists. Production WordPress always uses **`dist`**.
31
+
32
+ `SERVER_MODE` chooses the folder. The compiler (`mode`, minify, webpack cache) is always production for `dist`. For `dist-dev` it follows `NODE_ENV`: `wp-scripts start` is development (no minify, cache on); `wp-scripts build` is production (minify, cache off) still written to `dist-dev`.
33
+
34
+ `dev-reload.js` / overlay run only for `pnpm run dev` (`BROWSER_SYNC` + watch) and only under `dist-dev`. Pass `--no-dev-reload` after `--` (or `DEV_RELOAD=0`) to skip the overlay and live reload: `pnpm run dev -- --no-dev-reload`. Docker still starts and the browser still opens. The `--` is required so webpack-cli does not treat the flag as an unknown option.
35
+
36
+ | Command | Folder | Compiler | Overlay |
37
+ |-----------------------------------------|------------|------------------------------------------------------------------|---------|
38
+ | `pnpm run dev` | `dist-dev` | development (no minify, cache on) | yes |
39
+ | `pnpm run dev -- --no-dev-reload` | `dist-dev` | development (no minify, cache on) | no |
40
+ | `pnpm run watch` | `dist-dev` | development (no minify, cache on) | no |
41
+ | `pnpm run build` | `dist-dev` | production (minify, cache off) | no |
42
+ | `SERVER_MODE=production pnpm run build` | `dist` | same production compiler as `pnpm run build` (minify, cache off) | no |
43
+
44
+ The last row is the same compile as a local `build`; only the folder changes. That is what ships: `@plaudit/toolbox` (`toolbox init`) installs a **pre-commit** hook that runs `pnpm … build` with `SERVER_MODE=production` and stages `wp-content/**/dist/**`. A plain `pnpm run build` on your machine does **not** update `dist` unless you set `SERVER_MODE` yourself. `SKIP_BUILD=1` skips the hook build.
45
+
46
+ See [Plaudit - Dev Webpack Plugin](https://github.com/plaudit/dev-webpack-plugin#readme) for more details
27
47
 
28
48
  # Development
29
49
 
package/USER-GUIDE.md CHANGED
@@ -8,6 +8,7 @@
8
8
  * [Examples](#examples)
9
9
  * [Best Practices](#best-practices)
10
10
  * [Folder Structure](#folder-structure)
11
+ * [Enforced Naming Conventions](#enforced-naming-conventions)
11
12
  * [Blocks](#blocks)
12
13
  * [Extensions](#extensions)
13
14
  * [Plain Assets](#plain-assets)
@@ -189,11 +190,13 @@ This file automatically:
189
190
  - Sets up blocks and extensions
190
191
 
191
192
  ### 4. Run Build Commands
192
- While you *can* manually run these commands, using `theapp pack dev/watch/build` is preferred
193
+ While you *can* manually run these commands, using `theapp pack dev/watch/build` is preferred.
194
+
195
+ Typical theme/plugin scripts are `watch`, `dev`, and `build`. Which folder they write (`dist` vs `dist-dev`) and whether the compiler minifies is in the package [README](README.md#dist-vs-dist-dev) — a local `pnpm run build` is a production compile into `dist-dev`, not into `dist`.
193
196
 
194
197
  ```bash
195
- pnpm run watch # Development mode (watches for changes)
196
- pnpm run build # Production build
198
+ pnpm run watch # Watch; writes dist-dev
199
+ pnpm run build # One-shot production compile into dist-dev
197
200
  ```
198
201
 
199
202
  ---
@@ -1,7 +1,7 @@
1
- import { Compilation, Compiler } from "webpack";
1
+ import { Compilation, Compiler, type WebpackPluginInstance } from "webpack";
2
2
  import { PseudoSemaphore } from "../utils/pseduo-semaphore";
3
3
  import type { VerifiedPlauditWordpressWebpackConfig } from "../utils/common-config-helpers";
4
- import { type ParsedAssetJsonProvider, WebpackPlugin } from "../shared";
4
+ import { type ParsedAssetJsonProvider } from "../shared";
5
5
  type TapWithAssetsJsonOptions = {
6
6
  name?: string;
7
7
  stage?: (typeof Compilation.PROCESS_ASSETS_STAGE_REPORT) | (typeof Compilation.PROCESS_ASSETS_STAGE_ANALYSE);
@@ -9,7 +9,7 @@ type TapWithAssetsJsonOptions = {
9
9
  };
10
10
  type TapWithAssetsJsonFn = Parameters<Compilation['hooks']['processAssets']['tapPromise']>[1];
11
11
  type TapWithParsedAssetsJsonFn = (parsedAssetJsonProvider: ParsedAssetJsonProvider, assets: Parameters<TapWithAssetsJsonFn>[0]) => Promise<void> | void;
12
- export declare abstract class AbstractBiPhasicGroupPlugin implements WebpackPlugin {
12
+ export declare abstract class AbstractBiPhasicGroupPlugin implements WebpackPluginInstance {
13
13
  protected readonly config: VerifiedPlauditWordpressWebpackConfig;
14
14
  readonly group: string;
15
15
  private readonly semaphores;
@@ -1,5 +1,4 @@
1
- import type { Compiler } from "webpack";
2
- import type { WebpackPlugin } from "../shared";
3
- export declare class MiniCSSExtractPluginErrorCleaner implements WebpackPlugin {
1
+ import type { Compiler, WebpackPluginInstance } from "webpack";
2
+ export declare class MiniCSSExtractPluginErrorCleaner implements WebpackPluginInstance {
4
3
  apply(compiler: Compiler): void;
5
4
  }
@@ -1,5 +1,4 @@
1
- import type { Compiler } from "webpack";
2
- import type { WebpackPlugin } from "../shared";
3
- export declare class PackageConfigSanityChecker implements WebpackPlugin {
1
+ import type { Compiler, WebpackPluginInstance } from "webpack";
2
+ export declare class PackageConfigSanityChecker implements WebpackPluginInstance {
4
3
  apply(compiler: Compiler): void;
5
4
  }
@@ -1,7 +1,6 @@
1
1
  import type { VerifiedPlauditWordpressWebpackConfig } from "../utils/common-config-helpers";
2
- import type { Compiler } from "webpack";
3
- import type { WebpackPlugin } from "../shared";
4
- export declare class VariablesJSMonitorPlugin implements WebpackPlugin {
2
+ import type { Compiler, WebpackPluginInstance } from "webpack";
3
+ export declare class VariablesJSMonitorPlugin implements WebpackPluginInstance {
5
4
  private readonly config;
6
5
  constructor(config: VerifiedPlauditWordpressWebpackConfig);
7
6
  apply(compiler: Compiler): void;
@@ -1,7 +1,6 @@
1
- import { type WebpackPlugin } from "../shared";
2
1
  import { AbstractBiPhasicGroupAndEntryPlugin } from "./AbstractBiPhasicGroupAndEntryPlugin";
3
- import { type Compiler } from "webpack";
4
- export declare class WPMLConfigBuilderPlugin implements WebpackPlugin {
2
+ import { type Compiler, type WebpackPluginInstance } from "webpack";
3
+ export declare class WPMLConfigBuilderPlugin implements WebpackPluginInstance {
5
4
  private readonly destDir;
6
5
  private readonly referencePlugin;
7
6
  private static jsdomInstance?;
package/dist/shared.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { PHPWriter } from "@plaudit/php-writer";
2
2
  import { HereOrNowDoc } from "@plaudit/php-writer/expressions";
3
3
  import type { Options as PostcssFunctionsOptions } from "postcss-functions";
4
- import { type AssetInfo, type Compilation, type Configuration, type Entrypoint, WebpackError, type Compiler } from "webpack";
4
+ import { type AssetInfo, type Compilation, type Configuration, type Entrypoint, WebpackError } from "webpack";
5
5
  import { SourceType } from "./utils/entrypoint-resolution-logic";
6
6
  import type { NormalizedEnqueuingControlFlags } from "./utils/path-query-and-related-helpers";
7
7
  export * from "./utils/entrypoint-resolution-logic";
@@ -103,9 +103,6 @@ export declare function constantEntries<K extends string, V>(object: {
103
103
  [k in K]: V;
104
104
  }): [K, V][];
105
105
  export declare function determineCurrentSourceType(dest: string | AdvancedOutputConfig, srcIsDirectory: boolean): SourceType;
106
- export interface WebpackPlugin {
107
- apply(compiler: Compiler): void;
108
- }
109
106
  export type ObjectIndividualExternalDepConfig = {
110
107
  import?: string | [string, ...string[]];
111
108
  handle: string;
@@ -124,13 +121,13 @@ export type AdvancedOutputConfig = {
124
121
  bundleAnalyzer?: boolean | 'no-auto-open';
125
122
  locations?: UsageLocations | UsageLocations['handle'];
126
123
  lazyLoader?: string;
127
- pathQueryParameters?: PathQueryParameters;
128
124
  enqueuingFlags?: NormalizedEnqueuingControlFlags;
129
125
  };
130
- type OptionalCfgFields = 'directoryLayout' | 'externalize' | 'lazyLoader' | 'pathQueryParameters';
126
+ type OptionalCfgFields = 'directoryLayout' | 'externalize' | 'lazyLoader';
131
127
  export type VerifiedAdvancedOutputConfig = Required<Omit<AdvancedOutputConfig, 'locations' | 'enqueuingFlags' | OptionalCfgFields>> & Pick<AdvancedOutputConfig, OptionalCfgFields> & {
132
128
  enqueuingFlags: NormalizedEnqueuingControlFlags | undefined;
133
129
  locations: NormalizedUsageLocations;
130
+ pathQueryParameters?: PathQueryParameters;
134
131
  };
135
132
  export type SourcesObject = Record<string, string | AdvancedOutputConfig | boolean>;
136
133
  export type PlauditWordpressWebpackConfig = {
@@ -158,6 +155,13 @@ export type PlauditWordpressWebpackConfig = {
158
155
  onlyRunPostCSSOnPCSS?: boolean;
159
156
  useBlockSupportsAsThemeJsonDefaults?: boolean;
160
157
  };
158
+ /** Unified-loader watch output: `dist` → `dist-dev` when SERVER_MODE is development. */
159
+ export declare function shouldWriteDistDev(config: Pick<PlauditWordpressWebpackConfig, 'outputDir' | 'useUnifiedLoader' | 'omitDistDev'>): boolean;
160
+ /**
161
+ * This MUST be kept in sync with the copy in @plaudit/dev-webpack-plugin
162
+ * @returns true for `dist-dev` (or any `*-dev` output folder produced by {@link shouldWriteDistDev}).
163
+ */
164
+ export declare function isDistDevOutputPath(outputPath: string): boolean;
161
165
  export declare function applyStandards(config: PlauditWordpressWebpackConfig): {
162
166
  readonly standard?: "2026-03-13";
163
167
  readonly standaloneBlocks?: boolean;
@@ -235,8 +239,6 @@ export type TupleOf<T, N extends number> = N extends N ? number extends N ? T[]
235
239
  type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>;
236
240
  export declare function arrayIsLength<T, N extends number>(arr: T[] | null | undefined, length: N): arr is TupleOf<T, N>;
237
241
  export declare function kebabCase(value: string): string;
238
- export declare function loadEnvFile(filePath: string): Promise<Record<string, string>>;
239
- export declare function parseEnvFile(contents: string): Record<string, string>;
240
242
  export declare function newCleanWebpackError(error: string | ConstructorParameters<typeof WebpackError>): WebpackError;
241
243
  export declare function newWebpackErrorForFile(error: string | ConstructorParameters<typeof WebpackError>, file: string): WebpackError;
242
244
  /**
package/dist/shared.js CHANGED
@@ -25,6 +25,8 @@ exports.isNormalizedUsageLocations = isNormalizedUsageLocations;
25
25
  exports.constantKeys = constantKeys;
26
26
  exports.constantEntries = constantEntries;
27
27
  exports.determineCurrentSourceType = determineCurrentSourceType;
28
+ exports.shouldWriteDistDev = shouldWriteDistDev;
29
+ exports.isDistDevOutputPath = isDistDevOutputPath;
28
30
  exports.applyStandards = applyStandards;
29
31
  exports.resolveStandard = resolveStandard;
30
32
  exports.convertUsageLocationsHandleToEmittableHandle = convertUsageLocationsHandleToEmittableHandle;
@@ -39,8 +41,6 @@ exports.getHandleGroup = getHandleGroup;
39
41
  exports.hasAtLeastOneItem = hasAtLeastOneItem;
40
42
  exports.arrayIsLength = arrayIsLength;
41
43
  exports.kebabCase = kebabCase;
42
- exports.loadEnvFile = loadEnvFile;
43
- exports.parseEnvFile = parseEnvFile;
44
44
  exports.newCleanWebpackError = newCleanWebpackError;
45
45
  exports.newWebpackErrorForFile = newWebpackErrorForFile;
46
46
  exports.emitResolveBaseUriFunction = emitResolveBaseUriFunction;
@@ -56,7 +56,6 @@ exports.instanceOfNodeError = instanceOfNodeError;
56
56
  exports.shouldBeSkipped = shouldBeSkipped;
57
57
  const node_crypto_1 = require("node:crypto");
58
58
  const node_fs_1 = require("node:fs");
59
- const promises_1 = require("node:fs/promises");
60
59
  const node_path_1 = __importDefault(require("node:path"));
61
60
  const php_writer_1 = require("@plaudit/php-writer");
62
61
  const expressions_1 = require("@plaudit/php-writer/expressions");
@@ -115,6 +114,17 @@ function determineCurrentSourceType(dest, srcIsDirectory) {
115
114
  return dest.directoryLayout;
116
115
  }
117
116
  }
117
+ /** Unified-loader watch output: `dist` → `dist-dev` when SERVER_MODE is development. */
118
+ function shouldWriteDistDev(config) {
119
+ return !!(config.outputDir && config.useUnifiedLoader && !config.omitDistDev && (process.env['SERVER_MODE'] ?? 'development') === 'development');
120
+ }
121
+ /**
122
+ * This MUST be kept in sync with the copy in @plaudit/dev-webpack-plugin
123
+ * @returns true for `dist-dev` (or any `*-dev` output folder produced by {@link shouldWriteDistDev}).
124
+ */
125
+ function isDistDevOutputPath(outputPath) {
126
+ return node_path_1.default.basename(outputPath.replace(/[/\\]+$/, '')).endsWith('-dev');
127
+ }
118
128
  function applyStandards(config) {
119
129
  switch (config.standard) {
120
130
  case '2026-03-13':
@@ -224,17 +234,6 @@ function kebabCase(value) {
224
234
  const kebabCaseRegexes = [[/([a-z])([A-Z])/g, "$1-$2"], [/[\s_.\-]+/g, "-"]];
225
235
  return kebabCaseRegexes.reduce((str, [pattern, replacement]) => str.replace(pattern, replacement), value).toLowerCase();
226
236
  }
227
- async function loadEnvFile(filePath) {
228
- return (0, promises_1.readFile)(filePath, 'utf-8').then(parseEnvFile, () => ({}));
229
- }
230
- function parseEnvFile(contents) {
231
- return Object.fromEntries(contents.split(/(\r?\n)+/).map(line => line.trim())
232
- .filter(line => line.length > 0 && !line.startsWith("#") && !line.startsWith("//"))
233
- .map(line => {
234
- const equalsPos = line.indexOf('=');
235
- return equalsPos === -1 ? [line, ""] : [line.substring(0, equalsPos), line.substring(equalsPos + 1)];
236
- }));
237
- }
238
237
  function newCleanWebpackError(error) {
239
238
  const res = typeof error === 'string' ? new webpack_1.WebpackError(error) : new webpack_1.WebpackError(...error);
240
239
  res.hideStack = true;
@@ -1,6 +1,6 @@
1
1
  import type { AbstractBiPhasicGroupAndEntryPlugin, EntryProvider } from "../plugins/AbstractBiPhasicGroupAndEntryPlugin";
2
2
  import type { AdditionalDependencyInjectorPlugin } from "../plugins/AdditionalDependencyInjectorPlugin";
3
- import { EntrypointFields, PlauditWordpressWebpackConfig, BlockEntrypointInfo, VerifiedAdvancedOutputConfig, MinimumViableMetadata, WebpackPlugin } from "../shared";
3
+ import { EntrypointFields, PlauditWordpressWebpackConfig, BlockEntrypointInfo, VerifiedAdvancedOutputConfig, MinimumViableMetadata } from "../shared";
4
4
  import type { Compiler, Configuration, DynamicEntryPlugin, WebpackPluginInstance } from "webpack";
5
5
  import type WebpackRemoveEmptyScriptsPlugin from "webpack-remove-empty-scripts";
6
6
  export type VerifiedPlauditWordpressWebpackConfig = Required<Omit<PlauditWordpressWebpackConfig, 'variables' | 'src' | 'externals' | 'standard'>> & {
@@ -8,7 +8,7 @@ export type VerifiedPlauditWordpressWebpackConfig = Required<Omit<PlauditWordpre
8
8
  currentVariables: Record<string, any>;
9
9
  } & Pick<PlauditWordpressWebpackConfig, 'externals'>;
10
10
  export type CommonPluginConfig = {
11
- plugins: (WebpackPluginInstance | WebpackPlugin | ((this: Compiler, compiler: Compiler) => void))[];
11
+ plugins: (WebpackPluginInstance | ((this: Compiler, compiler: Compiler) => void))[];
12
12
  removeEmptyScriptsPlugin: WebpackRemoveEmptyScriptsPlugin;
13
13
  makeAdditionalDependencyInjectorPlugin(referencePlugin: AbstractBiPhasicGroupAndEntryPlugin<any>): AdditionalDependencyInjectorPlugin;
14
14
  };
@@ -390,10 +390,12 @@ function commonMakeWebpackConfig(config, commonConfig, webpackConfig, externaliz
390
390
  outputLibrary = webpackConfig.output?.library;
391
391
  }
392
392
  const extensions = processingModules ? ['.mjsx', '.mjs', '.mtsx', '.mts', '...'] : ['.jsx', '.tsx', '.ts', '...'];
393
+ // `dist` (SERVER_MODE=production, or omitDistDev) is always minified production. `dist-dev` follows NODE_ENV so `wp-scripts start` stays fast.
394
+ const isProductionBuild = !(0, shared_1.isDistDevOutputPath)(config.outputDir) || process.env['NODE_ENV'] === 'production';
393
395
  return {
394
396
  ...webpackConfig,
395
- devtool: 'source-map',
396
- mode: "production",
397
+ devtool: isProductionBuild ? 'source-map' : (webpackConfig.devtool ?? 'eval-cheap-module-source-map'),
398
+ mode: isProductionBuild ? 'production' : 'development',
397
399
  output: {
398
400
  ...webpackConfig.output,
399
401
  path: outPath,
@@ -404,6 +406,7 @@ function commonMakeWebpackConfig(config, commonConfig, webpackConfig, externaliz
404
406
  },
405
407
  optimization: {
406
408
  ...webpackConfig.optimization,
409
+ minimize: isProductionBuild,
407
410
  splitChunks: {
408
411
  ...(webpackConfig.optimization?.splitChunks || {}),
409
412
  cacheGroups: {
@@ -423,10 +426,12 @@ function commonMakeWebpackConfig(config, commonConfig, webpackConfig, externaliz
423
426
  default: false
424
427
  }
425
428
  },
426
- minimizer: [
427
- ...(webpackConfig.optimization?.minimizer || []),
428
- new css_minimizer_webpack_plugin_1.default()
429
- ]
429
+ minimizer: isProductionBuild
430
+ ? [
431
+ ...(webpackConfig.optimization?.minimizer || []),
432
+ new css_minimizer_webpack_plugin_1.default()
433
+ ]
434
+ : webpackConfig.optimization?.minimizer
430
435
  },
431
436
  module: {
432
437
  ...webpackConfig.module,
@@ -1,10 +1,13 @@
1
- import { type AdvancedOutputConfig, type PlauditWordpressWebpackConfig } from "../shared";
1
+ import { type AdvancedOutputConfig, type PathQueryParameters, type PlauditWordpressWebpackConfig } from "../shared";
2
2
  export declare const enum SourceType {
3
3
  blocks = "blocks",
4
4
  extensions = "extensions",
5
5
  plain = "plain"
6
6
  }
7
7
  export declare function isSourceType(str: string): str is SourceType;
8
- type Entrypoints = [string, AdvancedOutputConfig][];
8
+ type ResolvedSourceConfig = AdvancedOutputConfig & {
9
+ pathQueryParameters?: PathQueryParameters;
10
+ };
11
+ type Entrypoints = [string, ResolvedSourceConfig][];
9
12
  export declare function resolveAllConfigLevelEntrypoints(config: PlauditWordpressWebpackConfig, projectRoot?: string): Record<'staticEntrypoints' | 'dynamicEntrypoints', Entrypoints>;
10
13
  export {};
@@ -10,7 +10,6 @@ const entrypoint_resolution_logic_1 = require("./utils/entrypoint-resolution-log
10
10
  const common_config_helpers_1 = require("./utils/common-config-helpers");
11
11
  const path_query_and_related_helpers_1 = require("./utils/path-query-and-related-helpers");
12
12
  const AdditionalDependencyInjectorPlugin_1 = require("./plugins/AdditionalDependencyInjectorPlugin");
13
- const BrowserSyncPlugin_1 = require("./plugins/BrowserSyncPlugin");
14
13
  const dependency_extraction_webpack_plugin_config_builder_1 = require("./plugins/dependency-extraction-webpack-plugin-config-builder");
15
14
  const EnhancedDynamicEntryPlugin_1 = require("./plugins/EnhancedDynamicEntryPlugin");
16
15
  const ExtensionsConfigFileGeneratorPlugin_1 = require("./plugins/ExtensionsConfigFileGeneratorPlugin");
@@ -149,7 +148,7 @@ function buildVerifiedConfig(config) {
149
148
  config = (0, shared_1.applyStandards)(config);
150
149
  const { standaloneBlocks = false, stats = 'errors-warnings', variables: rawVariables, verbose = process.argv.includes('--verbose') || process.env['VERBOSE'] === 'true', postcss = {}, externals, assumeGlobalizedPlauditLibraries = true, useWebpackResourceFiltering = true, plainEntrypointsVersion = 1, srcDir = "", useUnifiedLoader = false, includePostInitFallback = false, omitDistDev = false, onlyRunPostCSSOnPCSS = false, useBlockSupportsAsThemeJsonDefaults = true, } = config;
151
150
  let outputDir = config.outputDir ?? "";
152
- if (outputDir && useUnifiedLoader && !omitDistDev && (process.env['SERVER_MODE'] ?? 'development') === 'development') {
151
+ if ((0, shared_1.shouldWriteDistDev)({ outputDir, useUnifiedLoader, omitDistDev })) {
153
152
  outputDir += "-dev";
154
153
  }
155
154
  let srcPrefixes;
@@ -192,6 +191,10 @@ function buildVerifiedConfig(config) {
192
191
  const allocatedDestinations = {};
193
192
  const partiallyVerifiedSources = rawSources.map(([src, config]) => {
194
193
  const { destination, additionalDependencies = [], assumeGlobalizedPlauditLibraries = cfg.assumeGlobalizedPlauditLibraries, bundleAnalyzer = false, directoryLayout, externalize, withLegacyBlocksIn = false, lazyLoader, pathQueryParameters: rawPathQueryParameters, enqueuingFlags: rawEnqueuingFlags, locations: rawSourceLocations, } = config;
194
+ // This guards against a crash later on down the line due to trying to run a spread on a boolean
195
+ if (externalize && typeof externalize !== 'string' && typeof externalize !== 'object') {
196
+ throw new TypeError(`externalize must be a string, an array or an object, but "${src}" set externalize to a ${typeof externalize}`);
197
+ }
195
198
  const { flags: queryEnqueuingFlags, remainder: pathQueryParameters, handle: pathQueryHandle } = (0, path_query_and_related_helpers_1.unpackEnqueuingControlFlagsFromPathQueryParameters)(rawPathQueryParameters, src, 'path query parameters');
196
199
  const enqueuingFlags = (0, path_query_and_related_helpers_1.mergeTwoEnqueuingControlFlagSets)(src, rawEnqueuingFlags, queryEnqueuingFlags);
197
200
  const normalizedParts = { additionalDependencies, assumeGlobalizedPlauditLibraries, bundleAnalyzer, directoryLayout, externalize, withLegacyBlocksIn, lazyLoader };
@@ -333,34 +336,73 @@ function withDerivedOutputDir(cfg, sources) {
333
336
  })
334
337
  };
335
338
  }
339
+ let forkTsCheckerInstalled = false;
340
+ function isTypeScriptSourceFile(file) {
341
+ return /\.[cm]?tsx?$/i.test(file.split('?')[0] ?? '');
342
+ }
343
+ const prefixes = ['c', 'm', ''];
344
+ const suffixes = ['x', ''];
345
+ const tsExtensions = prefixes.map(prefix => prefix + "ts").flatMap(name => suffixes.map(suffix => name + suffix));
336
346
  function handleDisablingTSCheckerIfNecessary(srcRoot, scriptExtension, plugins) {
337
- if (process.env["NO_TS_CHECKER"] !== "true") {
338
- const include = (Array.isArray(srcRoot) ? srcRoot : [srcRoot])
339
- .filter(sr => (0, node_path_1.extname)(sr).length === 0 || (0, shared_1.scriptOrStyleTest)(sr, scriptExtension) === "script")
340
- .map(sr => (0, node_path_1.extname)(sr).length > 0 ? sr : (0, node_path_1.join)(sr, "**", "*"));
341
- if (include.length > 0) {
342
- plugins.push(new fork_ts_checker_webpack_plugin_1.default({
343
- async: true,
344
- typescript: {
345
- diagnosticOptions: {
346
- semantic: true,
347
- syntactic: true,
348
- },
349
- configOverwrite: {
350
- include,
351
- compilerOptions: {
352
- skipLibCheck: true
353
- }
354
- }
355
- },
356
- issue: {
357
- exclude(issue) {
358
- return issue.code === 'TS18003'; // This hides the "no TypeScript files found" error while still monitoring the directory
359
- }
360
- }
361
- }));
347
+ if (process.env["NO_TS_CHECKER"] === "true" || forkTsCheckerInstalled) {
348
+ return;
349
+ }
350
+ const include = [];
351
+ for (const sr of (Array.isArray(srcRoot) ? srcRoot : [srcRoot])) {
352
+ if ((0, node_path_1.extname)(sr).length === 0) {
353
+ include.push(...tsExtensions.map(tsExt => (0, node_path_1.join)(sr, "**", `*.${tsExt}`)));
354
+ }
355
+ else if ((0, shared_1.scriptOrStyleTest)(sr, scriptExtension) === "script") {
356
+ include.push(sr);
362
357
  }
363
358
  }
359
+ if (include.length === 0) {
360
+ return;
361
+ }
362
+ forkTsCheckerInstalled = true;
363
+ let logTsStatus = true;
364
+ plugins.push({
365
+ apply(compiler) {
366
+ compiler.hooks.watchRun.tap('PlauditForkTsCheckerCssQuiet', watchingCompiler => {
367
+ const changed = [
368
+ ...(watchingCompiler.modifiedFiles ?? []),
369
+ ...(watchingCompiler.removedFiles ?? [])
370
+ ];
371
+ logTsStatus = changed.length === 0 || changed.some(isTypeScriptSourceFile);
372
+ });
373
+ }
374
+ });
375
+ plugins.push(new fork_ts_checker_webpack_plugin_1.default({
376
+ async: true,
377
+ logger: {
378
+ log(message) {
379
+ if (!logTsStatus) {
380
+ return;
381
+ }
382
+ console.log(message);
383
+ },
384
+ error(message) {
385
+ console.error(message);
386
+ }
387
+ },
388
+ typescript: {
389
+ diagnosticOptions: {
390
+ semantic: true,
391
+ syntactic: true,
392
+ },
393
+ configOverwrite: {
394
+ include,
395
+ compilerOptions: {
396
+ skipLibCheck: true
397
+ }
398
+ }
399
+ },
400
+ issue: {
401
+ exclude(issue) {
402
+ return issue.code === 'TS18003';
403
+ }
404
+ }
405
+ }));
364
406
  }
365
407
  function buildCommonPluginConfig(webpackConfig, config, bundleAnalyzer, assumeGlobalizedPlauditLibraries, externalize) {
366
408
  const plugins = webpackConfig.plugins?.filter(v => !!v)
@@ -405,7 +447,13 @@ function buildCommonPluginConfig(webpackConfig, config, bundleAnalyzer, assumeGl
405
447
  }
406
448
  const builtDependencyExtractionWebpackPlugin = (0, dependency_extraction_webpack_plugin_config_builder_1.makeDependencyExtractionPlugin)(config.externals, assumeGlobalizedPlauditLibraries, externalize);
407
449
  plugins[dependencyExtractionPluginIndex] = builtDependencyExtractionWebpackPlugin;
408
- plugins.push(new BrowserSyncPlugin_1.BrowserSyncPlugin());
450
+ if ((0, shared_1.isDistDevOutputPath)(config.outputDir)) {
451
+ try {
452
+ const { PlauditDevPlugin } = require("@plaudit/dev-webpack-plugin");
453
+ plugins.push(new PlauditDevPlugin());
454
+ }
455
+ catch { }
456
+ }
409
457
  return {
410
458
  plugins, removeEmptyScriptsPlugin,
411
459
  makeAdditionalDependencyInjectorPlugin(referencePlugin) {
@@ -452,7 +500,7 @@ function destToKey(dest) {
452
500
  : dest.externalize?.toString() ?? "undefined";
453
501
  return [dest.assumeGlobalizedPlauditLibraries, dest.bundleAnalyzer, externalize].join("~");
454
502
  }
455
- function processIndividualWebpackConfig(config, webpackConfig, sources, canClean) {
503
+ function processIndividualWebpackConfig(config, webpackConfig, sources, canClean, preferNonModuleTsChecker) {
456
504
  if (webpackConfig.output?.module) {
457
505
  // This ensures that module files are emitted as module files
458
506
  webpackConfig = {
@@ -486,7 +534,9 @@ function processIndividualWebpackConfig(config, webpackConfig, sources, canClean
486
534
  return batches.map(currentBatch => {
487
535
  const { bundleAnalyzer, assumeGlobalizedPlauditLibraries, externalize } = currentBatch[0].dest;
488
536
  const { plugins, removeEmptyScriptsPlugin, makeAdditionalDependencyInjectorPlugin } = buildCommonPluginConfig(webpackConfig, config, bundleAnalyzer, assumeGlobalizedPlauditLibraries, externalize);
489
- handleDisablingTSCheckerIfNecessary(currentBatch.flatMap(a => a.srcRoots), scriptExtension, plugins);
537
+ if (!processingModules || !preferNonModuleTsChecker) {
538
+ handleDisablingTSCheckerIfNecessary(currentBatch.flatMap(a => a.srcRoots), scriptExtension, plugins);
539
+ }
490
540
  const applicableExtensionTest = (name) => {
491
541
  return commonConfig.scriptExtension.test(name) || (!processingModules && shared_1.styleExtension.test(name));
492
542
  };
@@ -627,12 +677,13 @@ module.exports = function (config, webpackConfig = require("@wordpress/scripts/c
627
677
  webpackConfig = webpackConfig[0];
628
678
  }
629
679
  if (Array.isArray(webpackConfig)) {
680
+ const hasNonModuleCompiler = webpackConfig.some(cfg => !cfg.output?.module);
630
681
  return webpackConfig.toSorted((a, b) => {
631
682
  if (a.output?.module) {
632
683
  return b.output?.module ? 0 : -1;
633
684
  }
634
685
  return b.output?.module ? 1 : 0;
635
- }).flatMap(wpCfg => processIndividualWebpackConfig(cfg, wpCfg, sources, false));
686
+ }).flatMap(wpCfg => processIndividualWebpackConfig(cfg, wpCfg, sources, false, hasNonModuleCompiler));
636
687
  }
637
- return processIndividualWebpackConfig(cfg, webpackConfig, sources, true);
688
+ return processIndividualWebpackConfig(cfg, webpackConfig, sources, true, false);
638
689
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plaudit/webpack-extensions",
3
- "version": "2.96.2",
3
+ "version": "2.97.0",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,19 +32,19 @@
32
32
  }
33
33
  },
34
34
  "devDependencies": {
35
- "@plaudit/gutenberg-api-extensions": "^2.98.0",
36
- "@types/browser-sync-webpack-plugin": "^2.2.5",
35
+ "@plaudit/dev-webpack-plugin": "^1.0.1",
36
+ "@plaudit/gutenberg-api-extensions": "^2.98.2",
37
37
  "@types/jsdom": "^28.0.3",
38
38
  "@types/node": "^25.9.5",
39
39
  "@types/postcss-functions": "^4.0.4",
40
40
  "@types/tapable": "^2.3.0",
41
41
  "@types/webpack-sources": "^3.2.3",
42
42
  "atob": "^2.1.2",
43
- "css-loader": "^6.2.0",
44
- "glob": "^7.1.2",
45
- "jest": "^30.0.0",
46
- "lodash": "^4.17.21",
47
- "mini-css-extract-plugin": "^2.9.2",
43
+ "css-loader": "^6.11.0",
44
+ "glob": "^7.2.3",
45
+ "jest": "^30.4.2",
46
+ "lodash": "^4.18.1",
47
+ "mini-css-extract-plugin": "^2.10.2",
48
48
  "mkdirp": "^3.0.1",
49
49
  "rimraf": "^5.0.10",
50
50
  "typescript": "^6.0.3",
@@ -57,10 +57,9 @@
57
57
  "@plaudit/postcss-silent-extend": "^3.0.0",
58
58
  "@plaudit/postcss-strip-units": "^3.0.0",
59
59
  "@plaudit/postcss-variables": "^1.1.0",
60
- "@wordpress/dependency-extraction-webpack-plugin": "^6.51.0",
60
+ "@wordpress/dependency-extraction-webpack-plugin": "^6.53.0",
61
61
  "@wordpress/scripts": "^32.6.0",
62
62
  "autoprefixer": "^10.5.4",
63
- "browser-sync": "^3.0.4",
64
63
  "copy-webpack-plugin": "10.2.4",
65
64
  "css-minimizer-webpack-plugin": "^6.0.0",
66
65
  "cssnano": "^6.1.2",
@@ -68,11 +67,11 @@
68
67
  "http-proxy-middleware": "^3.0.7",
69
68
  "jsdom": "^29.1.1",
70
69
  "json2php": "0.0.12",
71
- "postcss": "^8.5.19",
70
+ "postcss": "^8.5.26",
72
71
  "postcss-calc": "^9.0.1",
73
72
  "postcss-discard-comments": "^6.0.2",
74
73
  "postcss-functions": "^4.0.2",
75
- "postcss-import": "^16.1.1",
74
+ "postcss-import": "^16.2.0",
76
75
  "postcss-load-config": "^4.0.2",
77
76
  "postcss-loader": "^7.3.4",
78
77
  "postcss-media-minmax": "^5.0.0",
@@ -82,10 +81,18 @@
82
81
  "postcss-reporter": "^7.1.0",
83
82
  "postcss-simple-vars": "^7.0.1",
84
83
  "postcss-url": "^10.1.4",
85
- "webpack": "^5.108.4",
84
+ "webpack": "^5.109.2",
86
85
  "webpack-remove-empty-scripts": "^1.1.1",
87
86
  "xml-formatter": "^3.7.0"
88
87
  },
88
+ "peerDependencies": {
89
+ "@plaudit/dev-webpack-plugin": "^1.0.0"
90
+ },
91
+ "peerDependenciesMeta": {
92
+ "@plaudit/dev-webpack-plugin": {
93
+ "optional": true
94
+ }
95
+ },
89
96
  "engines": {
90
97
  "node": ">=20"
91
98
  },
@@ -1,25 +0,0 @@
1
- import { type WebpackPlugin } from "../shared";
2
- import browserSync, { type BrowserSyncInstance } from "browser-sync";
3
- import type { Compiler } from "webpack";
4
- export type PluginOptions = {
5
- reload: boolean;
6
- name: string;
7
- callback?: (err: Error, bs: BrowserSyncInstance) => any;
8
- injectCss: boolean;
9
- middlewareBuilder?: (options: browserSync.Options) => browserSync.Options['middleware'];
10
- };
11
- export declare class BrowserSyncPlugin implements WebpackPlugin {
12
- private static isBrowserSyncRunning;
13
- private static browserSyncPluginOptions?;
14
- private readonly pluginOptions;
15
- private readonly browserSyncInstance;
16
- private isWebpackWatching;
17
- private mostRecentChunkHashes;
18
- private shouldNotify;
19
- constructor(pluginOptions?: Partial<PluginOptions>);
20
- private static getBrowserSyncPluginOptions;
21
- private static findEnvFile;
22
- apply(compiler: Compiler): void;
23
- private getCssOnlyEmittedAssetsNames;
24
- private static getSiteUrls;
25
- }
@@ -1,212 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.BrowserSyncPlugin = void 0;
7
- const node_child_process_1 = __importDefault(require("node:child_process"));
8
- const node_fs_1 = __importDefault(require("node:fs"));
9
- const node_path_1 = __importDefault(require("node:path"));
10
- const shared_1 = require("../shared");
11
- const browser_sync_1 = __importDefault(require("browser-sync"));
12
- const http_proxy_middleware_1 = require("http-proxy-middleware");
13
- class BrowserSyncPlugin {
14
- static isBrowserSyncRunning = false;
15
- static browserSyncPluginOptions;
16
- pluginOptions;
17
- browserSyncInstance;
18
- isWebpackWatching = false;
19
- mostRecentChunkHashes = {};
20
- shouldNotify = false;
21
- constructor(pluginOptions) {
22
- this.pluginOptions = { reload: true, name: "plaudit-bs-plugin", injectCss: true, ...pluginOptions };
23
- this.browserSyncInstance = browser_sync_1.default.has(this.pluginOptions.name) ? browser_sync_1.default.get(this.pluginOptions.name) : browser_sync_1.default.create(this.pluginOptions.name);
24
- }
25
- static getBrowserSyncPluginOptions() {
26
- return BrowserSyncPlugin.browserSyncPluginOptions ?? (BrowserSyncPlugin.browserSyncPluginOptions = new Promise(async (resolve) => {
27
- const envFilePath = BrowserSyncPlugin.findEnvFile();
28
- const envFile = envFilePath ? await (0, shared_1.loadEnvFile)(envFilePath) : {};
29
- const prefixes = BrowserSyncPlugin.getSiteUrls();
30
- const targetPort = envFile["WEB_PORT_SSL"]?.match(/^\d+$/) ? envFile["WEB_PORT_SSL"] : "8443";
31
- const targetHost = targetPort === "443" ? "localhost" : `localhost:${targetPort}`;
32
- if (prefixes.length === 0 || prefixes.every(prefix => prefix.startsWith("localhost"))) {
33
- resolve([{
34
- host: 'localhost',
35
- port: 3000,
36
- https: true,
37
- proxy: `https://${targetHost}`
38
- }, {}]);
39
- }
40
- else {
41
- resolve([{
42
- port: 3000,
43
- listen: "0.0.0.0",
44
- https: true,
45
- open: false,
46
- callbacks: {
47
- ready(err, bsi) {
48
- // This ensures that the opened URL is actually a valid one
49
- import("open").then(open => open.default(`https://${prefixes[0]?.replace(/:\d{2,4}/, "")}:${bsi.getOption("port") ?? 3000}`));
50
- }
51
- }
52
- }, {
53
- middlewareBuilder: (options) => {
54
- const proxyPort = options.port?.toString() ?? "3000";
55
- const router = prefixes.reduce((router, prefix) => {
56
- router[`${prefix}:${proxyPort}`] = {
57
- protocol: 'https:',
58
- slashes: true,
59
- auth: null,
60
- host: prefix,
61
- port: targetPort,
62
- hostname: targetHost,
63
- hash: null,
64
- search: null,
65
- query: null,
66
- pathname: '/',
67
- path: '/',
68
- href: `https://${targetHost}/`
69
- };
70
- return router;
71
- }, {});
72
- const portInjectionPattern = new RegExp(`(${prefixes.join('|')})(?!:3000)`, "gi");
73
- return (0, http_proxy_middleware_1.createProxyMiddleware)({
74
- changeOrigin: true, router, secure: false, xfwd: true, selfHandleResponse: true, target: `https://${targetHost}`,
75
- on: {
76
- proxyRes: (0, http_proxy_middleware_1.responseInterceptor)(async (responseBuffer, proxyRes) => {
77
- const contentType = proxyRes.headers["content-type"];
78
- if (contentType && (contentType.startsWith("text/") || contentType === "application/x-javascript")) {
79
- return responseBuffer.toString('utf-8').replaceAll(portInjectionPattern, "$1:3000");
80
- }
81
- return responseBuffer;
82
- })
83
- }
84
- });
85
- }
86
- }]);
87
- }
88
- }));
89
- }
90
- static findEnvFile() {
91
- for (let envFileHolderPath = process.cwd(); envFileHolderPath.length > 5; envFileHolderPath = node_path_1.default.dirname(envFileHolderPath)) {
92
- if (node_fs_1.default.existsSync(node_path_1.default.join(envFileHolderPath, ".env"))) {
93
- return node_path_1.default.join(envFileHolderPath, ".env");
94
- }
95
- }
96
- return undefined;
97
- }
98
- apply(compiler) {
99
- if (!process.argv.includes('--browser-sync') && process.env['BROWSER_SYNC'] !== 'true') {
100
- return;
101
- }
102
- let devTarget = process.env['DEV_TARGET'] ?? process.argv.find(a => a.startsWith("--dev-target="))?.substring(13);
103
- if (devTarget === undefined) {
104
- const flagIndex = process.argv.findIndex(a => a === "--dev-target");
105
- if (flagIndex > -1) {
106
- devTarget = process.argv[flagIndex + 1];
107
- }
108
- }
109
- if (devTarget !== undefined && devTarget !== node_path_1.default.basename(process.cwd()) && !(devTarget === "theme" && node_fs_1.default.existsSync(node_path_1.default.join(process.cwd(), "style.css")))) {
110
- return;
111
- }
112
- compiler.hooks.watchRun.tap(BrowserSyncPlugin.name, () => {
113
- this.isWebpackWatching = true;
114
- });
115
- compiler.hooks.compilation.tap(BrowserSyncPlugin.name, () => {
116
- if (BrowserSyncPlugin.isBrowserSyncRunning && this.shouldNotify) {
117
- this.browserSyncInstance.notify('Rebuilding...');
118
- }
119
- });
120
- compiler.hooks.done.tapPromise(BrowserSyncPlugin.name, async (stats) => {
121
- if (!this.isWebpackWatching) {
122
- return;
123
- }
124
- if (!BrowserSyncPlugin.isBrowserSyncRunning) {
125
- const [browserSyncOptions, pluginOptions] = await BrowserSyncPlugin.getBrowserSyncPluginOptions();
126
- const actualPluginOptions = { ...this.pluginOptions, ...pluginOptions };
127
- const middleware = actualPluginOptions.middlewareBuilder?.(browserSyncOptions);
128
- this.browserSyncInstance.init(middleware
129
- ? { ...browserSyncOptions, server: { middleware: Array.isArray(middleware) ? middleware : [middleware] } }
130
- : browserSyncOptions, this.pluginOptions.callback);
131
- if (browserSyncOptions.notify) {
132
- this.shouldNotify = true;
133
- }
134
- BrowserSyncPlugin.isBrowserSyncRunning = true;
135
- }
136
- if (this.pluginOptions.reload) {
137
- if (this.pluginOptions.injectCss) {
138
- const cssOnlyEmittedAssets = this.getCssOnlyEmittedAssetsNames(stats);
139
- if (cssOnlyEmittedAssets !== undefined) {
140
- this.browserSyncInstance.reload(cssOnlyEmittedAssets);
141
- return;
142
- }
143
- }
144
- this.browserSyncInstance.reload();
145
- }
146
- });
147
- }
148
- getCssOnlyEmittedAssetsNames(stats) {
149
- const compiledStats = stats.compilation.getStats().toJson({
150
- hash: true,
151
- publicPath: true,
152
- assets: true,
153
- chunks: true,
154
- modules: false,
155
- source: false,
156
- errorDetails: false,
157
- timings: false
158
- });
159
- const chunks = compiledStats.chunks
160
- ?.filter((chunk) => chunk.names !== undefined && chunk.files !== undefined);
161
- if (!chunks) {
162
- return undefined;
163
- }
164
- const mostRecentChunkHashes = this.mostRecentChunkHashes;
165
- this.mostRecentChunkHashes = Object.fromEntries(chunks.flatMap(chunk => chunk.names.map(cn => [cn, chunk.hash])));
166
- if (Object.keys(mostRecentChunkHashes).length !== chunks.length) {
167
- return undefined;
168
- }
169
- const changedFilenames = chunks
170
- .filter(chunk => chunk.names.some(name => mostRecentChunkHashes[name] !== chunk.hash))
171
- .flatMap(chunk => [...chunk.files, ...(chunk.auxiliaryFiles ?? [])])
172
- .filter(filename => !filename.endsWith(".asset.php"));
173
- if (changedFilenames.length === 0) {
174
- return undefined;
175
- }
176
- for (const filename of changedFilenames) {
177
- if (!filename.includes(".css")) {
178
- return undefined;
179
- }
180
- }
181
- return changedFilenames;
182
- }
183
- static getSiteUrls() {
184
- //docker container inspect "$(docker compose ps --format=json | jq '. | select(. | contains({"Service": "wordpress"})) | .ID' -r)" | jq '.[].Config.Env'
185
- const serviceId = node_child_process_1.default.spawnSync("docker", ["compose", "ps", "--format=json"], { encoding: "utf-8", stdio: ["ignore", "pipe", "inherit"] })
186
- .stdout.trim().split("\n").map(item => JSON.parse(item.trim())).find(item => item.Service === "wordpress")?.ID;
187
- if (serviceId === undefined) {
188
- return ["localhost"]; // This will only happen for Tomcat or misconfigured containers, both of which should use localhost
189
- }
190
- const inspectionResult = node_child_process_1.default.spawnSync("docker", ["container", "inspect", "--format=json", serviceId], { encoding: "utf-8", stdio: ["ignore", "pipe", "inherit"] })
191
- .stdout.trim();
192
- const containerEnv = Object.fromEntries(JSON.parse(inspectionResult)[0]?.Config.Env.map((envEntry) => {
193
- const equalSignIndex = envEntry.indexOf('=');
194
- return [envEntry.substring(0, equalSignIndex), envEntry.substring(equalSignIndex + 1)];
195
- }));
196
- if (containerEnv['WORDPRESS_MAPPED_DOMAINS'] !== '1') {
197
- return ["localhost:8443"]; //This will only happen for legacy WordPress sites
198
- }
199
- let siteUrls;
200
- const multisiteUrlsProcess = node_child_process_1.default.spawnSync("docker", ["compose", "exec", "--user=www-data", "wordpress", "wp", "site", "list", "--field=url", "--quiet"], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }); // We're forced to mute stderr here because it is otherwise almost guaranteed to print
201
- if (!multisiteUrlsProcess.error && !multisiteUrlsProcess.status && !multisiteUrlsProcess.signal) {
202
- siteUrls = multisiteUrlsProcess.stdout.split("\n").map(line => line.trim()).filter(line => line.length > 0);
203
- }
204
- else {
205
- siteUrls = [node_child_process_1.default.spawnSync("docker", ["compose", "exec", "--user=www-data", "wordpress", "wp", "option", "get", "siteurl"], { encoding: "utf-8", stdio: ["ignore", "pipe", "inherit"] }).stdout.trim()];
206
- }
207
- // Because mapped domain sites that are using my mapping scheme hyphenate instances of "www.", this is an effective test for whether it is in use.
208
- // If the URL still has the "www.", then it is using David's mapping scheme and should be accessed via localhost
209
- return siteUrls.map(siteUrl => siteUrl.includes("www.") ? "localhost" : siteUrl).map(siteUrl => siteUrl.replace(/^https?:\/\//i, ""));
210
- }
211
- }
212
- exports.BrowserSyncPlugin = BrowserSyncPlugin;