@plaudit/webpack-extensions 3.17.0 → 3.18.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 +26 -0
- package/README.md +22 -2
- package/USER-GUIDE.md +5 -3
- package/dist/plugins/AbstractBiPhasicGroupPlugin.d.ts +3 -3
- package/dist/plugins/MiniCSSExtractPluginErrorCleaner.d.ts +2 -3
- package/dist/plugins/PackageConfigSanityChecker.d.ts +2 -3
- package/dist/plugins/VariablesJSMonitorPlugin.d.ts +2 -3
- package/dist/plugins/WPMLConfigBuilder.d.ts +2 -3
- package/dist/shared.d.ts +8 -6
- package/dist/shared.js +13 -14
- package/dist/utils/common-config-helpers.d.ts +2 -2
- package/dist/utils/common-config-helpers.js +11 -6
- package/dist/wordpress-scripts-wrapper.js +79 -32
- package/package.json +10 -3
- package/dist/plugins/BrowserSyncPlugin.d.ts +0 -25
- package/dist/plugins/BrowserSyncPlugin.js +0 -212
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.18.0] - 2026-08-18
|
|
9
|
+
### Added
|
|
10
|
+
- David's improvements to build pipeline efficiency (Credit: David)
|
|
11
|
+
- This comes from version `2.97.0`
|
|
12
|
+
- Support for David's `@plaudit/dev-webpack-plugin` (Credit: David)
|
|
13
|
+
- This comes from version `2.97.0`
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- To Webpack's standard plugin interface (`WebpackPluginInstance`)
|
|
17
|
+
- This comes from version `2.97.0`
|
|
18
|
+
|
|
19
|
+
### Removed
|
|
20
|
+
- Browsersync and its tests (Credit: David)
|
|
21
|
+
- This comes from version `2.97.0`
|
|
22
|
+
|
|
8
23
|
## [3.17.0] - 2026-08-18
|
|
9
24
|
### Added
|
|
10
25
|
- A port of WordPress's Dependency Extraction Webpack Plugin because they keep breaking it
|
|
@@ -260,6 +275,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
260
275
|
- Legacy PostCSS features that have been integrated into modern CSS
|
|
261
276
|
- `@extends` support
|
|
262
277
|
|
|
278
|
+
## [2.97.0] - 2026-08-18
|
|
279
|
+
### Added
|
|
280
|
+
- David's improvements to build pipeline efficiency
|
|
281
|
+
- Support for David's `@plaudit/dev-webpack-plugin`
|
|
282
|
+
|
|
283
|
+
### Changed
|
|
284
|
+
- To Webpack's standard plugin interface (`WebpackPluginInstance`)
|
|
285
|
+
|
|
286
|
+
### Removed
|
|
287
|
+
- Browsersync tests
|
|
288
|
+
|
|
263
289
|
## [2.96.3] - 2026-08-11
|
|
264
290
|
### Added
|
|
265
291
|
- A few more validation checks
|
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
|
|
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
|
-
|
|
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
|
@@ -190,11 +190,13 @@ This file automatically:
|
|
|
190
190
|
- Sets up blocks and extensions
|
|
191
191
|
|
|
192
192
|
### 4. Run Build Commands
|
|
193
|
-
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`.
|
|
194
196
|
|
|
195
197
|
```bash
|
|
196
|
-
pnpm run watch #
|
|
197
|
-
pnpm run build #
|
|
198
|
+
pnpm run watch # Watch; writes dist-dev
|
|
199
|
+
pnpm run build # One-shot production compile into dist-dev
|
|
198
200
|
```
|
|
199
201
|
|
|
200
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 { PHPFile, 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
|
|
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";
|
|
@@ -105,9 +105,6 @@ export declare function constantEntries<K extends string, V>(object: {
|
|
|
105
105
|
[k in K]: V;
|
|
106
106
|
}): [K, V][];
|
|
107
107
|
export declare function determineCurrentSourceType(dest: string | AdvancedOutputConfig, srcIsDirectory: boolean): SourceType;
|
|
108
|
-
export interface WebpackPlugin {
|
|
109
|
-
apply(compiler: Compiler): void;
|
|
110
|
-
}
|
|
111
108
|
export type ObjectIndividualExternalDepConfig = {
|
|
112
109
|
import?: string | [string, ...string[]];
|
|
113
110
|
handle: string;
|
|
@@ -161,6 +158,13 @@ export type PlauditWordpressWebpackConfig = {
|
|
|
161
158
|
targetNamespace?: string;
|
|
162
159
|
useBlockSupportsAsThemeJsonDefaults?: boolean;
|
|
163
160
|
};
|
|
161
|
+
/** Unified-loader watch output: `dist` → `dist-dev` when SERVER_MODE is development. */
|
|
162
|
+
export declare function shouldWriteDistDev(config: Pick<PlauditWordpressWebpackConfig, 'outputDir' | 'useUnifiedLoader' | 'omitDistDev'>): boolean;
|
|
163
|
+
/**
|
|
164
|
+
* This MUST be kept in sync with the copy in @plaudit/dev-webpack-plugin
|
|
165
|
+
* @returns true for `dist-dev` (or any `*-dev` output folder produced by {@link shouldWriteDistDev}).
|
|
166
|
+
*/
|
|
167
|
+
export declare function isDistDevOutputPath(outputPath: string): boolean;
|
|
164
168
|
export declare function applyStandards(config: PlauditWordpressWebpackConfig): {
|
|
165
169
|
readonly standard?: "2026-03-13";
|
|
166
170
|
readonly standaloneBlocks?: boolean;
|
|
@@ -240,8 +244,6 @@ type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N
|
|
|
240
244
|
export declare function arrayIsLength<T, N extends number>(arr: T[] | null | undefined, length: N): arr is TupleOf<T, N>;
|
|
241
245
|
export declare function kebabCase(value: string): string;
|
|
242
246
|
export declare function camelCaseForPHPLabels(value: string): string;
|
|
243
|
-
export declare function loadEnvFile(filePath: string): Promise<Record<string, string>>;
|
|
244
|
-
export declare function parseEnvFile(contents: string): Record<string, string>;
|
|
245
247
|
export declare function newCleanWebpackError(error: string | ConstructorParameters<typeof WebpackError>): WebpackError;
|
|
246
248
|
export declare function newWebpackErrorForFile(error: string | ConstructorParameters<typeof WebpackError>, file: string): WebpackError;
|
|
247
249
|
/**
|
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;
|
|
@@ -40,8 +42,6 @@ exports.hasAtLeastOneItem = hasAtLeastOneItem;
|
|
|
40
42
|
exports.arrayIsLength = arrayIsLength;
|
|
41
43
|
exports.kebabCase = kebabCase;
|
|
42
44
|
exports.camelCaseForPHPLabels = camelCaseForPHPLabels;
|
|
43
|
-
exports.loadEnvFile = loadEnvFile;
|
|
44
|
-
exports.parseEnvFile = parseEnvFile;
|
|
45
45
|
exports.newCleanWebpackError = newCleanWebpackError;
|
|
46
46
|
exports.newWebpackErrorForFile = newWebpackErrorForFile;
|
|
47
47
|
exports.emitResolveBaseUriFunction = emitResolveBaseUriFunction;
|
|
@@ -57,7 +57,6 @@ exports.instanceOfNodeError = instanceOfNodeError;
|
|
|
57
57
|
exports.shouldBeSkipped = shouldBeSkipped;
|
|
58
58
|
const node_crypto_1 = require("node:crypto");
|
|
59
59
|
const node_fs_1 = require("node:fs");
|
|
60
|
-
const promises_1 = require("node:fs/promises");
|
|
61
60
|
const node_path_1 = __importDefault(require("node:path"));
|
|
62
61
|
const php_writer_1 = require("@plaudit/php-writer");
|
|
63
62
|
const expressions_1 = require("@plaudit/php-writer/expressions");
|
|
@@ -116,6 +115,17 @@ function determineCurrentSourceType(dest, srcIsDirectory) {
|
|
|
116
115
|
return dest.directoryLayout;
|
|
117
116
|
}
|
|
118
117
|
}
|
|
118
|
+
/** Unified-loader watch output: `dist` → `dist-dev` when SERVER_MODE is development. */
|
|
119
|
+
function shouldWriteDistDev(config) {
|
|
120
|
+
return !!(config.outputDir && config.useUnifiedLoader && !config.omitDistDev && (process.env['SERVER_MODE'] ?? 'development') === 'development');
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* This MUST be kept in sync with the copy in @plaudit/dev-webpack-plugin
|
|
124
|
+
* @returns true for `dist-dev` (or any `*-dev` output folder produced by {@link shouldWriteDistDev}).
|
|
125
|
+
*/
|
|
126
|
+
function isDistDevOutputPath(outputPath) {
|
|
127
|
+
return node_path_1.default.basename(outputPath.replace(/[/\\]+$/, '')).endsWith('-dev');
|
|
128
|
+
}
|
|
119
129
|
function applyStandards(config) {
|
|
120
130
|
switch (config.standard) {
|
|
121
131
|
case '2026-03-13':
|
|
@@ -251,17 +261,6 @@ function camelCaseForPHPLabels(value) {
|
|
|
251
261
|
})
|
|
252
262
|
.join("\\");
|
|
253
263
|
}
|
|
254
|
-
async function loadEnvFile(filePath) {
|
|
255
|
-
return (0, promises_1.readFile)(filePath, 'utf-8').then(parseEnvFile, () => ({}));
|
|
256
|
-
}
|
|
257
|
-
function parseEnvFile(contents) {
|
|
258
|
-
return Object.fromEntries(contents.split(/(\r?\n)+/).map(line => line.trim())
|
|
259
|
-
.filter(line => line.length > 0 && !line.startsWith("#") && !line.startsWith("//"))
|
|
260
|
-
.map(line => {
|
|
261
|
-
const equalsPos = line.indexOf('=');
|
|
262
|
-
return equalsPos === -1 ? [line, ""] : [line.substring(0, equalsPos), line.substring(equalsPos + 1)];
|
|
263
|
-
}));
|
|
264
|
-
}
|
|
265
264
|
function newCleanWebpackError(error) {
|
|
266
265
|
const res = typeof error === 'string' ? new webpack_1.WebpackError(error) : new webpack_1.WebpackError(...error);
|
|
267
266
|
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
|
|
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 |
|
|
11
|
+
plugins: (WebpackPluginInstance | ((this: Compiler, compiler: Compiler) => void))[];
|
|
12
12
|
removeEmptyScriptsPlugin: WebpackRemoveEmptyScriptsPlugin;
|
|
13
13
|
makeAdditionalDependencyInjectorPlugin(referencePlugin: AbstractBiPhasicGroupAndEntryPlugin<any>): AdditionalDependencyInjectorPlugin;
|
|
14
14
|
};
|
|
@@ -417,10 +417,12 @@ function commonMakeWebpackConfig(config, commonConfig, webpackConfig, externaliz
|
|
|
417
417
|
outputLibrary = webpackConfig.output?.library;
|
|
418
418
|
}
|
|
419
419
|
const extensions = processingModules ? ['.mjsx', '.mjs', '.mtsx', '.mts', '...'] : ['.jsx', '.tsx', '.ts', '...'];
|
|
420
|
+
// `dist` (SERVER_MODE=production, or omitDistDev) is always minified production. `dist-dev` follows NODE_ENV so `wp-scripts start` stays fast.
|
|
421
|
+
const isProductionBuild = !(0, shared_1.isDistDevOutputPath)(config.outputDir) || process.env['NODE_ENV'] === 'production';
|
|
420
422
|
return {
|
|
421
423
|
...webpackConfig,
|
|
422
|
-
devtool: 'source-map',
|
|
423
|
-
mode:
|
|
424
|
+
devtool: isProductionBuild ? 'source-map' : (webpackConfig.devtool ?? 'eval-cheap-module-source-map'),
|
|
425
|
+
mode: isProductionBuild ? 'production' : 'development',
|
|
424
426
|
output: {
|
|
425
427
|
...webpackConfig.output,
|
|
426
428
|
path: outPath,
|
|
@@ -431,6 +433,7 @@ function commonMakeWebpackConfig(config, commonConfig, webpackConfig, externaliz
|
|
|
431
433
|
},
|
|
432
434
|
optimization: {
|
|
433
435
|
...webpackConfig.optimization,
|
|
436
|
+
minimize: isProductionBuild,
|
|
434
437
|
splitChunks: {
|
|
435
438
|
...(webpackConfig.optimization?.splitChunks || {}),
|
|
436
439
|
cacheGroups: {
|
|
@@ -450,10 +453,12 @@ function commonMakeWebpackConfig(config, commonConfig, webpackConfig, externaliz
|
|
|
450
453
|
default: false
|
|
451
454
|
}
|
|
452
455
|
},
|
|
453
|
-
minimizer:
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
456
|
+
minimizer: isProductionBuild
|
|
457
|
+
? [
|
|
458
|
+
...(webpackConfig.optimization?.minimizer || []),
|
|
459
|
+
new css_minimizer_webpack_plugin_1.default()
|
|
460
|
+
]
|
|
461
|
+
: webpackConfig.optimization?.minimizer
|
|
457
462
|
},
|
|
458
463
|
module: {
|
|
459
464
|
...webpackConfig.module,
|
|
@@ -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
|
|
151
|
+
if ((0, shared_1.shouldWriteDistDev)({ outputDir, useUnifiedLoader, omitDistDev })) {
|
|
153
152
|
outputDir += "-dev";
|
|
154
153
|
}
|
|
155
154
|
let srcPrefixes;
|
|
@@ -348,34 +347,73 @@ function withDerivedOutputDir(cfg, sources) {
|
|
|
348
347
|
})
|
|
349
348
|
};
|
|
350
349
|
}
|
|
350
|
+
let forkTsCheckerInstalled = false;
|
|
351
|
+
function isTypeScriptSourceFile(file) {
|
|
352
|
+
return /\.[cm]?tsx?$/i.test(file.split('?')[0] ?? '');
|
|
353
|
+
}
|
|
354
|
+
const prefixes = ['c', 'm', ''];
|
|
355
|
+
const suffixes = ['x', ''];
|
|
356
|
+
const tsExtensions = prefixes.map(prefix => prefix + "ts").flatMap(name => suffixes.map(suffix => name + suffix));
|
|
351
357
|
function handleDisablingTSCheckerIfNecessary(srcRoot, scriptExtension, plugins) {
|
|
352
|
-
if (process.env["NO_TS_CHECKER"]
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
syntactic: true,
|
|
363
|
-
},
|
|
364
|
-
configOverwrite: {
|
|
365
|
-
include,
|
|
366
|
-
compilerOptions: {
|
|
367
|
-
skipLibCheck: true
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
},
|
|
371
|
-
issue: {
|
|
372
|
-
exclude(issue) {
|
|
373
|
-
return issue.code === 'TS18003'; // This hides the "no TypeScript files found" error while still monitoring the directory
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}));
|
|
358
|
+
if (process.env["NO_TS_CHECKER"] === "true" || forkTsCheckerInstalled) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const include = [];
|
|
362
|
+
for (const sr of (Array.isArray(srcRoot) ? srcRoot : [srcRoot])) {
|
|
363
|
+
if ((0, node_path_1.extname)(sr).length === 0) {
|
|
364
|
+
include.push(...tsExtensions.map(tsExt => (0, node_path_1.join)(sr, "**", `*.${tsExt}`)));
|
|
365
|
+
}
|
|
366
|
+
else if ((0, shared_1.scriptOrStyleTest)(sr, scriptExtension) === "script") {
|
|
367
|
+
include.push(sr);
|
|
377
368
|
}
|
|
378
369
|
}
|
|
370
|
+
if (include.length === 0) {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
forkTsCheckerInstalled = true;
|
|
374
|
+
let logTsStatus = true;
|
|
375
|
+
plugins.push({
|
|
376
|
+
apply(compiler) {
|
|
377
|
+
compiler.hooks.watchRun.tap('PlauditForkTsCheckerCssQuiet', watchingCompiler => {
|
|
378
|
+
const changed = [
|
|
379
|
+
...(watchingCompiler.modifiedFiles ?? []),
|
|
380
|
+
...(watchingCompiler.removedFiles ?? [])
|
|
381
|
+
];
|
|
382
|
+
logTsStatus = changed.length === 0 || changed.some(isTypeScriptSourceFile);
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
plugins.push(new fork_ts_checker_webpack_plugin_1.default({
|
|
387
|
+
async: true,
|
|
388
|
+
logger: {
|
|
389
|
+
log(message) {
|
|
390
|
+
if (!logTsStatus) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
console.log(message);
|
|
394
|
+
},
|
|
395
|
+
error(message) {
|
|
396
|
+
console.error(message);
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
typescript: {
|
|
400
|
+
diagnosticOptions: {
|
|
401
|
+
semantic: true,
|
|
402
|
+
syntactic: true,
|
|
403
|
+
},
|
|
404
|
+
configOverwrite: {
|
|
405
|
+
include,
|
|
406
|
+
compilerOptions: {
|
|
407
|
+
skipLibCheck: true
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
issue: {
|
|
412
|
+
exclude(issue) {
|
|
413
|
+
return issue.code === 'TS18003';
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}));
|
|
379
417
|
}
|
|
380
418
|
function buildCommonPluginConfig(webpackConfig, config, bundleAnalyzer, assumeGlobalizedPlauditLibraries, externalize) {
|
|
381
419
|
const plugins = webpackConfig.plugins?.filter(v => !!v)
|
|
@@ -420,7 +458,13 @@ function buildCommonPluginConfig(webpackConfig, config, bundleAnalyzer, assumeGl
|
|
|
420
458
|
}
|
|
421
459
|
const builtDependencyExtractionWebpackPlugin = (0, dependency_extraction_webpack_plugin_config_builder_1.makeDependencyExtractionPlugin)(config.externals, assumeGlobalizedPlauditLibraries, externalize);
|
|
422
460
|
plugins[dependencyExtractionPluginIndex] = builtDependencyExtractionWebpackPlugin;
|
|
423
|
-
|
|
461
|
+
if ((0, shared_1.isDistDevOutputPath)(config.outputDir)) {
|
|
462
|
+
try {
|
|
463
|
+
const { PlauditDevPlugin } = require("@plaudit/dev-webpack-plugin");
|
|
464
|
+
plugins.push(new PlauditDevPlugin());
|
|
465
|
+
}
|
|
466
|
+
catch { }
|
|
467
|
+
}
|
|
424
468
|
return {
|
|
425
469
|
plugins, removeEmptyScriptsPlugin,
|
|
426
470
|
makeAdditionalDependencyInjectorPlugin(referencePlugin) {
|
|
@@ -467,7 +511,7 @@ function destToKey(dest) {
|
|
|
467
511
|
: dest.externalize?.toString() ?? "undefined";
|
|
468
512
|
return [dest.assumeGlobalizedPlauditLibraries, dest.bundleAnalyzer, externalize].join("~");
|
|
469
513
|
}
|
|
470
|
-
function processIndividualWebpackConfig(config, webpackConfig, sources, canClean) {
|
|
514
|
+
function processIndividualWebpackConfig(config, webpackConfig, sources, canClean, preferNonModuleTsChecker) {
|
|
471
515
|
if (webpackConfig.output?.module) {
|
|
472
516
|
// This ensures that module files are emitted as module files
|
|
473
517
|
webpackConfig = {
|
|
@@ -501,7 +545,9 @@ function processIndividualWebpackConfig(config, webpackConfig, sources, canClean
|
|
|
501
545
|
return batches.map(currentBatch => {
|
|
502
546
|
const { bundleAnalyzer, assumeGlobalizedPlauditLibraries, externalize } = currentBatch[0].dest;
|
|
503
547
|
const { plugins, removeEmptyScriptsPlugin, makeAdditionalDependencyInjectorPlugin } = buildCommonPluginConfig(webpackConfig, config, bundleAnalyzer, assumeGlobalizedPlauditLibraries, externalize);
|
|
504
|
-
|
|
548
|
+
if (!processingModules || !preferNonModuleTsChecker) {
|
|
549
|
+
handleDisablingTSCheckerIfNecessary(currentBatch.flatMap(a => a.srcRoots), scriptExtension, plugins);
|
|
550
|
+
}
|
|
505
551
|
const applicableExtensionTest = (name) => {
|
|
506
552
|
return commonConfig.scriptExtension.test(name) || (!processingModules && shared_1.styleExtension.test(name));
|
|
507
553
|
};
|
|
@@ -642,12 +688,13 @@ module.exports = function (config, webpackConfig = require("@wordpress/scripts/c
|
|
|
642
688
|
webpackConfig = webpackConfig[0];
|
|
643
689
|
}
|
|
644
690
|
if (Array.isArray(webpackConfig)) {
|
|
691
|
+
const hasNonModuleCompiler = webpackConfig.some(cfg => !cfg.output?.module);
|
|
645
692
|
return webpackConfig.toSorted((a, b) => {
|
|
646
693
|
if (a.output?.module) {
|
|
647
694
|
return b.output?.module ? 0 : -1;
|
|
648
695
|
}
|
|
649
696
|
return b.output?.module ? 1 : 0;
|
|
650
|
-
}).flatMap(wpCfg => processIndividualWebpackConfig(cfg, wpCfg, sources, false));
|
|
697
|
+
}).flatMap(wpCfg => processIndividualWebpackConfig(cfg, wpCfg, sources, false, hasNonModuleCompiler));
|
|
651
698
|
}
|
|
652
|
-
return processIndividualWebpackConfig(cfg, webpackConfig, sources, true);
|
|
699
|
+
return processIndividualWebpackConfig(cfg, webpackConfig, sources, true, false);
|
|
653
700
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plaudit/webpack-extensions",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.18.0",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
+
"@plaudit/dev-webpack-plugin": "^1.0.1",
|
|
35
36
|
"@plaudit/gutenberg-api-extensions": "^2.98.2",
|
|
36
|
-
"@types/browser-sync-webpack-plugin": "^2.2.5",
|
|
37
37
|
"@types/jsdom": "^28.0.3",
|
|
38
38
|
"@types/node": "^25.9.5",
|
|
39
39
|
"@types/postcss-functions": "^4.0.4",
|
|
@@ -61,7 +61,6 @@
|
|
|
61
61
|
"@wordpress/dependency-extraction-webpack-plugin": "^6.53.0",
|
|
62
62
|
"@wordpress/scripts": "^32.6.0",
|
|
63
63
|
"autoprefixer": "^10.5.4",
|
|
64
|
-
"browser-sync": "^3.0.4",
|
|
65
64
|
"copy-webpack-plugin": "10.2.4",
|
|
66
65
|
"css-minimizer-webpack-plugin": "^8.0.0",
|
|
67
66
|
"cssnano": "^7.1.9",
|
|
@@ -83,6 +82,14 @@
|
|
|
83
82
|
"webpack-remove-empty-scripts": "^1.1.1",
|
|
84
83
|
"xml-formatter": "^3.7.0"
|
|
85
84
|
},
|
|
85
|
+
"peerDependencies": {
|
|
86
|
+
"@plaudit/dev-webpack-plugin": "^1.0.0"
|
|
87
|
+
},
|
|
88
|
+
"peerDependenciesMeta": {
|
|
89
|
+
"@plaudit/dev-webpack-plugin": {
|
|
90
|
+
"optional": true
|
|
91
|
+
}
|
|
92
|
+
},
|
|
86
93
|
"engines": {
|
|
87
94
|
"node": ">=20"
|
|
88
95
|
},
|
|
@@ -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;
|