@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 +15 -0
- package/README.md +22 -2
- package/USER-GUIDE.md +6 -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 +10 -8
- 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/utils/entrypoint-resolution-logic.d.ts +5 -2
- package/dist/wordpress-scripts-wrapper.js +83 -32
- package/package.json +20 -13
- package/dist/plugins/BrowserSyncPlugin.d.ts +0 -25
- package/dist/plugins/BrowserSyncPlugin.js +0 -212
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
|
|
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
|
@@ -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 #
|
|
196
|
-
pnpm run 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
|
|
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 { 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";
|
|
@@ -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'
|
|
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
|
|
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
|
};
|
|
@@ -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:
|
|
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
|
-
|
|
428
|
-
|
|
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
|
|
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
|
|
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"]
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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/
|
|
36
|
-
"@
|
|
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.
|
|
44
|
-
"glob": "^7.
|
|
45
|
-
"jest": "^30.
|
|
46
|
-
"lodash": "^4.
|
|
47
|
-
"mini-css-extract-plugin": "^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.
|
|
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.
|
|
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.
|
|
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.
|
|
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;
|