@wordpress/build 0.4.1-next.8fd3f8831.0 → 0.5.1-next.79a2f3cdd.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/.cache/tsconfig.tsbuildinfo +1 -1
- package/LICENSE.md +1 -1
- package/build-module/build.mjs +1454 -0
- package/build-module/build.mjs.map +7 -0
- package/build-module/dependency-graph.mjs +149 -0
- package/build-module/dependency-graph.mjs.map +7 -0
- package/build-module/package-utils.mjs +44 -0
- package/build-module/package-utils.mjs.map +7 -0
- package/build-module/php-generator.mjs +48 -0
- package/build-module/php-generator.mjs.map +7 -0
- package/build-module/route-utils.mjs +85 -0
- package/build-module/route-utils.mjs.map +7 -0
- package/build-module/wordpress-externals-plugin.mjs +257 -0
- package/build-module/wordpress-externals-plugin.mjs.map +7 -0
- package/package.json +3 -3
- package/src/build.mjs +44 -41
- package/src/php-generator.mjs +2 -8
- package/templates/constants.php.template +14 -0
- package/templates/index.php.template +0 -6
- package/templates/module-registration.php.template +3 -1
- package/templates/page-wp-admin.php.template +4 -1
- package/templates/page.php.template +12 -3
- package/templates/routes-registration.php.template +4 -2
- package/templates/script-registration.php.template +4 -2
- package/templates/style-registration.php.template +6 -2
- package/templates/version.php.template +0 -11
|
@@ -0,0 +1,1454 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// packages/wp-build/src/build.mjs
|
|
4
|
+
import { readFile, writeFile, copyFile, mkdir, unlink } from "fs/promises";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { parseArgs } from "node:util";
|
|
7
|
+
import esbuild from "esbuild";
|
|
8
|
+
import glob from "fast-glob";
|
|
9
|
+
import chokidar from "chokidar";
|
|
10
|
+
import browserslistToEsbuild from "browserslist-to-esbuild";
|
|
11
|
+
import { sassPlugin, postcssModules } from "esbuild-sass-plugin";
|
|
12
|
+
import postcss from "postcss";
|
|
13
|
+
import autoprefixer from "autoprefixer";
|
|
14
|
+
import rtlcss from "rtlcss";
|
|
15
|
+
import cssnano from "cssnano";
|
|
16
|
+
import babel from "esbuild-plugin-babel";
|
|
17
|
+
import { camelCase } from "change-case";
|
|
18
|
+
import {
|
|
19
|
+
groupByDepth,
|
|
20
|
+
findScriptsToRebundle,
|
|
21
|
+
findRoutesToRebuild
|
|
22
|
+
} from "./dependency-graph.mjs";
|
|
23
|
+
import {
|
|
24
|
+
generatePhpFromTemplate,
|
|
25
|
+
getPhpReplacements
|
|
26
|
+
} from "./php-generator.mjs";
|
|
27
|
+
import { getPackageInfo, getPackageInfoFromFile } from "./package-utils.mjs";
|
|
28
|
+
import { createWordpressExternalsPlugin } from "./wordpress-externals-plugin.mjs";
|
|
29
|
+
import {
|
|
30
|
+
getAllRoutes,
|
|
31
|
+
getRouteFiles,
|
|
32
|
+
getRouteMetadata,
|
|
33
|
+
generateContentEntryPoint
|
|
34
|
+
} from "./route-utils.mjs";
|
|
35
|
+
var ROOT_DIR = process.cwd();
|
|
36
|
+
var PACKAGES_DIR = path.join(ROOT_DIR, "packages");
|
|
37
|
+
var BUILD_DIR = path.join(ROOT_DIR, "build");
|
|
38
|
+
var SOURCE_EXTENSIONS = "{js,mjs,ts,tsx}";
|
|
39
|
+
var ASSET_EXTENSIONS = "json";
|
|
40
|
+
var IGNORE_PATTERNS = [
|
|
41
|
+
"**/benchmark/**",
|
|
42
|
+
"**/{__mocks__,__tests__,test}/**",
|
|
43
|
+
"**/{storybook,stories}/**",
|
|
44
|
+
"**/*.native.*",
|
|
45
|
+
"**/*.ios.*",
|
|
46
|
+
"**/*.android.*",
|
|
47
|
+
"**/*.{spec,test}.*"
|
|
48
|
+
];
|
|
49
|
+
var TEST_FILE_PATTERNS = [
|
|
50
|
+
/\/(benchmark|__mocks__|__tests__|test|storybook|stories)\/.+/,
|
|
51
|
+
/\.(spec|test)\.(js|ts|tsx)$/,
|
|
52
|
+
/\.(native|ios|android)\.(js|ts|tsx)$/
|
|
53
|
+
];
|
|
54
|
+
function getAllPackages() {
|
|
55
|
+
return glob.sync(normalizePath(path.join(PACKAGES_DIR, "*", "package.json"))).map(
|
|
56
|
+
(packageJsonPath) => path.basename(path.dirname(packageJsonPath))
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
var PACKAGES = getAllPackages();
|
|
60
|
+
var ROOT_PACKAGE_JSON = getPackageInfoFromFile(
|
|
61
|
+
path.join(ROOT_DIR, "package.json")
|
|
62
|
+
);
|
|
63
|
+
var WP_PLUGIN_CONFIG = ROOT_PACKAGE_JSON.wpPlugin || {};
|
|
64
|
+
var SCRIPT_GLOBAL = WP_PLUGIN_CONFIG.scriptGlobal;
|
|
65
|
+
var PACKAGE_NAMESPACE = WP_PLUGIN_CONFIG.packageNamespace;
|
|
66
|
+
var HANDLE_PREFIX = WP_PLUGIN_CONFIG.handlePrefix || PACKAGE_NAMESPACE;
|
|
67
|
+
var EXTERNAL_NAMESPACES = WP_PLUGIN_CONFIG.externalNamespaces || {};
|
|
68
|
+
var PAGES = WP_PLUGIN_CONFIG.pages || [];
|
|
69
|
+
var baseDefine = {
|
|
70
|
+
"globalThis.IS_GUTENBERG_PLUGIN": JSON.stringify(
|
|
71
|
+
Boolean(process.env.npm_package_config_IS_GUTENBERG_PLUGIN)
|
|
72
|
+
),
|
|
73
|
+
"globalThis.IS_WORDPRESS_CORE": JSON.stringify(
|
|
74
|
+
Boolean(process.env.npm_package_config_IS_WORDPRESS_CORE)
|
|
75
|
+
)
|
|
76
|
+
};
|
|
77
|
+
var getDefine = (scriptDebug) => ({
|
|
78
|
+
...baseDefine,
|
|
79
|
+
"globalThis.SCRIPT_DEBUG": JSON.stringify(scriptDebug)
|
|
80
|
+
});
|
|
81
|
+
var wordpressExternalsPlugin = createWordpressExternalsPlugin(
|
|
82
|
+
PACKAGE_NAMESPACE,
|
|
83
|
+
SCRIPT_GLOBAL,
|
|
84
|
+
EXTERNAL_NAMESPACES,
|
|
85
|
+
HANDLE_PREFIX
|
|
86
|
+
);
|
|
87
|
+
var styleBundlingPlugins = [
|
|
88
|
+
// Handle CSS modules (.module.css and .module.scss)
|
|
89
|
+
sassPlugin({
|
|
90
|
+
embedded: true,
|
|
91
|
+
filter: /\.module\.(css|scss)$/,
|
|
92
|
+
transform: postcssModules({
|
|
93
|
+
generateScopedName: "[name]__[local]__[hash:base64:5]"
|
|
94
|
+
}),
|
|
95
|
+
type: "style",
|
|
96
|
+
loadPaths: ["node_modules", path.join(PACKAGES_DIR, "base-styles")]
|
|
97
|
+
}),
|
|
98
|
+
// Handle regular CSS/SCSS files
|
|
99
|
+
// Note: .module.css and .module.scss already handled by plugin above
|
|
100
|
+
sassPlugin({
|
|
101
|
+
embedded: true,
|
|
102
|
+
filter: /\.(css|scss)$/,
|
|
103
|
+
type: "style",
|
|
104
|
+
loadPaths: ["node_modules", path.join(PACKAGES_DIR, "base-styles")]
|
|
105
|
+
})
|
|
106
|
+
];
|
|
107
|
+
function normalizePath(p) {
|
|
108
|
+
return p.replace(/\\/g, "/");
|
|
109
|
+
}
|
|
110
|
+
function transformPhpContent(content, transforms) {
|
|
111
|
+
const {
|
|
112
|
+
functionPrefix = "",
|
|
113
|
+
classSuffix = "",
|
|
114
|
+
prefixFunctions = [],
|
|
115
|
+
suffixClasses = [],
|
|
116
|
+
addActionPriority
|
|
117
|
+
} = transforms;
|
|
118
|
+
content = content.toString();
|
|
119
|
+
if (prefixFunctions.length) {
|
|
120
|
+
content = content.replace(
|
|
121
|
+
new RegExp(prefixFunctions.join("|"), "g"),
|
|
122
|
+
(match) => `${functionPrefix}${match.replace(/^wp_/, "")}`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
if (suffixClasses.length) {
|
|
126
|
+
content = content.replace(
|
|
127
|
+
new RegExp(suffixClasses.join("|"), "g"),
|
|
128
|
+
(match) => `${match}${classSuffix}`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
if (functionPrefix) {
|
|
132
|
+
content = Array.from(
|
|
133
|
+
content.matchAll(/^\s*function ([^\(]+)/gm)
|
|
134
|
+
).reduce((result, [, functionName]) => {
|
|
135
|
+
return result.replace(
|
|
136
|
+
new RegExp(functionName + "(?![a-zA-Z0-9_])", "g"),
|
|
137
|
+
(match) => functionPrefix + match.replace(/^wp_/, "")
|
|
138
|
+
);
|
|
139
|
+
}, content);
|
|
140
|
+
}
|
|
141
|
+
if (addActionPriority) {
|
|
142
|
+
content = content.replace(
|
|
143
|
+
/(add_action\(\s*'init',\s*'gutenberg_register_block_[^']+'(?!,))/,
|
|
144
|
+
`$1, ${addActionPriority}`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return content;
|
|
148
|
+
}
|
|
149
|
+
function momentTimezoneAliasPlugin() {
|
|
150
|
+
return {
|
|
151
|
+
name: "moment-timezone-alias",
|
|
152
|
+
async setup(build) {
|
|
153
|
+
const { createRequire } = await import("module");
|
|
154
|
+
const require2 = createRequire(import.meta.url);
|
|
155
|
+
let preBuiltBundlePath;
|
|
156
|
+
let momentTimezoneUtilsPath;
|
|
157
|
+
const resolvePaths = () => {
|
|
158
|
+
if (preBuiltBundlePath) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
preBuiltBundlePath = require2.resolve(
|
|
162
|
+
"moment-timezone/builds/moment-timezone-with-data-1970-2030"
|
|
163
|
+
);
|
|
164
|
+
momentTimezoneUtilsPath = require2.resolve(
|
|
165
|
+
"moment-timezone/moment-timezone-utils.js"
|
|
166
|
+
);
|
|
167
|
+
};
|
|
168
|
+
build.onResolve(
|
|
169
|
+
{ filter: /^moment-timezone\/moment-timezone$/ },
|
|
170
|
+
() => {
|
|
171
|
+
resolvePaths();
|
|
172
|
+
return { path: preBuiltBundlePath };
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
build.onResolve(
|
|
176
|
+
{ filter: /^moment-timezone\/moment-timezone-utils$/ },
|
|
177
|
+
() => {
|
|
178
|
+
resolvePaths();
|
|
179
|
+
return { path: momentTimezoneUtilsPath };
|
|
180
|
+
}
|
|
181
|
+
);
|
|
182
|
+
build.onResolve({ filter: /^\.\/$/ }, (args) => {
|
|
183
|
+
if (args.importer && args.importer.includes("moment-timezone-utils")) {
|
|
184
|
+
resolvePaths();
|
|
185
|
+
return { path: preBuiltBundlePath };
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function resolveEntryPoint(packageDir, packageJson) {
|
|
192
|
+
if (packageJson.exports) {
|
|
193
|
+
const rootExport = packageJson.exports["."];
|
|
194
|
+
if (rootExport) {
|
|
195
|
+
if (typeof rootExport === "object") {
|
|
196
|
+
const entryFile = rootExport.import || rootExport.default || rootExport.require;
|
|
197
|
+
if (entryFile) {
|
|
198
|
+
return path.join(packageDir, entryFile);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (typeof rootExport === "string") {
|
|
202
|
+
return path.join(packageDir, rootExport);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (packageJson.module) {
|
|
207
|
+
return path.join(packageDir, packageJson.module);
|
|
208
|
+
}
|
|
209
|
+
if (packageJson.main) {
|
|
210
|
+
return path.join(packageDir, packageJson.main);
|
|
211
|
+
}
|
|
212
|
+
return path.join(packageDir, "build-module", "index.js");
|
|
213
|
+
}
|
|
214
|
+
async function bundlePackage(packageName, options = {}) {
|
|
215
|
+
const {
|
|
216
|
+
sourceDir = PACKAGES_DIR,
|
|
217
|
+
handlePrefix = HANDLE_PREFIX,
|
|
218
|
+
scriptGlobal = SCRIPT_GLOBAL,
|
|
219
|
+
packageNamespace = PACKAGE_NAMESPACE
|
|
220
|
+
} = options;
|
|
221
|
+
const builtModules = [];
|
|
222
|
+
const builtScripts = [];
|
|
223
|
+
const builtStyles = [];
|
|
224
|
+
const packageDir = path.join(sourceDir, packageName);
|
|
225
|
+
const packageJson = getPackageInfoFromFile(
|
|
226
|
+
path.join(sourceDir, packageName, "package.json")
|
|
227
|
+
);
|
|
228
|
+
const builds = [];
|
|
229
|
+
if (packageJson.wpScript) {
|
|
230
|
+
const entryPoint = resolveEntryPoint(packageDir, packageJson);
|
|
231
|
+
const outputDir = path.join(BUILD_DIR, "scripts", packageName);
|
|
232
|
+
const target = browserslistToEsbuild();
|
|
233
|
+
const packageFullName = packageJson.name;
|
|
234
|
+
const matchesNamespace = packageFullName.startsWith(
|
|
235
|
+
`@${packageNamespace}/`
|
|
236
|
+
);
|
|
237
|
+
const shouldExposeGlobal = matchesNamespace && scriptGlobal !== false;
|
|
238
|
+
const globalName = shouldExposeGlobal ? `${scriptGlobal}.${camelCase(packageName)}` : void 0;
|
|
239
|
+
const baseConfig = {
|
|
240
|
+
entryPoints: [entryPoint],
|
|
241
|
+
bundle: true,
|
|
242
|
+
sourcemap: true,
|
|
243
|
+
format: "iife",
|
|
244
|
+
target,
|
|
245
|
+
platform: "browser",
|
|
246
|
+
globalName
|
|
247
|
+
};
|
|
248
|
+
if (packageJson.wpScriptDefaultExport && globalName) {
|
|
249
|
+
baseConfig.footer = {
|
|
250
|
+
js: `if (typeof ${globalName} === 'object' && ${globalName}.default) { ${globalName} = ${globalName}.default; }`
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const baseBundlePlugins = [momentTimezoneAliasPlugin()];
|
|
254
|
+
builds.push(
|
|
255
|
+
esbuild.build({
|
|
256
|
+
...baseConfig,
|
|
257
|
+
outfile: path.join(outputDir, "index.min.js"),
|
|
258
|
+
minify: true,
|
|
259
|
+
define: getDefine(false),
|
|
260
|
+
plugins: [
|
|
261
|
+
...baseBundlePlugins,
|
|
262
|
+
wordpressExternalsPlugin(
|
|
263
|
+
"index.min",
|
|
264
|
+
"iife",
|
|
265
|
+
packageJson.wpScriptExtraDependencies || [],
|
|
266
|
+
true
|
|
267
|
+
// Generate asset file for minified build
|
|
268
|
+
)
|
|
269
|
+
]
|
|
270
|
+
}),
|
|
271
|
+
esbuild.build({
|
|
272
|
+
...baseConfig,
|
|
273
|
+
outfile: path.join(outputDir, "index.js"),
|
|
274
|
+
minify: false,
|
|
275
|
+
define: getDefine(true),
|
|
276
|
+
plugins: [
|
|
277
|
+
...baseBundlePlugins,
|
|
278
|
+
wordpressExternalsPlugin(
|
|
279
|
+
"index.min",
|
|
280
|
+
"iife",
|
|
281
|
+
packageJson.wpScriptExtraDependencies || [],
|
|
282
|
+
false
|
|
283
|
+
// Skip asset file for non-minified build
|
|
284
|
+
)
|
|
285
|
+
]
|
|
286
|
+
})
|
|
287
|
+
);
|
|
288
|
+
builtScripts.push({
|
|
289
|
+
handle: `${handlePrefix}-${packageName}`,
|
|
290
|
+
path: `${packageName}/index`,
|
|
291
|
+
asset: `${packageName}/index.min.asset.php`
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
if (packageJson.wpScriptModuleExports) {
|
|
295
|
+
const target = browserslistToEsbuild();
|
|
296
|
+
const rootBuildModuleDir = path.join(
|
|
297
|
+
BUILD_DIR,
|
|
298
|
+
"modules",
|
|
299
|
+
packageName
|
|
300
|
+
);
|
|
301
|
+
const exports = typeof packageJson.wpScriptModuleExports === "string" ? { ".": packageJson.wpScriptModuleExports } : packageJson.wpScriptModuleExports;
|
|
302
|
+
for (const [exportName, exportPath] of Object.entries(exports)) {
|
|
303
|
+
const fileName = exportName === "." ? "index" : exportName.replace(/^\.\//, "");
|
|
304
|
+
const entryPoint = path.join(packageDir, exportPath);
|
|
305
|
+
const baseFileName = path.basename(fileName);
|
|
306
|
+
builds.push(
|
|
307
|
+
esbuild.build({
|
|
308
|
+
entryPoints: [entryPoint],
|
|
309
|
+
outfile: path.join(
|
|
310
|
+
rootBuildModuleDir,
|
|
311
|
+
`${fileName}.min.js`
|
|
312
|
+
),
|
|
313
|
+
bundle: true,
|
|
314
|
+
sourcemap: true,
|
|
315
|
+
format: "esm",
|
|
316
|
+
target,
|
|
317
|
+
platform: "browser",
|
|
318
|
+
minify: true,
|
|
319
|
+
define: getDefine(false),
|
|
320
|
+
plugins: [
|
|
321
|
+
wordpressExternalsPlugin(
|
|
322
|
+
`${baseFileName}.min`,
|
|
323
|
+
"esm",
|
|
324
|
+
[],
|
|
325
|
+
true
|
|
326
|
+
// Generate asset file for minified build
|
|
327
|
+
)
|
|
328
|
+
]
|
|
329
|
+
}),
|
|
330
|
+
esbuild.build({
|
|
331
|
+
entryPoints: [entryPoint],
|
|
332
|
+
outfile: path.join(
|
|
333
|
+
rootBuildModuleDir,
|
|
334
|
+
`${fileName}.js`
|
|
335
|
+
),
|
|
336
|
+
bundle: true,
|
|
337
|
+
sourcemap: true,
|
|
338
|
+
format: "esm",
|
|
339
|
+
target,
|
|
340
|
+
platform: "browser",
|
|
341
|
+
minify: false,
|
|
342
|
+
define: getDefine(true),
|
|
343
|
+
plugins: [
|
|
344
|
+
wordpressExternalsPlugin(
|
|
345
|
+
`${baseFileName}.min`,
|
|
346
|
+
"esm",
|
|
347
|
+
[],
|
|
348
|
+
false
|
|
349
|
+
// Skip asset file for non-minified build
|
|
350
|
+
)
|
|
351
|
+
]
|
|
352
|
+
})
|
|
353
|
+
);
|
|
354
|
+
const scriptModuleId = exportName === "." ? `@${packageNamespace}/${packageName}` : `@${packageNamespace}/${packageName}/${fileName}`;
|
|
355
|
+
builtModules.push({
|
|
356
|
+
id: scriptModuleId,
|
|
357
|
+
path: `${packageName}/${fileName}`,
|
|
358
|
+
asset: `${packageName}/${fileName}.min.asset.php`
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
let hasMainStyle = false;
|
|
363
|
+
if (packageJson.wpScript) {
|
|
364
|
+
const buildStyleDir = path.join(packageDir, "build-style");
|
|
365
|
+
const outputDir = path.join(BUILD_DIR, "styles", packageName);
|
|
366
|
+
const cssFiles = await glob(
|
|
367
|
+
normalizePath(path.join(buildStyleDir, "**/*.css"))
|
|
368
|
+
);
|
|
369
|
+
for (const cssFile of cssFiles) {
|
|
370
|
+
const relativePath = path.relative(buildStyleDir, cssFile);
|
|
371
|
+
const destPath = path.join(outputDir, relativePath);
|
|
372
|
+
const destDir = path.dirname(destPath);
|
|
373
|
+
if (relativePath === "style.css") {
|
|
374
|
+
hasMainStyle = true;
|
|
375
|
+
}
|
|
376
|
+
const minifiedPath = destPath.replace(/\.css$/, ".min.css");
|
|
377
|
+
builds.push(
|
|
378
|
+
(async () => {
|
|
379
|
+
await mkdir(destDir, { recursive: true });
|
|
380
|
+
const content = await readFile(cssFile, "utf8");
|
|
381
|
+
await writeFile(destPath, content);
|
|
382
|
+
const result = await postcss([
|
|
383
|
+
cssnano({
|
|
384
|
+
preset: [
|
|
385
|
+
"default",
|
|
386
|
+
{
|
|
387
|
+
discardComments: {
|
|
388
|
+
removeAll: true
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
]
|
|
392
|
+
})
|
|
393
|
+
]).process(content, {
|
|
394
|
+
from: cssFile,
|
|
395
|
+
to: minifiedPath
|
|
396
|
+
});
|
|
397
|
+
await writeFile(minifiedPath, result.css);
|
|
398
|
+
})()
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (packageJson.wpCopyFiles) {
|
|
403
|
+
const { files, transforms = {} } = packageJson.wpCopyFiles;
|
|
404
|
+
const packageSourceDir = path.join(packageDir, "src");
|
|
405
|
+
const outputDir = path.join(BUILD_DIR, "scripts", packageName);
|
|
406
|
+
for (const filePattern of files) {
|
|
407
|
+
const matchedFiles = await glob(
|
|
408
|
+
normalizePath(path.join(packageDir, filePattern))
|
|
409
|
+
);
|
|
410
|
+
for (const sourceFile of matchedFiles) {
|
|
411
|
+
const relativePath = path.relative(
|
|
412
|
+
packageSourceDir,
|
|
413
|
+
sourceFile
|
|
414
|
+
);
|
|
415
|
+
const destPath = path.join(outputDir, relativePath);
|
|
416
|
+
const destDir = path.dirname(destPath);
|
|
417
|
+
if (sourceFile.endsWith(".php") && transforms.php) {
|
|
418
|
+
builds.push(
|
|
419
|
+
(async () => {
|
|
420
|
+
let finalPath = destPath;
|
|
421
|
+
let finalDir = destDir;
|
|
422
|
+
const content = await readFile(
|
|
423
|
+
sourceFile,
|
|
424
|
+
"utf8"
|
|
425
|
+
);
|
|
426
|
+
const transformed = transformPhpContent(
|
|
427
|
+
content,
|
|
428
|
+
transforms.php
|
|
429
|
+
);
|
|
430
|
+
if (transforms.php.filenameSuffix) {
|
|
431
|
+
const ext = path.extname(destPath);
|
|
432
|
+
const base = path.basename(destPath, ext);
|
|
433
|
+
finalPath = path.join(
|
|
434
|
+
destDir,
|
|
435
|
+
`${base}${transforms.php.filenameSuffix}${ext}`
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
if (transforms.php.flattenIndexFiles && path.basename(sourceFile) === "index.php") {
|
|
439
|
+
const parentDir = path.dirname(finalPath);
|
|
440
|
+
const blockName = path.basename(parentDir);
|
|
441
|
+
finalPath = path.join(
|
|
442
|
+
path.dirname(parentDir),
|
|
443
|
+
`${blockName}.php`
|
|
444
|
+
);
|
|
445
|
+
finalDir = path.dirname(finalPath);
|
|
446
|
+
}
|
|
447
|
+
await mkdir(finalDir, { recursive: true });
|
|
448
|
+
await writeFile(finalPath, transformed);
|
|
449
|
+
})()
|
|
450
|
+
);
|
|
451
|
+
} else {
|
|
452
|
+
builds.push(
|
|
453
|
+
mkdir(destDir, { recursive: true }).then(
|
|
454
|
+
() => copyFile(sourceFile, destPath)
|
|
455
|
+
)
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
if (builds.length === 0) {
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
await Promise.all(builds);
|
|
465
|
+
if (hasMainStyle) {
|
|
466
|
+
const scriptAssetPath = path.join(
|
|
467
|
+
BUILD_DIR,
|
|
468
|
+
"scripts",
|
|
469
|
+
packageName,
|
|
470
|
+
"index.min.asset.php"
|
|
471
|
+
);
|
|
472
|
+
const assetContent = await readFile(scriptAssetPath, "utf8");
|
|
473
|
+
const depsMatch = assetContent.match(
|
|
474
|
+
/'dependencies' => array\((.*?)\)/s
|
|
475
|
+
);
|
|
476
|
+
let scriptDependencies = [];
|
|
477
|
+
if (depsMatch) {
|
|
478
|
+
const depsString = depsMatch[1];
|
|
479
|
+
scriptDependencies = depsString.match(/'([^']+)'/g)?.map((d) => d.replace(/'/g, "")) || [];
|
|
480
|
+
}
|
|
481
|
+
const styleDeps = await inferStyleDependencies(
|
|
482
|
+
scriptDependencies,
|
|
483
|
+
packageName
|
|
484
|
+
);
|
|
485
|
+
builtStyles.push({
|
|
486
|
+
handle: `${handlePrefix}-${packageName}`,
|
|
487
|
+
path: `${packageName}/style`,
|
|
488
|
+
dependencies: styleDeps
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
modules: builtModules,
|
|
493
|
+
scripts: builtScripts,
|
|
494
|
+
styles: builtStyles
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
async function inferStyleDependencies(scriptDependencies, packageName) {
|
|
498
|
+
if (!scriptDependencies || scriptDependencies.length === 0) {
|
|
499
|
+
return [];
|
|
500
|
+
}
|
|
501
|
+
const styleDeps = [];
|
|
502
|
+
const resolveDir = path.join(PACKAGES_DIR, packageName);
|
|
503
|
+
for (const scriptHandle of scriptDependencies) {
|
|
504
|
+
if (!scriptHandle.startsWith("wp-")) {
|
|
505
|
+
continue;
|
|
506
|
+
}
|
|
507
|
+
const shortName = scriptHandle.replace("wp-", "");
|
|
508
|
+
const depPackageName = `@wordpress/${shortName}`;
|
|
509
|
+
try {
|
|
510
|
+
const depPackageJson = getPackageInfo(depPackageName, resolveDir);
|
|
511
|
+
if (!depPackageJson) {
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
if (depPackageJson.wpScript === true) {
|
|
515
|
+
const styleFile = path.join(
|
|
516
|
+
BUILD_DIR,
|
|
517
|
+
"styles",
|
|
518
|
+
shortName,
|
|
519
|
+
"style.css"
|
|
520
|
+
);
|
|
521
|
+
try {
|
|
522
|
+
await readFile(styleFile);
|
|
523
|
+
styleDeps.push(scriptHandle);
|
|
524
|
+
} catch {
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
} catch {
|
|
528
|
+
continue;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
return styleDeps;
|
|
532
|
+
}
|
|
533
|
+
async function generateModuleRegistrationPhp(modules, replacements) {
|
|
534
|
+
const modulesArray = modules.map(
|
|
535
|
+
(module) => ` array(
|
|
536
|
+
'id' => '${module.id}',
|
|
537
|
+
'path' => '${module.path}',
|
|
538
|
+
'asset' => '${module.asset}',
|
|
539
|
+
),`
|
|
540
|
+
).join("\n");
|
|
541
|
+
await Promise.all([
|
|
542
|
+
generatePhpFromTemplate(
|
|
543
|
+
"module-registry.php.template",
|
|
544
|
+
path.join(BUILD_DIR, "modules", "index.php"),
|
|
545
|
+
{ ...replacements, "{{MODULES}}": modulesArray }
|
|
546
|
+
),
|
|
547
|
+
generatePhpFromTemplate(
|
|
548
|
+
"module-registration.php.template",
|
|
549
|
+
path.join(BUILD_DIR, "modules.php"),
|
|
550
|
+
replacements
|
|
551
|
+
)
|
|
552
|
+
]);
|
|
553
|
+
}
|
|
554
|
+
async function generateScriptRegistrationPhp(scripts, replacements) {
|
|
555
|
+
const scriptsArray = scripts.map(
|
|
556
|
+
(script) => ` array(
|
|
557
|
+
'handle' => '${script.handle}',
|
|
558
|
+
'path' => '${script.path}',
|
|
559
|
+
'asset' => '${script.asset}',
|
|
560
|
+
),`
|
|
561
|
+
).join("\n");
|
|
562
|
+
await Promise.all([
|
|
563
|
+
generatePhpFromTemplate(
|
|
564
|
+
"script-registry.php.template",
|
|
565
|
+
path.join(BUILD_DIR, "scripts", "index.php"),
|
|
566
|
+
{ ...replacements, "{{SCRIPTS}}": scriptsArray }
|
|
567
|
+
),
|
|
568
|
+
generatePhpFromTemplate(
|
|
569
|
+
"script-registration.php.template",
|
|
570
|
+
path.join(BUILD_DIR, "scripts.php"),
|
|
571
|
+
replacements
|
|
572
|
+
)
|
|
573
|
+
]);
|
|
574
|
+
}
|
|
575
|
+
async function generateConstantsPhp(replacements) {
|
|
576
|
+
await generatePhpFromTemplate(
|
|
577
|
+
"constants.php.template",
|
|
578
|
+
path.join(BUILD_DIR, "constants.php"),
|
|
579
|
+
replacements
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
async function generateStyleRegistrationPhp(styles, replacements) {
|
|
583
|
+
const stylesArray = styles.map(
|
|
584
|
+
(style) => ` array(
|
|
585
|
+
'handle' => '${style.handle}',
|
|
586
|
+
'path' => '${style.path}',
|
|
587
|
+
'dependencies' => array(${style.dependencies.map((dep) => `'${dep}'`).join(", ")}),
|
|
588
|
+
),`
|
|
589
|
+
).join("\n");
|
|
590
|
+
await Promise.all([
|
|
591
|
+
generatePhpFromTemplate(
|
|
592
|
+
"style-registry.php.template",
|
|
593
|
+
path.join(BUILD_DIR, "styles", "index.php"),
|
|
594
|
+
{ ...replacements, "{{STYLES}}": stylesArray }
|
|
595
|
+
),
|
|
596
|
+
generatePhpFromTemplate(
|
|
597
|
+
"style-registration.php.template",
|
|
598
|
+
path.join(BUILD_DIR, "styles.php"),
|
|
599
|
+
replacements
|
|
600
|
+
)
|
|
601
|
+
]);
|
|
602
|
+
}
|
|
603
|
+
async function generateMainIndexPhp(replacements) {
|
|
604
|
+
await generatePhpFromTemplate(
|
|
605
|
+
"index.php.template",
|
|
606
|
+
path.join(BUILD_DIR, "index.php"),
|
|
607
|
+
replacements
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
async function generateRoutesRegistry(routes, replacements) {
|
|
611
|
+
if (routes.length === 0) {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
const routeEntries = routes.map((route) => {
|
|
615
|
+
const hasRouteStr = route.hasRoute ? "true" : "false";
|
|
616
|
+
const hasContentStr = route.hasContent ? "true" : "false";
|
|
617
|
+
return ` array(
|
|
618
|
+
'name' => '${route.name}',
|
|
619
|
+
'path' => '${route.path}',
|
|
620
|
+
'page' => '${route.page}',
|
|
621
|
+
'has_route' => ${hasRouteStr},
|
|
622
|
+
'has_content' => ${hasContentStr},
|
|
623
|
+
)`;
|
|
624
|
+
}).join(",\n");
|
|
625
|
+
await generatePhpFromTemplate(
|
|
626
|
+
"route-registry.php.template",
|
|
627
|
+
path.join(BUILD_DIR, "routes", "index.php"),
|
|
628
|
+
{ ...replacements, "{{ROUTES}}": routeEntries }
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
async function generateRoutesPhp(routes, replacements) {
|
|
632
|
+
if (routes.length === 0) {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
await generatePhpFromTemplate(
|
|
636
|
+
"routes-registration.php.template",
|
|
637
|
+
path.join(BUILD_DIR, "routes.php"),
|
|
638
|
+
{ ...replacements, "{{HANDLE_PREFIX}}": HANDLE_PREFIX }
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
async function generatePagesPhp(pageData, replacements) {
|
|
642
|
+
if (pageData.length === 0) {
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
const pageGenerationPromises = pageData.map(async (page) => {
|
|
646
|
+
if (page.routes.length === 0) {
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
const pageSlugUnderscore = page.slug.replace(/-/g, "_");
|
|
650
|
+
const prefixUnderscore = replacements["{{PREFIX}}"].replace(
|
|
651
|
+
/-/g,
|
|
652
|
+
"_"
|
|
653
|
+
);
|
|
654
|
+
const initModulesPhp = page.initModules.length > 0 ? page.initModules.map(
|
|
655
|
+
(moduleId) => ` $boot_dependencies[] = array( 'import' => 'static', 'id' => '${moduleId}' );`
|
|
656
|
+
).join("\n") : " // No init modules configured";
|
|
657
|
+
const templateReplacements = {
|
|
658
|
+
...replacements,
|
|
659
|
+
"{{PAGE_SLUG}}": page.slug,
|
|
660
|
+
"{{PAGE_SLUG_UNDERSCORE}}": pageSlugUnderscore,
|
|
661
|
+
"{{PREFIX}}": prefixUnderscore,
|
|
662
|
+
"{{INIT_MODULES_PHP_ARRAY}}": initModulesPhp,
|
|
663
|
+
"{{INIT_MODULES_JSON}}": JSON.stringify(page.initModules)
|
|
664
|
+
};
|
|
665
|
+
await Promise.all([
|
|
666
|
+
generatePhpFromTemplate(
|
|
667
|
+
"page.php.template",
|
|
668
|
+
path.join(BUILD_DIR, "pages", page.slug, "page.php"),
|
|
669
|
+
templateReplacements
|
|
670
|
+
),
|
|
671
|
+
generatePhpFromTemplate(
|
|
672
|
+
"page-wp-admin.php.template",
|
|
673
|
+
path.join(BUILD_DIR, "pages", page.slug, "page-wp-admin.php"),
|
|
674
|
+
templateReplacements
|
|
675
|
+
)
|
|
676
|
+
]);
|
|
677
|
+
await writeFile(
|
|
678
|
+
path.join(BUILD_DIR, "pages", page.slug, "loader.js"),
|
|
679
|
+
"// Empty module loader for page dependencies\n"
|
|
680
|
+
);
|
|
681
|
+
});
|
|
682
|
+
await Promise.all(pageGenerationPromises);
|
|
683
|
+
const pageIncludes = pageData.map((page) => {
|
|
684
|
+
return `require_once __DIR__ . '/pages/${page.slug}/page.php';
|
|
685
|
+
require_once __DIR__ . '/pages/${page.slug}/page-wp-admin.php';`;
|
|
686
|
+
}).join("\n");
|
|
687
|
+
await generatePhpFromTemplate(
|
|
688
|
+
"pages.php.template",
|
|
689
|
+
path.join(BUILD_DIR, "pages.php"),
|
|
690
|
+
{ ...replacements, "{{PAGE_INCLUDES}}": pageIncludes }
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
async function transpilePackage(packageName) {
|
|
694
|
+
const startTime = Date.now();
|
|
695
|
+
const packageDir = path.join(PACKAGES_DIR, packageName);
|
|
696
|
+
const packageJson = getPackageInfoFromFile(
|
|
697
|
+
path.join(PACKAGES_DIR, packageName, "package.json")
|
|
698
|
+
);
|
|
699
|
+
if (!packageJson) {
|
|
700
|
+
throw new Error(
|
|
701
|
+
`Could not find package.json for package: ${packageName}`
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
const srcFiles = await glob(
|
|
705
|
+
normalizePath(
|
|
706
|
+
path.join(packageDir, `src/**/*.${SOURCE_EXTENSIONS}`)
|
|
707
|
+
),
|
|
708
|
+
{
|
|
709
|
+
ignore: IGNORE_PATTERNS
|
|
710
|
+
}
|
|
711
|
+
);
|
|
712
|
+
const assetFiles = await glob(
|
|
713
|
+
normalizePath(
|
|
714
|
+
path.join(packageDir, `src/**/*.${ASSET_EXTENSIONS}`)
|
|
715
|
+
),
|
|
716
|
+
{
|
|
717
|
+
ignore: IGNORE_PATTERNS
|
|
718
|
+
}
|
|
719
|
+
);
|
|
720
|
+
const buildDir = path.join(packageDir, "build");
|
|
721
|
+
const buildModuleDir = path.join(packageDir, "build-module");
|
|
722
|
+
const srcDir = path.join(packageDir, "src");
|
|
723
|
+
const target = browserslistToEsbuild();
|
|
724
|
+
const builds = [];
|
|
725
|
+
const needsEmotionPlugin = packageName === "components";
|
|
726
|
+
const emotionPlugin = babel({
|
|
727
|
+
filter: /\.[jt]sx?$/,
|
|
728
|
+
config: {
|
|
729
|
+
plugins: ["@emotion/babel-plugin"]
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
const externalizeAllExceptCssPlugin = {
|
|
733
|
+
name: "externalize-except-css",
|
|
734
|
+
setup(build) {
|
|
735
|
+
build.onResolve({ filter: /.*/ }, async (args) => {
|
|
736
|
+
if (args.pluginData?.__fromExternalize) {
|
|
737
|
+
return null;
|
|
738
|
+
}
|
|
739
|
+
if (args.kind === "entry-point") {
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
742
|
+
if (args.path.match(/\.(css|scss)$/)) {
|
|
743
|
+
return null;
|
|
744
|
+
}
|
|
745
|
+
if (args.path.startsWith(".")) {
|
|
746
|
+
const resolved = await build.resolve(args.path, {
|
|
747
|
+
namespace: args.namespace,
|
|
748
|
+
importer: args.importer,
|
|
749
|
+
kind: args.kind,
|
|
750
|
+
resolveDir: args.resolveDir,
|
|
751
|
+
with: args.with,
|
|
752
|
+
pluginData: {
|
|
753
|
+
...args.pluginData,
|
|
754
|
+
__fromExternalize: true
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
if (resolved.errors.length > 0) {
|
|
758
|
+
return resolved;
|
|
759
|
+
}
|
|
760
|
+
let relativePath = normalizePath(
|
|
761
|
+
path.relative(args.resolveDir, resolved.path)
|
|
762
|
+
);
|
|
763
|
+
if (!relativePath.startsWith(".")) {
|
|
764
|
+
relativePath = "./" + relativePath;
|
|
765
|
+
}
|
|
766
|
+
const newExt = build.initialOptions.format === "cjs" ? ".cjs" : ".mjs";
|
|
767
|
+
relativePath = relativePath.replace(/\.[jt]sx?$/, newExt);
|
|
768
|
+
return {
|
|
769
|
+
path: relativePath,
|
|
770
|
+
external: true
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
return { path: args.path, external: true };
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
const plugins = [
|
|
778
|
+
needsEmotionPlugin && emotionPlugin,
|
|
779
|
+
externalizeAllExceptCssPlugin,
|
|
780
|
+
...styleBundlingPlugins
|
|
781
|
+
].filter(Boolean);
|
|
782
|
+
if (packageJson.main) {
|
|
783
|
+
builds.push(
|
|
784
|
+
esbuild.build({
|
|
785
|
+
entryPoints: srcFiles,
|
|
786
|
+
outdir: buildDir,
|
|
787
|
+
outbase: srcDir,
|
|
788
|
+
outExtension: { ".js": ".cjs" },
|
|
789
|
+
bundle: true,
|
|
790
|
+
platform: "node",
|
|
791
|
+
format: "cjs",
|
|
792
|
+
sourcemap: true,
|
|
793
|
+
target,
|
|
794
|
+
jsx: "automatic",
|
|
795
|
+
jsxImportSource: "react",
|
|
796
|
+
loader: { ".js": "jsx" },
|
|
797
|
+
plugins
|
|
798
|
+
})
|
|
799
|
+
);
|
|
800
|
+
for (const assetFile of assetFiles) {
|
|
801
|
+
const relativePath = path.relative(srcDir, assetFile);
|
|
802
|
+
const destPath = path.join(buildDir, relativePath);
|
|
803
|
+
const destDir = path.dirname(destPath);
|
|
804
|
+
builds.push(
|
|
805
|
+
mkdir(destDir, { recursive: true }).then(
|
|
806
|
+
() => copyFile(assetFile, destPath)
|
|
807
|
+
)
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
if (packageJson.module) {
|
|
812
|
+
builds.push(
|
|
813
|
+
esbuild.build({
|
|
814
|
+
entryPoints: srcFiles,
|
|
815
|
+
outdir: buildModuleDir,
|
|
816
|
+
outbase: srcDir,
|
|
817
|
+
outExtension: { ".js": ".mjs" },
|
|
818
|
+
bundle: true,
|
|
819
|
+
platform: "neutral",
|
|
820
|
+
format: "esm",
|
|
821
|
+
sourcemap: true,
|
|
822
|
+
target,
|
|
823
|
+
jsx: "automatic",
|
|
824
|
+
jsxImportSource: "react",
|
|
825
|
+
loader: { ".js": "jsx" },
|
|
826
|
+
plugins
|
|
827
|
+
})
|
|
828
|
+
);
|
|
829
|
+
for (const jsonFile of assetFiles) {
|
|
830
|
+
const relativePath = path.relative(srcDir, jsonFile);
|
|
831
|
+
const destPath = path.join(buildModuleDir, relativePath);
|
|
832
|
+
const destDir = path.dirname(destPath);
|
|
833
|
+
builds.push(
|
|
834
|
+
mkdir(destDir, { recursive: true }).then(
|
|
835
|
+
() => copyFile(jsonFile, destPath)
|
|
836
|
+
)
|
|
837
|
+
);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
await Promise.all(builds);
|
|
841
|
+
await compileStyles(packageName);
|
|
842
|
+
return Date.now() - startTime;
|
|
843
|
+
}
|
|
844
|
+
async function compileStyles(packageName) {
|
|
845
|
+
const packageDir = path.join(PACKAGES_DIR, packageName);
|
|
846
|
+
const packageJson = getPackageInfoFromFile(
|
|
847
|
+
path.join(PACKAGES_DIR, packageName, "package.json")
|
|
848
|
+
);
|
|
849
|
+
const scssEntryPointPatterns = packageJson.wpStyleEntryPoints || [
|
|
850
|
+
"src/*.scss"
|
|
851
|
+
];
|
|
852
|
+
const scssEntries = await glob(
|
|
853
|
+
scssEntryPointPatterns.map(
|
|
854
|
+
(pattern) => normalizePath(path.join(packageDir, pattern))
|
|
855
|
+
)
|
|
856
|
+
);
|
|
857
|
+
if (scssEntries.length === 0) {
|
|
858
|
+
return null;
|
|
859
|
+
}
|
|
860
|
+
const startTime = Date.now();
|
|
861
|
+
const buildStyleDir = path.join(packageDir, "build-style");
|
|
862
|
+
const srcDir = path.join(packageDir, "src");
|
|
863
|
+
await Promise.all(
|
|
864
|
+
scssEntries.map(async (styleEntryPath) => {
|
|
865
|
+
const relativePath = path.relative(srcDir, styleEntryPath);
|
|
866
|
+
const relativeDir = path.dirname(relativePath);
|
|
867
|
+
const entryName = path.basename(styleEntryPath, ".scss");
|
|
868
|
+
const outputDir = relativeDir === "." ? buildStyleDir : path.join(buildStyleDir, relativeDir);
|
|
869
|
+
await mkdir(outputDir, { recursive: true });
|
|
870
|
+
await esbuild.build({
|
|
871
|
+
entryPoints: [styleEntryPath],
|
|
872
|
+
outdir: outputDir,
|
|
873
|
+
bundle: true,
|
|
874
|
+
write: false,
|
|
875
|
+
loader: {
|
|
876
|
+
".scss": "css"
|
|
877
|
+
},
|
|
878
|
+
plugins: [
|
|
879
|
+
sassPlugin({
|
|
880
|
+
embedded: true,
|
|
881
|
+
loadPaths: [
|
|
882
|
+
"node_modules",
|
|
883
|
+
path.join(PACKAGES_DIR, "base-styles")
|
|
884
|
+
],
|
|
885
|
+
async transform(source) {
|
|
886
|
+
const ltrResult = await postcss([
|
|
887
|
+
autoprefixer({ grid: true })
|
|
888
|
+
]).process(source, { from: void 0 });
|
|
889
|
+
const rtlResult = await postcss([
|
|
890
|
+
rtlcss()
|
|
891
|
+
]).process(ltrResult.css, { from: void 0 });
|
|
892
|
+
await Promise.all([
|
|
893
|
+
writeFile(
|
|
894
|
+
path.join(
|
|
895
|
+
outputDir,
|
|
896
|
+
`${entryName}.css`
|
|
897
|
+
),
|
|
898
|
+
ltrResult.css
|
|
899
|
+
),
|
|
900
|
+
writeFile(
|
|
901
|
+
path.join(
|
|
902
|
+
outputDir,
|
|
903
|
+
`${entryName}-rtl.css`
|
|
904
|
+
),
|
|
905
|
+
rtlResult.css
|
|
906
|
+
)
|
|
907
|
+
]);
|
|
908
|
+
return "";
|
|
909
|
+
}
|
|
910
|
+
})
|
|
911
|
+
]
|
|
912
|
+
});
|
|
913
|
+
})
|
|
914
|
+
);
|
|
915
|
+
return Date.now() - startTime;
|
|
916
|
+
}
|
|
917
|
+
function isPackageSourceFile(filename) {
|
|
918
|
+
const relativePath = normalizePath(
|
|
919
|
+
path.relative(process.cwd(), filename)
|
|
920
|
+
);
|
|
921
|
+
if (!/\/src\/.+/.test(relativePath)) {
|
|
922
|
+
return false;
|
|
923
|
+
}
|
|
924
|
+
if (TEST_FILE_PATTERNS.some((regex) => regex.test(relativePath))) {
|
|
925
|
+
return false;
|
|
926
|
+
}
|
|
927
|
+
return PACKAGES.some((packageName) => {
|
|
928
|
+
const packagePath = normalizePath(
|
|
929
|
+
path.join("packages", packageName)
|
|
930
|
+
);
|
|
931
|
+
return relativePath.startsWith(packagePath + "/");
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
function getPackageName(filename) {
|
|
935
|
+
const relativePath = normalizePath(
|
|
936
|
+
path.relative(process.cwd(), filename)
|
|
937
|
+
);
|
|
938
|
+
for (const packageName of PACKAGES) {
|
|
939
|
+
const packagePath = normalizePath(
|
|
940
|
+
path.join("packages", packageName)
|
|
941
|
+
);
|
|
942
|
+
if (relativePath.startsWith(packagePath + "/")) {
|
|
943
|
+
return packageName;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
return null;
|
|
947
|
+
}
|
|
948
|
+
async function buildRoute(routeName) {
|
|
949
|
+
const startTime = Date.now();
|
|
950
|
+
const routeDir = path.join(ROOT_DIR, "routes", routeName);
|
|
951
|
+
const outputDir = path.join(BUILD_DIR, "routes", routeName);
|
|
952
|
+
await mkdir(outputDir, { recursive: true });
|
|
953
|
+
await copyFile(
|
|
954
|
+
path.join(routeDir, "package.json"),
|
|
955
|
+
path.join(outputDir, "package.json")
|
|
956
|
+
);
|
|
957
|
+
const files = getRouteFiles(routeDir);
|
|
958
|
+
if (files.hasRoute) {
|
|
959
|
+
const routeEntryPoints = await glob(`route.${SOURCE_EXTENSIONS}`, {
|
|
960
|
+
cwd: routeDir,
|
|
961
|
+
absolute: true
|
|
962
|
+
});
|
|
963
|
+
if (routeEntryPoints.length > 0) {
|
|
964
|
+
await Promise.all([
|
|
965
|
+
esbuild.build({
|
|
966
|
+
entryPoints: routeEntryPoints,
|
|
967
|
+
outfile: path.join(outputDir, "route.min.js"),
|
|
968
|
+
bundle: true,
|
|
969
|
+
format: "esm",
|
|
970
|
+
target: browserslistToEsbuild(),
|
|
971
|
+
minify: true,
|
|
972
|
+
define: getDefine(false),
|
|
973
|
+
plugins: [
|
|
974
|
+
wordpressExternalsPlugin(
|
|
975
|
+
"route.min",
|
|
976
|
+
"esm",
|
|
977
|
+
[],
|
|
978
|
+
true
|
|
979
|
+
// Generate asset file for minified build
|
|
980
|
+
)
|
|
981
|
+
]
|
|
982
|
+
}),
|
|
983
|
+
esbuild.build({
|
|
984
|
+
entryPoints: routeEntryPoints,
|
|
985
|
+
outfile: path.join(outputDir, "route.js"),
|
|
986
|
+
bundle: true,
|
|
987
|
+
format: "esm",
|
|
988
|
+
target: browserslistToEsbuild(),
|
|
989
|
+
minify: false,
|
|
990
|
+
define: getDefine(true),
|
|
991
|
+
plugins: [
|
|
992
|
+
wordpressExternalsPlugin(
|
|
993
|
+
"route.min",
|
|
994
|
+
"esm",
|
|
995
|
+
[],
|
|
996
|
+
false
|
|
997
|
+
// Skip asset file for non-minified build
|
|
998
|
+
)
|
|
999
|
+
]
|
|
1000
|
+
})
|
|
1001
|
+
]);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
if (files.hasStage || files.hasInspector || files.hasCanvas) {
|
|
1005
|
+
const syntheticEntry = generateContentEntryPoint(files);
|
|
1006
|
+
const tempEntryPath = path.join(routeDir, ".content-entry.js");
|
|
1007
|
+
await writeFile(tempEntryPath, syntheticEntry);
|
|
1008
|
+
await Promise.all([
|
|
1009
|
+
esbuild.build({
|
|
1010
|
+
entryPoints: [tempEntryPath],
|
|
1011
|
+
outfile: path.join(outputDir, "content.min.js"),
|
|
1012
|
+
bundle: true,
|
|
1013
|
+
format: "esm",
|
|
1014
|
+
target: browserslistToEsbuild(),
|
|
1015
|
+
minify: true,
|
|
1016
|
+
define: getDefine(false),
|
|
1017
|
+
plugins: [
|
|
1018
|
+
wordpressExternalsPlugin(
|
|
1019
|
+
"content.min",
|
|
1020
|
+
"esm",
|
|
1021
|
+
[],
|
|
1022
|
+
true
|
|
1023
|
+
// Generate asset file for minified build
|
|
1024
|
+
),
|
|
1025
|
+
...styleBundlingPlugins
|
|
1026
|
+
]
|
|
1027
|
+
}),
|
|
1028
|
+
esbuild.build({
|
|
1029
|
+
entryPoints: [tempEntryPath],
|
|
1030
|
+
outfile: path.join(outputDir, "content.js"),
|
|
1031
|
+
bundle: true,
|
|
1032
|
+
format: "esm",
|
|
1033
|
+
target: browserslistToEsbuild(),
|
|
1034
|
+
minify: false,
|
|
1035
|
+
define: getDefine(true),
|
|
1036
|
+
plugins: [
|
|
1037
|
+
wordpressExternalsPlugin(
|
|
1038
|
+
"content.min",
|
|
1039
|
+
"esm",
|
|
1040
|
+
[],
|
|
1041
|
+
false
|
|
1042
|
+
// Skip asset file for non-minified build
|
|
1043
|
+
),
|
|
1044
|
+
...styleBundlingPlugins
|
|
1045
|
+
]
|
|
1046
|
+
})
|
|
1047
|
+
]);
|
|
1048
|
+
await unlink(tempEntryPath);
|
|
1049
|
+
}
|
|
1050
|
+
return Date.now() - startTime;
|
|
1051
|
+
}
|
|
1052
|
+
async function buildAllRoutes() {
|
|
1053
|
+
console.log("\n\u{1F6A6} Phase 3: Building routes...\n");
|
|
1054
|
+
const routes = getAllRoutes(ROOT_DIR);
|
|
1055
|
+
if (routes.length === 0) {
|
|
1056
|
+
console.log(" No routes found, skipping.\n");
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
await Promise.all(
|
|
1060
|
+
routes.map(async (routeName) => {
|
|
1061
|
+
const buildTime = await buildRoute(routeName);
|
|
1062
|
+
console.log(
|
|
1063
|
+
` \u2714 Built route ${routeName} (${buildTime}ms)`
|
|
1064
|
+
);
|
|
1065
|
+
})
|
|
1066
|
+
);
|
|
1067
|
+
}
|
|
1068
|
+
async function buildAll(baseUrlExpression) {
|
|
1069
|
+
console.log("\u{1F528} Building packages...\n");
|
|
1070
|
+
const startTime = Date.now();
|
|
1071
|
+
const shortToFull = /* @__PURE__ */ new Map();
|
|
1072
|
+
const fullToShort = /* @__PURE__ */ new Map();
|
|
1073
|
+
const fullToPackageJson = /* @__PURE__ */ new Map();
|
|
1074
|
+
for (const pkg of PACKAGES) {
|
|
1075
|
+
const packageJson = getPackageInfoFromFile(
|
|
1076
|
+
path.join(PACKAGES_DIR, pkg, "package.json")
|
|
1077
|
+
);
|
|
1078
|
+
shortToFull.set(pkg, packageJson.name);
|
|
1079
|
+
fullToShort.set(packageJson.name, pkg);
|
|
1080
|
+
fullToPackageJson.set(packageJson.name, packageJson);
|
|
1081
|
+
}
|
|
1082
|
+
const levels = groupByDepth(fullToPackageJson);
|
|
1083
|
+
console.log("\u{1F4DD} Phase 1: Transpiling packages...\n");
|
|
1084
|
+
for (const level of levels) {
|
|
1085
|
+
await Promise.all(
|
|
1086
|
+
level.map(async (fullName) => {
|
|
1087
|
+
const packageName = fullToShort.get(fullName);
|
|
1088
|
+
const buildTime = await transpilePackage(packageName);
|
|
1089
|
+
console.log(
|
|
1090
|
+
` \u2714 Transpiled ${packageName} (${buildTime}ms)`
|
|
1091
|
+
);
|
|
1092
|
+
})
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1095
|
+
console.log("\n\u{1F4E6} Phase 2: Bundling packages...\n");
|
|
1096
|
+
const modules = [];
|
|
1097
|
+
const scripts = [];
|
|
1098
|
+
const styles = [];
|
|
1099
|
+
await Promise.all(
|
|
1100
|
+
PACKAGES.map(async (packageName) => {
|
|
1101
|
+
const startBundleTime = Date.now();
|
|
1102
|
+
const ret = await bundlePackage(packageName);
|
|
1103
|
+
const buildTime = Date.now() - startBundleTime;
|
|
1104
|
+
if (ret) {
|
|
1105
|
+
console.log(
|
|
1106
|
+
` \u2714 Bundled ${packageName} (${buildTime}ms)`
|
|
1107
|
+
);
|
|
1108
|
+
if (ret.modules) {
|
|
1109
|
+
modules.push(...ret.modules);
|
|
1110
|
+
}
|
|
1111
|
+
if (ret.scripts) {
|
|
1112
|
+
scripts.push(...ret.scripts);
|
|
1113
|
+
}
|
|
1114
|
+
if (ret.styles) {
|
|
1115
|
+
styles.push(...ret.styles);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
})
|
|
1119
|
+
);
|
|
1120
|
+
await buildAllRoutes();
|
|
1121
|
+
const routes = getAllRoutes(ROOT_DIR).flatMap((routeName) => {
|
|
1122
|
+
const metadata = getRouteMetadata(ROOT_DIR, routeName);
|
|
1123
|
+
if (!metadata || !metadata.pages || metadata.pages.length === 0) {
|
|
1124
|
+
return [];
|
|
1125
|
+
}
|
|
1126
|
+
const routeFiles = getRouteFiles(
|
|
1127
|
+
path.join(ROOT_DIR, "routes", routeName)
|
|
1128
|
+
);
|
|
1129
|
+
return metadata.pages.map((page) => {
|
|
1130
|
+
return {
|
|
1131
|
+
name: routeName,
|
|
1132
|
+
path: metadata.path,
|
|
1133
|
+
page,
|
|
1134
|
+
hasRoute: routeFiles.hasRoute,
|
|
1135
|
+
hasContent: routeFiles.hasStage || routeFiles.hasInspector
|
|
1136
|
+
};
|
|
1137
|
+
});
|
|
1138
|
+
});
|
|
1139
|
+
const normalizedPages = PAGES.map((page) => {
|
|
1140
|
+
if (typeof page === "string") {
|
|
1141
|
+
return { id: page, init: [], title: void 0 };
|
|
1142
|
+
}
|
|
1143
|
+
return {
|
|
1144
|
+
id: page.id,
|
|
1145
|
+
init: page.init || [],
|
|
1146
|
+
title: page.title || void 0
|
|
1147
|
+
};
|
|
1148
|
+
});
|
|
1149
|
+
const pageData = normalizedPages.map((page) => {
|
|
1150
|
+
const pageRoutes = routes.filter((r) => r.page === page.id);
|
|
1151
|
+
return {
|
|
1152
|
+
slug: page.id,
|
|
1153
|
+
routes: pageRoutes,
|
|
1154
|
+
initModules: page.init,
|
|
1155
|
+
title: page.title
|
|
1156
|
+
};
|
|
1157
|
+
});
|
|
1158
|
+
if (pageData.length > 0) {
|
|
1159
|
+
try {
|
|
1160
|
+
const { createRequire } = await import("module");
|
|
1161
|
+
const require2 = createRequire(import.meta.url);
|
|
1162
|
+
const bootPackageJson = require2.resolve(
|
|
1163
|
+
"@wordpress/boot/package.json",
|
|
1164
|
+
{ paths: [ROOT_DIR] }
|
|
1165
|
+
);
|
|
1166
|
+
const wordpressPackagesDir = path.dirname(
|
|
1167
|
+
path.dirname(bootPackageJson)
|
|
1168
|
+
);
|
|
1169
|
+
const externalPackages = [
|
|
1170
|
+
"boot",
|
|
1171
|
+
"route",
|
|
1172
|
+
"theme",
|
|
1173
|
+
"private-apis"
|
|
1174
|
+
];
|
|
1175
|
+
for (const pkgName of externalPackages) {
|
|
1176
|
+
const result = await bundlePackage(pkgName, {
|
|
1177
|
+
sourceDir: wordpressPackagesDir,
|
|
1178
|
+
handlePrefix: "wp",
|
|
1179
|
+
scriptGlobal: "wp",
|
|
1180
|
+
packageNamespace: "wordpress"
|
|
1181
|
+
});
|
|
1182
|
+
if (result && result.modules) {
|
|
1183
|
+
modules.push(...result.modules);
|
|
1184
|
+
}
|
|
1185
|
+
if (result && result.scripts) {
|
|
1186
|
+
scripts.push(...result.scripts);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
} catch (error) {
|
|
1190
|
+
console.warn(
|
|
1191
|
+
"\n\u26A0\uFE0F Warning: Could not bundle WordPress packages for pages:",
|
|
1192
|
+
error.message
|
|
1193
|
+
);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
console.log("\n\u{1F4C4} Generating PHP registration files...\n");
|
|
1197
|
+
const phpReplacements = await getPhpReplacements(
|
|
1198
|
+
ROOT_DIR,
|
|
1199
|
+
baseUrlExpression
|
|
1200
|
+
);
|
|
1201
|
+
await Promise.all([
|
|
1202
|
+
generateMainIndexPhp(phpReplacements),
|
|
1203
|
+
generateModuleRegistrationPhp(modules, phpReplacements),
|
|
1204
|
+
generateScriptRegistrationPhp(scripts, phpReplacements),
|
|
1205
|
+
generateStyleRegistrationPhp(styles, phpReplacements),
|
|
1206
|
+
generateConstantsPhp(phpReplacements),
|
|
1207
|
+
generateRoutesRegistry(routes, phpReplacements),
|
|
1208
|
+
generateRoutesPhp(routes, phpReplacements),
|
|
1209
|
+
generatePagesPhp(pageData, phpReplacements)
|
|
1210
|
+
]);
|
|
1211
|
+
console.log(" \u2714 Generated build/modules.php");
|
|
1212
|
+
console.log(" \u2714 Generated build/modules/index.php");
|
|
1213
|
+
console.log(" \u2714 Generated build/scripts.php");
|
|
1214
|
+
console.log(" \u2714 Generated build/scripts/index.php");
|
|
1215
|
+
console.log(" \u2714 Generated build/styles.php");
|
|
1216
|
+
console.log(" \u2714 Generated build/styles/index.php");
|
|
1217
|
+
console.log(" \u2714 Generated build/version.php");
|
|
1218
|
+
console.log(" \u2714 Generated build/routes.php");
|
|
1219
|
+
if (pageData.length > 0) {
|
|
1220
|
+
console.log(" \u2714 Generated build/pages.php");
|
|
1221
|
+
for (const page of pageData) {
|
|
1222
|
+
console.log(
|
|
1223
|
+
` \u2714 Generated build/pages/${page.slug}/page.php`
|
|
1224
|
+
);
|
|
1225
|
+
console.log(
|
|
1226
|
+
` \u2714 Generated build/pages/${page.slug}/page-wp-admin.php`
|
|
1227
|
+
);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
console.log(" \u2714 Generated build/index.php");
|
|
1231
|
+
const totalTime = Date.now() - startTime;
|
|
1232
|
+
console.log(
|
|
1233
|
+
`
|
|
1234
|
+
\u{1F389} All packages built successfully! (${totalTime}ms total)`
|
|
1235
|
+
);
|
|
1236
|
+
}
|
|
1237
|
+
async function watchMode() {
|
|
1238
|
+
let isRebuilding = false;
|
|
1239
|
+
const needsRebuild = /* @__PURE__ */ new Set();
|
|
1240
|
+
const shortToFull = /* @__PURE__ */ new Map();
|
|
1241
|
+
const fullToShort = /* @__PURE__ */ new Map();
|
|
1242
|
+
const fullToPackageJson = /* @__PURE__ */ new Map();
|
|
1243
|
+
for (const pkg of PACKAGES) {
|
|
1244
|
+
const packageJson = getPackageInfoFromFile(
|
|
1245
|
+
path.join(PACKAGES_DIR, pkg, "package.json")
|
|
1246
|
+
);
|
|
1247
|
+
shortToFull.set(pkg, packageJson.name);
|
|
1248
|
+
fullToShort.set(packageJson.name, pkg);
|
|
1249
|
+
fullToPackageJson.set(packageJson.name, packageJson);
|
|
1250
|
+
}
|
|
1251
|
+
const allRoutes = getAllRoutes(ROOT_DIR);
|
|
1252
|
+
async function rebuildPackage(packageName) {
|
|
1253
|
+
try {
|
|
1254
|
+
const startTime = Date.now();
|
|
1255
|
+
await transpilePackage(packageName);
|
|
1256
|
+
await bundlePackage(packageName);
|
|
1257
|
+
const buildTime = Date.now() - startTime;
|
|
1258
|
+
console.log(`\u2705 ${packageName} (${buildTime}ms)`);
|
|
1259
|
+
const fullName = shortToFull.get(packageName);
|
|
1260
|
+
const affectedScripts = findScriptsToRebundle(
|
|
1261
|
+
fullName,
|
|
1262
|
+
fullToPackageJson
|
|
1263
|
+
);
|
|
1264
|
+
for (const fullScript of affectedScripts) {
|
|
1265
|
+
const script = fullToShort.get(fullScript);
|
|
1266
|
+
try {
|
|
1267
|
+
const rebundleStartTime = Date.now();
|
|
1268
|
+
await compileStyles(script);
|
|
1269
|
+
await bundlePackage(script);
|
|
1270
|
+
const rebundleTime = Date.now() - rebundleStartTime;
|
|
1271
|
+
console.log(
|
|
1272
|
+
`\u2705 ${script} (rebundled) (${rebundleTime}ms)`
|
|
1273
|
+
);
|
|
1274
|
+
} catch (error) {
|
|
1275
|
+
console.log(
|
|
1276
|
+
`\u274C ${script} - Rebundle error: ${error.message}`
|
|
1277
|
+
);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
const affectedRoutes = findRoutesToRebuild(
|
|
1281
|
+
fullName,
|
|
1282
|
+
fullToPackageJson,
|
|
1283
|
+
ROOT_DIR,
|
|
1284
|
+
allRoutes
|
|
1285
|
+
);
|
|
1286
|
+
for (const route of affectedRoutes) {
|
|
1287
|
+
try {
|
|
1288
|
+
const rebuildStartTime = Date.now();
|
|
1289
|
+
await buildRoute(route);
|
|
1290
|
+
const rebuildTime = Date.now() - rebuildStartTime;
|
|
1291
|
+
console.log(
|
|
1292
|
+
`\u2705 routes/${route} (rebuilt) (${rebuildTime}ms)`
|
|
1293
|
+
);
|
|
1294
|
+
} catch (error) {
|
|
1295
|
+
console.log(
|
|
1296
|
+
`\u274C routes/${route} - Rebuild error: ${error.message}`
|
|
1297
|
+
);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
} catch (error) {
|
|
1301
|
+
console.log(`\u274C ${packageName} - Error: ${error.message}`);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
async function rebuildRoute(routeName) {
|
|
1305
|
+
try {
|
|
1306
|
+
const startTime = Date.now();
|
|
1307
|
+
await buildRoute(routeName);
|
|
1308
|
+
const buildTime = Date.now() - startTime;
|
|
1309
|
+
console.log(`\u2705 routes/${routeName} (${buildTime}ms)`);
|
|
1310
|
+
} catch (error) {
|
|
1311
|
+
console.log(
|
|
1312
|
+
`\u274C routes/${routeName} - Error: ${error.message}`
|
|
1313
|
+
);
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
async function processNextRebuild() {
|
|
1317
|
+
if (needsRebuild.size === 0) {
|
|
1318
|
+
isRebuilding = false;
|
|
1319
|
+
return;
|
|
1320
|
+
}
|
|
1321
|
+
const itemsToRebuild = Array.from(needsRebuild);
|
|
1322
|
+
needsRebuild.clear();
|
|
1323
|
+
for (const item of itemsToRebuild) {
|
|
1324
|
+
if (item.startsWith("route:")) {
|
|
1325
|
+
const routeName = item.slice(6);
|
|
1326
|
+
await rebuildRoute(routeName);
|
|
1327
|
+
} else {
|
|
1328
|
+
await rebuildPackage(item);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
await processNextRebuild();
|
|
1332
|
+
}
|
|
1333
|
+
const watchPaths = PACKAGES.map(
|
|
1334
|
+
(packageName) => path.join(PACKAGES_DIR, packageName, "src")
|
|
1335
|
+
);
|
|
1336
|
+
const watcher = chokidar.watch(watchPaths, {
|
|
1337
|
+
ignored: [
|
|
1338
|
+
"**/{__mocks__,__tests__,test,storybook,stories}/**",
|
|
1339
|
+
"**/*.{spec,test}.{js,ts,tsx}",
|
|
1340
|
+
"**/*.native.*"
|
|
1341
|
+
],
|
|
1342
|
+
persistent: true,
|
|
1343
|
+
ignoreInitial: true,
|
|
1344
|
+
// Reduce file descriptor usage on macOS
|
|
1345
|
+
useFsEvents: true,
|
|
1346
|
+
depth: 10,
|
|
1347
|
+
awaitWriteFinish: {
|
|
1348
|
+
stabilityThreshold: 100,
|
|
1349
|
+
pollInterval: 50
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
1352
|
+
watcher.on("error", (error) => {
|
|
1353
|
+
if (error.code === "EMFILE") {
|
|
1354
|
+
console.error(
|
|
1355
|
+
"\n\u274C Too many open files. Try increasing the limit:\n Run: ulimit -n 10240\n Or add to ~/.zshrc: ulimit -n 10240\n"
|
|
1356
|
+
);
|
|
1357
|
+
process.exit(1);
|
|
1358
|
+
}
|
|
1359
|
+
console.error("\u274C Watcher error:", error);
|
|
1360
|
+
});
|
|
1361
|
+
const handleFileChange = async (filename) => {
|
|
1362
|
+
if (!isPackageSourceFile(filename)) {
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
const packageName = getPackageName(filename);
|
|
1366
|
+
if (!packageName) {
|
|
1367
|
+
return;
|
|
1368
|
+
}
|
|
1369
|
+
if (isRebuilding) {
|
|
1370
|
+
needsRebuild.add(packageName);
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
isRebuilding = true;
|
|
1374
|
+
await rebuildPackage(packageName);
|
|
1375
|
+
await processNextRebuild();
|
|
1376
|
+
};
|
|
1377
|
+
watcher.on("change", handleFileChange);
|
|
1378
|
+
watcher.on("add", handleFileChange);
|
|
1379
|
+
watcher.on("unlink", handleFileChange);
|
|
1380
|
+
if (allRoutes.length > 0) {
|
|
1381
|
+
const routeWatchPaths = allRoutes.map(
|
|
1382
|
+
(routeName) => path.join(ROOT_DIR, "routes", routeName)
|
|
1383
|
+
);
|
|
1384
|
+
const routeWatcher = chokidar.watch(routeWatchPaths, {
|
|
1385
|
+
persistent: true,
|
|
1386
|
+
ignoreInitial: true,
|
|
1387
|
+
ignored: (filepath) => {
|
|
1388
|
+
const basename = path.basename(filepath);
|
|
1389
|
+
if (basename === ".content-entry.js") {
|
|
1390
|
+
return true;
|
|
1391
|
+
}
|
|
1392
|
+
if (filepath.includes("node_modules")) {
|
|
1393
|
+
return true;
|
|
1394
|
+
}
|
|
1395
|
+
return false;
|
|
1396
|
+
},
|
|
1397
|
+
useFsEvents: true,
|
|
1398
|
+
depth: 10,
|
|
1399
|
+
awaitWriteFinish: {
|
|
1400
|
+
stabilityThreshold: 100,
|
|
1401
|
+
pollInterval: 50
|
|
1402
|
+
}
|
|
1403
|
+
});
|
|
1404
|
+
routeWatcher.on("error", (error) => {
|
|
1405
|
+
console.error("\u274C Route watcher error:", error);
|
|
1406
|
+
});
|
|
1407
|
+
const handleRouteFileChange = async (filename) => {
|
|
1408
|
+
const routeMatch = filename.match(/routes[/\\]([^/\\]+)[/\\]/);
|
|
1409
|
+
if (!routeMatch) {
|
|
1410
|
+
return;
|
|
1411
|
+
}
|
|
1412
|
+
const routeName = routeMatch[1];
|
|
1413
|
+
if (!allRoutes.includes(routeName)) {
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
if (isRebuilding) {
|
|
1417
|
+
needsRebuild.add(`route:${routeName}`);
|
|
1418
|
+
return;
|
|
1419
|
+
}
|
|
1420
|
+
isRebuilding = true;
|
|
1421
|
+
await rebuildRoute(routeName);
|
|
1422
|
+
await processNextRebuild();
|
|
1423
|
+
};
|
|
1424
|
+
routeWatcher.on("change", handleRouteFileChange);
|
|
1425
|
+
routeWatcher.on("add", handleRouteFileChange);
|
|
1426
|
+
routeWatcher.on("unlink", handleRouteFileChange);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
async function main() {
|
|
1430
|
+
const { values } = parseArgs({
|
|
1431
|
+
options: {
|
|
1432
|
+
watch: {
|
|
1433
|
+
type: "boolean",
|
|
1434
|
+
short: "w",
|
|
1435
|
+
default: false
|
|
1436
|
+
},
|
|
1437
|
+
"base-url": {
|
|
1438
|
+
type: "string",
|
|
1439
|
+
default: "plugin_dir_url( __FILE__ )"
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
});
|
|
1443
|
+
const baseUrlExpression = values["base-url"];
|
|
1444
|
+
await buildAll(baseUrlExpression);
|
|
1445
|
+
if (values.watch) {
|
|
1446
|
+
console.log("\n\u{1F440} Watching for changes...\n");
|
|
1447
|
+
await watchMode();
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
main().catch((error) => {
|
|
1451
|
+
console.error("\u274C Build failed:", error);
|
|
1452
|
+
process.exit(1);
|
|
1453
|
+
});
|
|
1454
|
+
//# sourceMappingURL=build.mjs.map
|