@wordpress/build 0.4.1-next.738bb1424.0 → 0.4.1-next.76cff8c98.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 +4 -6
- package/src/build.mjs +62 -50
- package/src/dependency-graph.mjs +36 -110
- package/src/package-utils.mjs +45 -10
- package/src/php-generator.mjs +2 -8
- package/src/wordpress-externals-plugin.mjs +4 -1
- 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,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/route-utils.mjs"],
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport { readdirSync } from 'fs';\nimport path from 'path';\n\n/**\n * Internal dependencies\n */\nimport { getPackageInfoFromFile } from './package-utils.mjs';\n\n/**\n * Get all route names from the routes directory.\n *\n * @param {string} rootDir Root directory of the project.\n * @return {string[]} Array of route names.\n */\nexport function getAllRoutes( rootDir ) {\n\tconst routesPath = path.join( rootDir, 'routes' );\n\n\ttry {\n\t\treturn readdirSync( routesPath, { withFileTypes: true } )\n\t\t\t.filter( ( dirent ) => dirent.isDirectory() )\n\t\t\t.map( ( dirent ) => dirent.name );\n\t} catch ( error ) {\n\t\t// Routes directory doesn't exist, return empty array\n\t\treturn [];\n\t}\n}\n\n/**\n * @typedef {Object} RouteMetadata\n * @property {string} name Route name.\n * @property {string} path Route path.\n * @property {string[]} pages Array of page slugs this route belongs to.\n */\n\n/**\n * Get route metadata from package.json.\n *\n * @param {string} rootDir Root directory of the project.\n * @param {string} routeName Route name.\n * @return {RouteMetadata|null} Route metadata object or null if not found.\n */\nexport function getRouteMetadata( rootDir, routeName ) {\n\tconst routePackageJson =\n\t\t/** @type {import('./package-utils.mjs').RoutePackageJson|null} */ (\n\t\t\tgetPackageInfoFromFile(\n\t\t\t\tpath.join( rootDir, 'routes', routeName, 'package.json' )\n\t\t\t)\n\t\t);\n\n\tif ( ! routePackageJson || ! routePackageJson.route ) {\n\t\treturn null;\n\t}\n\n\t// Normalize page field to always be an array\n\t// Supports both \"page\": \"string\" and \"page\": [\"array\"]\n\tconst pageField = routePackageJson.route.page;\n\t/** @type {string[]} */\n\tlet pages = [];\n\tif ( pageField ) {\n\t\tpages = Array.isArray( pageField ) ? pageField : [ pageField ];\n\t}\n\n\treturn {\n\t\tname: routeName,\n\t\tpath: routePackageJson.route.path,\n\t\tpages,\n\t};\n}\n\n/**\n * @typedef {Object} RouteFiles\n * @property {boolean} hasRoute Whether route file exists.\n * @property {boolean} hasStage Whether stage file exists.\n * @property {boolean} hasInspector Whether inspector file exists.\n * @property {boolean} hasCanvas Whether canvas file exists.\n * @property {boolean} hasStyle Whether style file exists.\n */\n\n/**\n * Check if a route has specific files.\n *\n * @param {string} routeDirectory Route directory path.\n * @return {RouteFiles} Object with boolean flags for route files.\n */\nexport function getRouteFiles( routeDirectory ) {\n\tconst extensions = [ 'tsx', 'ts', 'jsx', 'js' ];\n\tconst files = {\n\t\thasRoute: false,\n\t\thasStage: false,\n\t\thasInspector: false,\n\t\thasCanvas: false,\n\t\thasStyle: false,\n\t};\n\n\tconst entries = readdirSync( routeDirectory );\n\n\tfor ( const ext of extensions ) {\n\t\tif ( entries.includes( `route.${ ext }` ) ) {\n\t\t\tfiles.hasRoute = true;\n\t\t}\n\t\tif ( entries.includes( `stage.${ ext }` ) ) {\n\t\t\tfiles.hasStage = true;\n\t\t}\n\t\tif ( entries.includes( `inspector.${ ext }` ) ) {\n\t\t\tfiles.hasInspector = true;\n\t\t}\n\t\tif ( entries.includes( `canvas.${ ext }` ) ) {\n\t\t\tfiles.hasCanvas = true;\n\t\t}\n\t}\n\n\tif ( entries.includes( 'route.scss' ) ) {\n\t\tfiles.hasStyle = true;\n\t}\n\n\treturn files;\n}\n\n/**\n * Generate a synthetic content entry point for a route.\n * This creates a module that imports and re-exports stage, inspector, and canvas components.\n *\n * @param {RouteFiles} files Route files information.\n * @return {string} Generated entry point code.\n */\nexport function generateContentEntryPoint( files ) {\n\tconst lines = [];\n\n\tif ( files.hasStage ) {\n\t\tlines.push( \"export { stage } from './stage';\" );\n\t}\n\n\tif ( files.hasInspector ) {\n\t\tlines.push( \"export { inspector } from './inspector';\" );\n\t}\n\n\tif ( files.hasCanvas ) {\n\t\tlines.push( \"export { canvas } from './canvas';\" );\n\t}\n\n\t// If no components exist, export empty object\n\tif ( lines.length === 0 ) {\n\t\tlines.push( 'export {};' );\n\t}\n\n\treturn lines.join( '\\n' );\n}\n"],
|
|
5
|
+
"mappings": ";AAGA,SAAS,mBAAmB;AAC5B,OAAO,UAAU;AAKjB,SAAS,8BAA8B;AAQhC,SAAS,aAAc,SAAU;AACvC,QAAM,aAAa,KAAK,KAAM,SAAS,QAAS;AAEhD,MAAI;AACH,WAAO,YAAa,YAAY,EAAE,eAAe,KAAK,CAAE,EACtD,OAAQ,CAAE,WAAY,OAAO,YAAY,CAAE,EAC3C,IAAK,CAAE,WAAY,OAAO,IAAK;AAAA,EAClC,SAAU,OAAQ;AAEjB,WAAO,CAAC;AAAA,EACT;AACD;AAgBO,SAAS,iBAAkB,SAAS,WAAY;AACtD,QAAM;AAAA;AAAA,IAEJ;AAAA,MACC,KAAK,KAAM,SAAS,UAAU,WAAW,cAAe;AAAA,IACzD;AAAA;AAGF,MAAK,CAAE,oBAAoB,CAAE,iBAAiB,OAAQ;AACrD,WAAO;AAAA,EACR;AAIA,QAAM,YAAY,iBAAiB,MAAM;AAEzC,MAAI,QAAQ,CAAC;AACb,MAAK,WAAY;AAChB,YAAQ,MAAM,QAAS,SAAU,IAAI,YAAY,CAAE,SAAU;AAAA,EAC9D;AAEA,SAAO;AAAA,IACN,MAAM;AAAA,IACN,MAAM,iBAAiB,MAAM;AAAA,IAC7B;AAAA,EACD;AACD;AAiBO,SAAS,cAAe,gBAAiB;AAC/C,QAAM,aAAa,CAAE,OAAO,MAAM,OAAO,IAAK;AAC9C,QAAM,QAAQ;AAAA,IACb,UAAU;AAAA,IACV,UAAU;AAAA,IACV,cAAc;AAAA,IACd,WAAW;AAAA,IACX,UAAU;AAAA,EACX;AAEA,QAAM,UAAU,YAAa,cAAe;AAE5C,aAAY,OAAO,YAAa;AAC/B,QAAK,QAAQ,SAAU,SAAU,GAAI,EAAG,GAAI;AAC3C,YAAM,WAAW;AAAA,IAClB;AACA,QAAK,QAAQ,SAAU,SAAU,GAAI,EAAG,GAAI;AAC3C,YAAM,WAAW;AAAA,IAClB;AACA,QAAK,QAAQ,SAAU,aAAc,GAAI,EAAG,GAAI;AAC/C,YAAM,eAAe;AAAA,IACtB;AACA,QAAK,QAAQ,SAAU,UAAW,GAAI,EAAG,GAAI;AAC5C,YAAM,YAAY;AAAA,IACnB;AAAA,EACD;AAEA,MAAK,QAAQ,SAAU,YAAa,GAAI;AACvC,UAAM,WAAW;AAAA,EAClB;AAEA,SAAO;AACR;AASO,SAAS,0BAA2B,OAAQ;AAClD,QAAM,QAAQ,CAAC;AAEf,MAAK,MAAM,UAAW;AACrB,UAAM,KAAM,kCAAmC;AAAA,EAChD;AAEA,MAAK,MAAM,cAAe;AACzB,UAAM,KAAM,0CAA2C;AAAA,EACxD;AAEA,MAAK,MAAM,WAAY;AACtB,UAAM,KAAM,oCAAqC;AAAA,EAClD;AAGA,MAAK,MAAM,WAAW,GAAI;AACzB,UAAM,KAAM,YAAa;AAAA,EAC1B;AAEA,SAAO,MAAM,KAAM,IAAK;AACzB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// packages/wp-build/src/wordpress-externals-plugin.mjs
|
|
2
|
+
import { writeFile, mkdir, readFile } from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { camelCase } from "change-case";
|
|
5
|
+
import { createHash } from "crypto";
|
|
6
|
+
import { getPackageInfo } from "./package-utils.mjs";
|
|
7
|
+
async function generateContentHash(filePaths, algorithm = "sha256", length = 20) {
|
|
8
|
+
const hashBuilder = createHash(algorithm);
|
|
9
|
+
const sortedPaths = [...filePaths].sort();
|
|
10
|
+
for (const filePath of sortedPaths) {
|
|
11
|
+
const content = await readFile(filePath);
|
|
12
|
+
hashBuilder.update(content);
|
|
13
|
+
}
|
|
14
|
+
const fullHash = hashBuilder.digest("hex");
|
|
15
|
+
return fullHash.slice(0, length);
|
|
16
|
+
}
|
|
17
|
+
function createWordpressExternalsPlugin(packageNamespace, scriptGlobal, externalNamespaces = {}, handlePrefix) {
|
|
18
|
+
return function wordpressExternalsPlugin(assetName = "index.min", buildFormat = "iife", extraDependencies = [], generateAssetFile = true) {
|
|
19
|
+
return {
|
|
20
|
+
name: "wordpress-externals",
|
|
21
|
+
/** @param {import('esbuild').PluginBuild} build */
|
|
22
|
+
setup(build) {
|
|
23
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
24
|
+
const moduleDependencies = /* @__PURE__ */ new Map();
|
|
25
|
+
function isScriptModuleImport(packageJson, subpath) {
|
|
26
|
+
const { wpScriptModuleExports } = packageJson;
|
|
27
|
+
if (!wpScriptModuleExports) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if (!subpath) {
|
|
31
|
+
if (typeof wpScriptModuleExports === "string") {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
if (typeof wpScriptModuleExports === "object" && wpScriptModuleExports["."]) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (typeof wpScriptModuleExports === "object" && wpScriptModuleExports[`./${subpath}`]) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
const vendorExternals = {
|
|
45
|
+
react: { global: "React", handle: "react" },
|
|
46
|
+
"react-dom": { global: "ReactDOM", handle: "react-dom" },
|
|
47
|
+
"react/jsx-runtime": {
|
|
48
|
+
global: "ReactJSXRuntime",
|
|
49
|
+
handle: "react-jsx-runtime"
|
|
50
|
+
},
|
|
51
|
+
"react/jsx-dev-runtime": {
|
|
52
|
+
global: "ReactJSXRuntime",
|
|
53
|
+
handle: "react-jsx-runtime"
|
|
54
|
+
},
|
|
55
|
+
moment: { global: "moment", handle: "moment" },
|
|
56
|
+
lodash: { global: "lodash", handle: "lodash" },
|
|
57
|
+
"lodash-es": { global: "lodash", handle: "lodash" },
|
|
58
|
+
jquery: { global: "jQuery", handle: "jquery" }
|
|
59
|
+
};
|
|
60
|
+
const packageExternals = [
|
|
61
|
+
{
|
|
62
|
+
namespace: "wordpress",
|
|
63
|
+
pattern: /^@wordpress\//,
|
|
64
|
+
globalName: "wp",
|
|
65
|
+
handlePrefix: "wp"
|
|
66
|
+
}
|
|
67
|
+
];
|
|
68
|
+
if (packageNamespace && packageNamespace !== "wordpress" && scriptGlobal !== false) {
|
|
69
|
+
packageExternals.push({
|
|
70
|
+
namespace: packageNamespace,
|
|
71
|
+
pattern: new RegExp(`^@${packageNamespace}/`),
|
|
72
|
+
globalName: scriptGlobal,
|
|
73
|
+
handlePrefix: handlePrefix || packageNamespace
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
for (const [namespace, config] of Object.entries(
|
|
77
|
+
externalNamespaces
|
|
78
|
+
)) {
|
|
79
|
+
packageExternals.push({
|
|
80
|
+
namespace,
|
|
81
|
+
pattern: new RegExp(`^@${namespace}/`),
|
|
82
|
+
globalName: config.global,
|
|
83
|
+
handlePrefix: config.handlePrefix || namespace
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
for (const [packageName, config] of Object.entries(
|
|
87
|
+
vendorExternals
|
|
88
|
+
)) {
|
|
89
|
+
build.onResolve(
|
|
90
|
+
{
|
|
91
|
+
filter: new RegExp(`^${packageName}$`)
|
|
92
|
+
},
|
|
93
|
+
/** @param {import('esbuild').OnResolveArgs} args */
|
|
94
|
+
(args) => {
|
|
95
|
+
dependencies.add(config.handle);
|
|
96
|
+
return {
|
|
97
|
+
path: args.path,
|
|
98
|
+
namespace: "vendor-external",
|
|
99
|
+
pluginData: { global: config.global }
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
for (const externalConfig of packageExternals) {
|
|
105
|
+
build.onResolve(
|
|
106
|
+
{ filter: externalConfig.pattern },
|
|
107
|
+
/** @param {import('esbuild').OnResolveArgs} args */
|
|
108
|
+
(args) => {
|
|
109
|
+
const parts = args.path.split("/");
|
|
110
|
+
let packageName = args.path;
|
|
111
|
+
let subpath = null;
|
|
112
|
+
if (parts.length > 2) {
|
|
113
|
+
packageName = parts.slice(0, 2).join("/");
|
|
114
|
+
subpath = parts.slice(2).join("/");
|
|
115
|
+
}
|
|
116
|
+
const shortName = parts[1];
|
|
117
|
+
const handle = `${externalConfig.handlePrefix}-${shortName}`;
|
|
118
|
+
const packageJson = getPackageInfo(
|
|
119
|
+
packageName,
|
|
120
|
+
args.resolveDir
|
|
121
|
+
);
|
|
122
|
+
if (!packageJson) {
|
|
123
|
+
return void 0;
|
|
124
|
+
}
|
|
125
|
+
let isScriptModule = isScriptModuleImport(
|
|
126
|
+
packageJson,
|
|
127
|
+
subpath
|
|
128
|
+
);
|
|
129
|
+
let isScript = !!packageJson.wpScript;
|
|
130
|
+
if (isScriptModule && isScript) {
|
|
131
|
+
isScript = buildFormat === "iife";
|
|
132
|
+
isScriptModule = buildFormat === "esm";
|
|
133
|
+
}
|
|
134
|
+
const kind = args.kind === "dynamic-import" ? "dynamic" : "static";
|
|
135
|
+
if (isScriptModule) {
|
|
136
|
+
if (kind === "static") {
|
|
137
|
+
moduleDependencies.set(
|
|
138
|
+
args.path,
|
|
139
|
+
"static"
|
|
140
|
+
);
|
|
141
|
+
} else if (!moduleDependencies.has(args.path)) {
|
|
142
|
+
moduleDependencies.set(
|
|
143
|
+
args.path,
|
|
144
|
+
"dynamic"
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
path: args.path,
|
|
149
|
+
external: true,
|
|
150
|
+
sideEffects: !!packageJson.sideEffects
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (isScript) {
|
|
154
|
+
dependencies.add(handle);
|
|
155
|
+
return {
|
|
156
|
+
path: args.path,
|
|
157
|
+
namespace: "package-external",
|
|
158
|
+
pluginData: {
|
|
159
|
+
globalName: externalConfig.globalName
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return void 0;
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
build.onLoad(
|
|
168
|
+
{ filter: /.*/, namespace: "vendor-external" },
|
|
169
|
+
/** @param {import('esbuild').OnLoadArgs} args */
|
|
170
|
+
(args) => {
|
|
171
|
+
const global = args.pluginData.global;
|
|
172
|
+
return {
|
|
173
|
+
contents: `module.exports = window.${global};`,
|
|
174
|
+
loader: "js"
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
build.onLoad(
|
|
179
|
+
{ filter: /.*/, namespace: "package-external" },
|
|
180
|
+
/** @param {import('esbuild').OnLoadArgs} args */
|
|
181
|
+
(args) => {
|
|
182
|
+
const globalName = args.pluginData.globalName;
|
|
183
|
+
const packagePath = args.path.split("/").slice(1).join("/");
|
|
184
|
+
const camelCasedName = camelCase(packagePath);
|
|
185
|
+
return {
|
|
186
|
+
contents: `module.exports = window.${globalName}.${camelCasedName};`,
|
|
187
|
+
loader: "js"
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
build.onEnd(
|
|
192
|
+
/** @param {import('esbuild').BuildResult} result */
|
|
193
|
+
async (result) => {
|
|
194
|
+
if (result.errors.length > 0) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const moduleDependenciesArray = Array.from(
|
|
198
|
+
moduleDependencies.entries()
|
|
199
|
+
).sort(([a], [b]) => a.localeCompare(b)).map(
|
|
200
|
+
([dep, kind]) => `array('id' => '${dep}', 'import' => '${kind}')`
|
|
201
|
+
);
|
|
202
|
+
const moduleDependenciesString = moduleDependenciesArray.length > 0 ? moduleDependenciesArray.join(", ") : "";
|
|
203
|
+
if (!generateAssetFile) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const allDependencies = /* @__PURE__ */ new Set([
|
|
207
|
+
...dependencies,
|
|
208
|
+
...extraDependencies
|
|
209
|
+
]);
|
|
210
|
+
const dependenciesString = Array.from(allDependencies).sort().map((dep) => `'${dep}'`).join(", ");
|
|
211
|
+
let outputFilePath;
|
|
212
|
+
if (build.initialOptions.outfile) {
|
|
213
|
+
outputFilePath = build.initialOptions.outfile;
|
|
214
|
+
} else if (build.initialOptions.outdir) {
|
|
215
|
+
outputFilePath = path.join(
|
|
216
|
+
build.initialOptions.outdir,
|
|
217
|
+
`${assetName}.js`
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
const filesToHash = [];
|
|
221
|
+
if (outputFilePath) {
|
|
222
|
+
filesToHash.push(outputFilePath);
|
|
223
|
+
}
|
|
224
|
+
const version = await generateContentHash(filesToHash);
|
|
225
|
+
const parts = [
|
|
226
|
+
`'dependencies' => array(${dependenciesString})`
|
|
227
|
+
];
|
|
228
|
+
if (moduleDependenciesString) {
|
|
229
|
+
parts.push(
|
|
230
|
+
`'module_dependencies' => array(${moduleDependenciesString})`
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
parts.push(`'version' => '${version}'`);
|
|
234
|
+
const assetContent = `<?php return array(${parts.join(
|
|
235
|
+
", "
|
|
236
|
+
)});`;
|
|
237
|
+
const outputDir = build.initialOptions.outdir || path.dirname(
|
|
238
|
+
build.initialOptions.outfile || "build"
|
|
239
|
+
);
|
|
240
|
+
const assetFilePath = path.join(
|
|
241
|
+
outputDir,
|
|
242
|
+
`${assetName}.asset.php`
|
|
243
|
+
);
|
|
244
|
+
await mkdir(path.dirname(assetFilePath), {
|
|
245
|
+
recursive: true
|
|
246
|
+
});
|
|
247
|
+
await writeFile(assetFilePath, assetContent);
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
export {
|
|
255
|
+
createWordpressExternalsPlugin
|
|
256
|
+
};
|
|
257
|
+
//# sourceMappingURL=wordpress-externals-plugin.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/wordpress-externals-plugin.mjs"],
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport { writeFile, mkdir, readFile } from 'fs/promises';\nimport path from 'path';\nimport { camelCase } from 'change-case';\nimport { createHash } from 'crypto';\n\n/**\n * Internal dependencies\n */\nimport { getPackageInfo } from './package-utils.mjs';\n\n/**\n * Generate a content hash from file contents.\n * Uses SHA256 algorithm for broad compatibility across Node.js versions.\n *\n * @param {string[]} filePaths - Absolute paths to files to hash\n * @param {string} algorithm - Hash algorithm (default: 'sha256')\n * @param {number} length - Hash length (default: 20)\n * @return {Promise<string>} Content hash string\n */\nasync function generateContentHash(\n\tfilePaths,\n\talgorithm = 'sha256',\n\tlength = 20\n) {\n\tconst hashBuilder = createHash( algorithm );\n\n\t// Sort paths for deterministic ordering\n\tconst sortedPaths = [ ...filePaths ].sort();\n\n\t// Read and hash each file\n\tfor ( const filePath of sortedPaths ) {\n\t\tconst content = await readFile( filePath );\n\t\thashBuilder.update( content );\n\t}\n\n\t// Generate hash as hex string and truncate\n\tconst fullHash = hashBuilder.digest( 'hex' );\n\treturn fullHash.slice( 0, length );\n}\n\n/**\n * Create WordPress externals plugin for esbuild.\n * This plugin handles WordPress package externals and vendor libraries,\n * treating them as external dependencies available via global variables.\n *\n * @param {string} packageNamespace Custom package namespace (e.g., 'wordpress', 'my-plugin').\n * @param {string|false} scriptGlobal Global variable name (e.g., 'wp', 'myPlugin') or false to disable globals.\n * @param {Object} externalNamespaces Additional namespaces to externalize (e.g., { 'woo': { global: 'woo', handlePrefix: 'woocommerce' } }).\n * @param {string} handlePrefix Handle prefix for main package (e.g., 'wp', 'mp'). Defaults to packageNamespace.\n * @return {Function} Function that creates the esbuild plugin instance.\n */\nexport function createWordpressExternalsPlugin(\n\tpackageNamespace,\n\tscriptGlobal,\n\texternalNamespaces = {},\n\thandlePrefix\n) {\n\t/**\n\t * WordPress externals plugin for esbuild.\n\t *\n\t * @param {string} assetName Base name for the asset file (e.g., 'index.min').\n\t * @param {string} buildFormat Build format: 'iife' for classic scripts, 'esm' for modules.\n\t * @param {Array<string>} extraDependencies Additional dependencies to include in the asset file.\n\t * @param {boolean} generateAssetFile Whether to generate the .asset.php file. Default true.\n\t * @return {Object} esbuild plugin object.\n\t */\n\treturn function wordpressExternalsPlugin(\n\t\tassetName = 'index.min',\n\t\tbuildFormat = 'iife',\n\t\textraDependencies = [],\n\t\tgenerateAssetFile = true\n\t) {\n\t\treturn {\n\t\t\tname: 'wordpress-externals',\n\t\t\t/** @param {import('esbuild').PluginBuild} build */\n\t\t\tsetup( build ) {\n\t\t\t\tconst dependencies = new Set();\n\t\t\t\tconst moduleDependencies = new Map();\n\n\t\t\t\t/**\n\t\t\t\t * Check if a package import is a script module.\n\t\t\t\t * A package is considered a script module if it has wpScriptModuleExports\n\t\t\t\t * and the specific import path (root or subpath) is declared in wpScriptModuleExports.\n\t\t\t\t *\n\t\t\t\t * @param {import('./package-utils.mjs').PackageJson} packageJson Package.json object.\n\t\t\t\t * @param {string|null} subpath Subpath after package name, or null for root import.\n\t\t\t\t * @return {boolean} True if the import is a script module.\n\t\t\t\t */\n\t\t\t\tfunction isScriptModuleImport( packageJson, subpath ) {\n\t\t\t\t\tconst { wpScriptModuleExports } = packageJson;\n\n\t\t\t\t\tif ( ! wpScriptModuleExports ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Root import: @wordpress/package-name\n\t\t\t\t\tif ( ! subpath ) {\n\t\t\t\t\t\tif ( typeof wpScriptModuleExports === 'string' ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\ttypeof wpScriptModuleExports === 'object' &&\n\t\t\t\t\t\t\twpScriptModuleExports[ '.' ]\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Subpath import: @wordpress/package-name/subpath\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof wpScriptModuleExports === 'object' &&\n\t\t\t\t\t\twpScriptModuleExports[ `./${ subpath }` ]\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Map of vendor packages to their global variables and handles\n\t\t\t\tconst vendorExternals = {\n\t\t\t\t\treact: { global: 'React', handle: 'react' },\n\t\t\t\t\t'react-dom': { global: 'ReactDOM', handle: 'react-dom' },\n\t\t\t\t\t'react/jsx-runtime': {\n\t\t\t\t\t\tglobal: 'ReactJSXRuntime',\n\t\t\t\t\t\thandle: 'react-jsx-runtime',\n\t\t\t\t\t},\n\t\t\t\t\t'react/jsx-dev-runtime': {\n\t\t\t\t\t\tglobal: 'ReactJSXRuntime',\n\t\t\t\t\t\thandle: 'react-jsx-runtime',\n\t\t\t\t\t},\n\t\t\t\t\tmoment: { global: 'moment', handle: 'moment' },\n\t\t\t\t\tlodash: { global: 'lodash', handle: 'lodash' },\n\t\t\t\t\t'lodash-es': { global: 'lodash', handle: 'lodash' },\n\t\t\t\t\tjquery: { global: 'jQuery', handle: 'jquery' },\n\t\t\t\t};\n\n\t\t\t\t// Build list of package namespace configurations\n\t\t\t\tconst packageExternals = [\n\t\t\t\t\t{\n\t\t\t\t\t\tnamespace: 'wordpress',\n\t\t\t\t\t\tpattern: /^@wordpress\\//,\n\t\t\t\t\t\tglobalName: 'wp',\n\t\t\t\t\t\thandlePrefix: 'wp',\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\t// Add custom namespace if different from wordpress and scriptGlobal is not false\n\t\t\t\tif (\n\t\t\t\t\tpackageNamespace &&\n\t\t\t\t\tpackageNamespace !== 'wordpress' &&\n\t\t\t\t\tscriptGlobal !== false\n\t\t\t\t) {\n\t\t\t\t\tpackageExternals.push( {\n\t\t\t\t\t\tnamespace: packageNamespace,\n\t\t\t\t\t\tpattern: new RegExp( `^@${ packageNamespace }/` ),\n\t\t\t\t\t\tglobalName: scriptGlobal,\n\t\t\t\t\t\thandlePrefix: handlePrefix || packageNamespace,\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\t// Add additional external namespaces from configuration\n\t\t\t\tfor ( const [ namespace, config ] of Object.entries(\n\t\t\t\t\texternalNamespaces\n\t\t\t\t) ) {\n\t\t\t\t\tpackageExternals.push( {\n\t\t\t\t\t\tnamespace,\n\t\t\t\t\t\tpattern: new RegExp( `^@${ namespace }/` ),\n\t\t\t\t\t\tglobalName: config.global,\n\t\t\t\t\t\thandlePrefix: config.handlePrefix || namespace,\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tfor ( const [ packageName, config ] of Object.entries(\n\t\t\t\t\tvendorExternals\n\t\t\t\t) ) {\n\t\t\t\t\tbuild.onResolve(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfilter: new RegExp( `^${ packageName }$` ),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t/** @param {import('esbuild').OnResolveArgs} args */\n\t\t\t\t\t\t( args ) => {\n\t\t\t\t\t\t\tdependencies.add( config.handle );\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tpath: args.path,\n\t\t\t\t\t\t\t\tnamespace: 'vendor-external',\n\t\t\t\t\t\t\t\tpluginData: { global: config.global },\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Handle package namespace externals (wordpress and custom)\n\t\t\t\tfor ( const externalConfig of packageExternals ) {\n\t\t\t\t\tbuild.onResolve(\n\t\t\t\t\t\t{ filter: externalConfig.pattern },\n\t\t\t\t\t\t/** @param {import('esbuild').OnResolveArgs} args */\n\t\t\t\t\t\t( args ) => {\n\t\t\t\t\t\t\t// Extract package name and subpath from import\n\t\t\t\t\t\t\t// e.g., '@wordpress/blocks/sub/path' \u2192 packageName='@wordpress/blocks', subpath='sub/path'\n\t\t\t\t\t\t\tconst parts = args.path.split( '/' );\n\t\t\t\t\t\t\tlet packageName = args.path;\n\t\t\t\t\t\t\tlet subpath = null;\n\t\t\t\t\t\t\tif ( parts.length > 2 ) {\n\t\t\t\t\t\t\t\tpackageName = parts.slice( 0, 2 ).join( '/' );\n\t\t\t\t\t\t\t\tsubpath = parts.slice( 2 ).join( '/' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst shortName = parts[ 1 ];\n\t\t\t\t\t\t\tconst handle = `${ externalConfig.handlePrefix }-${ shortName }`;\n\n\t\t\t\t\t\t\tconst packageJson = getPackageInfo(\n\t\t\t\t\t\t\t\tpackageName,\n\t\t\t\t\t\t\t\targs.resolveDir\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif ( ! packageJson ) {\n\t\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlet isScriptModule = isScriptModuleImport(\n\t\t\t\t\t\t\t\tpackageJson,\n\t\t\t\t\t\t\t\tsubpath\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tlet isScript = !! packageJson.wpScript;\n\t\t\t\t\t\t\tif ( isScriptModule && isScript ) {\n\t\t\t\t\t\t\t\t// If the package is both a script and a script module, rely on the format being built\n\t\t\t\t\t\t\t\tisScript = buildFormat === 'iife';\n\t\t\t\t\t\t\t\tisScriptModule = buildFormat === 'esm';\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst kind =\n\t\t\t\t\t\t\t\targs.kind === 'dynamic-import'\n\t\t\t\t\t\t\t\t\t? 'dynamic'\n\t\t\t\t\t\t\t\t\t: 'static';\n\n\t\t\t\t\t\t\tif ( isScriptModule ) {\n\t\t\t\t\t\t\t\tif ( kind === 'static' ) {\n\t\t\t\t\t\t\t\t\tmoduleDependencies.set(\n\t\t\t\t\t\t\t\t\t\targs.path,\n\t\t\t\t\t\t\t\t\t\t'static'\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\t\t\t! moduleDependencies.has( args.path )\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tmoduleDependencies.set(\n\t\t\t\t\t\t\t\t\t\targs.path,\n\t\t\t\t\t\t\t\t\t\t'dynamic'\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tpath: args.path,\n\t\t\t\t\t\t\t\t\texternal: true,\n\t\t\t\t\t\t\t\t\tsideEffects: !! packageJson.sideEffects,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( isScript ) {\n\t\t\t\t\t\t\t\tdependencies.add( handle );\n\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tpath: args.path,\n\t\t\t\t\t\t\t\t\tnamespace: 'package-external',\n\t\t\t\t\t\t\t\t\tpluginData: {\n\t\t\t\t\t\t\t\t\t\tglobalName: externalConfig.globalName,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tbuild.onLoad(\n\t\t\t\t\t{ filter: /.*/, namespace: 'vendor-external' },\n\t\t\t\t\t/** @param {import('esbuild').OnLoadArgs} args */\n\t\t\t\t\t( args ) => {\n\t\t\t\t\t\tconst global = args.pluginData.global;\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontents: `module.exports = window.${ global };`,\n\t\t\t\t\t\t\tloader: 'js',\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\tbuild.onLoad(\n\t\t\t\t\t{ filter: /.*/, namespace: 'package-external' },\n\t\t\t\t\t/** @param {import('esbuild').OnLoadArgs} args */\n\t\t\t\t\t( args ) => {\n\t\t\t\t\t\tconst globalName = args.pluginData.globalName;\n\t\t\t\t\t\t// Extract package name after '@namespace/' prefix\n\t\t\t\t\t\t// e.g., '@wordpress/blocks' or '@my-plugin/data'\n\t\t\t\t\t\tconst packagePath = args.path\n\t\t\t\t\t\t\t.split( '/' )\n\t\t\t\t\t\t\t.slice( 1 )\n\t\t\t\t\t\t\t.join( '/' );\n\t\t\t\t\t\tconst camelCasedName = camelCase( packagePath );\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontents: `module.exports = window.${ globalName }.${ camelCasedName };`,\n\t\t\t\t\t\t\tloader: 'js',\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\tbuild.onEnd(\n\t\t\t\t\t/** @param {import('esbuild').BuildResult} result */\n\t\t\t\t\tasync ( result ) => {\n\t\t\t\t\t\tif ( result.errors.length > 0 ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Format module dependencies as array of arrays with 'id' and 'import' keys\n\t\t\t\t\t\tconst moduleDependenciesArray = Array.from(\n\t\t\t\t\t\t\tmoduleDependencies.entries()\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.sort( ( [ a ], [ b ] ) => a.localeCompare( b ) )\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t( [ dep, kind ] ) =>\n\t\t\t\t\t\t\t\t\t`array('id' => '${ dep }', 'import' => '${ kind }')`\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst moduleDependenciesString =\n\t\t\t\t\t\t\tmoduleDependenciesArray.length > 0\n\t\t\t\t\t\t\t\t? moduleDependenciesArray.join( ', ' )\n\t\t\t\t\t\t\t\t: '';\n\n\t\t\t\t\t\t// Only generate asset file if requested\n\t\t\t\t\t\tif ( ! generateAssetFile ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Merge discovered dependencies with extra dependencies\n\t\t\t\t\t\tconst allDependencies = new Set( [\n\t\t\t\t\t\t\t...dependencies,\n\t\t\t\t\t\t\t...extraDependencies,\n\t\t\t\t\t\t] );\n\n\t\t\t\t\t\tconst dependenciesString = Array.from( allDependencies )\n\t\t\t\t\t\t\t.sort()\n\t\t\t\t\t\t\t.map( ( dep ) => `'${ dep }'` )\n\t\t\t\t\t\t\t.join( ', ' );\n\n\t\t\t\t\t\t// Determine output file path from build config\n\t\t\t\t\t\tlet outputFilePath;\n\t\t\t\t\t\tif ( build.initialOptions.outfile ) {\n\t\t\t\t\t\t\toutputFilePath = build.initialOptions.outfile;\n\t\t\t\t\t\t} else if ( build.initialOptions.outdir ) {\n\t\t\t\t\t\t\t// Construct expected output filename from assetName\n\t\t\t\t\t\t\t// e.g., assetName='index.min' -> 'index.min.js'\n\t\t\t\t\t\t\toutputFilePath = path.join(\n\t\t\t\t\t\t\t\tbuild.initialOptions.outdir,\n\t\t\t\t\t\t\t\t`${ assetName }.js`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Collect files to hash\n\t\t\t\t\t\tconst filesToHash = [];\n\t\t\t\t\t\tif ( outputFilePath ) {\n\t\t\t\t\t\t\tfilesToHash.push( outputFilePath );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Generate content-based version hash\n\t\t\t\t\t\tconst version =\n\t\t\t\t\t\t\tawait generateContentHash( filesToHash );\n\n\t\t\t\t\t\tconst parts = [\n\t\t\t\t\t\t\t`'dependencies' => array(${ dependenciesString })`,\n\t\t\t\t\t\t];\n\t\t\t\t\t\tif ( moduleDependenciesString ) {\n\t\t\t\t\t\t\tparts.push(\n\t\t\t\t\t\t\t\t`'module_dependencies' => array(${ moduleDependenciesString })`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparts.push( `'version' => '${ version }'` );\n\t\t\t\t\t\tconst assetContent = `<?php return array(${ parts.join(\n\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t) });`;\n\n\t\t\t\t\t\tconst outputDir =\n\t\t\t\t\t\t\tbuild.initialOptions.outdir ||\n\t\t\t\t\t\t\tpath.dirname(\n\t\t\t\t\t\t\t\tbuild.initialOptions.outfile || 'build'\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst assetFilePath = path.join(\n\t\t\t\t\t\t\toutputDir,\n\t\t\t\t\t\t\t`${ assetName }.asset.php`\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tawait mkdir( path.dirname( assetFilePath ), {\n\t\t\t\t\t\t\trecursive: true,\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tawait writeFile( assetFilePath, assetContent );\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t};\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/build",
|
|
3
|
-
"version": "0.4.1-next.
|
|
3
|
+
"version": "0.4.1-next.76cff8c98.0",
|
|
4
4
|
"description": "Build tool for WordPress plugins.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"npm": ">=10.2.3"
|
|
25
25
|
},
|
|
26
26
|
"type": "module",
|
|
27
|
-
"
|
|
27
|
+
"module": "./src/build.mjs",
|
|
28
28
|
"exports": {
|
|
29
29
|
".": {
|
|
30
30
|
"import": "./src/build.mjs"
|
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@emotion/babel-plugin": "11.11.0",
|
|
39
|
-
"@types/toposort": "2.0.7",
|
|
40
39
|
"autoprefixer": "10.4.21",
|
|
41
40
|
"browserslist-to-esbuild": "2.1.1",
|
|
42
41
|
"change-case": "4.1.2",
|
|
@@ -48,8 +47,7 @@
|
|
|
48
47
|
"fast-glob": "^3.2.7",
|
|
49
48
|
"postcss": "8.4.38",
|
|
50
49
|
"postcss-modules": "6.0.1",
|
|
51
|
-
"rtlcss": "4.3.0"
|
|
52
|
-
"toposort": "2.0.2"
|
|
50
|
+
"rtlcss": "4.3.0"
|
|
53
51
|
},
|
|
54
52
|
"peerDependencies": {
|
|
55
53
|
"@wordpress/boot": "^0.3.0",
|
|
@@ -74,5 +72,5 @@
|
|
|
74
72
|
"publishConfig": {
|
|
75
73
|
"access": "public"
|
|
76
74
|
},
|
|
77
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "368727f14b858e75179e140967c2d9ec965c8790"
|
|
78
76
|
}
|
package/src/build.mjs
CHANGED
|
@@ -43,7 +43,7 @@ const ROOT_DIR = process.cwd();
|
|
|
43
43
|
const PACKAGES_DIR = path.join( ROOT_DIR, 'packages' );
|
|
44
44
|
const BUILD_DIR = path.join( ROOT_DIR, 'build' );
|
|
45
45
|
|
|
46
|
-
const SOURCE_EXTENSIONS = '{js,ts,tsx}';
|
|
46
|
+
const SOURCE_EXTENSIONS = '{js,mjs,ts,tsx}';
|
|
47
47
|
const ASSET_EXTENSIONS = 'json';
|
|
48
48
|
const IGNORE_PATTERNS = [
|
|
49
49
|
'**/benchmark/**',
|
|
@@ -471,7 +471,6 @@ async function bundlePackage( packageName, options = {} ) {
|
|
|
471
471
|
if ( packageJson.wpScript ) {
|
|
472
472
|
const buildStyleDir = path.join( packageDir, 'build-style' );
|
|
473
473
|
const outputDir = path.join( BUILD_DIR, 'styles', packageName );
|
|
474
|
-
const isProduction = process.env.NODE_ENV === 'production';
|
|
475
474
|
|
|
476
475
|
const cssFiles = await glob(
|
|
477
476
|
normalizePath( path.join( buildStyleDir, '**/*.css' ) )
|
|
@@ -487,36 +486,39 @@ async function bundlePackage( packageName, options = {} ) {
|
|
|
487
486
|
hasMainStyle = true;
|
|
488
487
|
}
|
|
489
488
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
489
|
+
// Generate minified path: style.css -> style.min.css, style-rtl.css -> style-rtl.min.css
|
|
490
|
+
const minifiedPath = destPath.replace( /\.css$/, '.min.css' );
|
|
491
|
+
|
|
492
|
+
// Always produce both versions (like JavaScript does):
|
|
493
|
+
// 1. Non-minified version (for SCRIPT_DEBUG=true)
|
|
494
|
+
// 2. Minified version (for SCRIPT_DEBUG=false)
|
|
495
|
+
builds.push(
|
|
496
|
+
( async () => {
|
|
497
|
+
await mkdir( destDir, { recursive: true } );
|
|
498
|
+
const content = await readFile( cssFile, 'utf8' );
|
|
499
|
+
|
|
500
|
+
// Write non-minified version
|
|
501
|
+
await writeFile( destPath, content );
|
|
502
|
+
|
|
503
|
+
// Write minified version
|
|
504
|
+
const result = await postcss( [
|
|
505
|
+
cssnano( {
|
|
506
|
+
preset: [
|
|
507
|
+
'default',
|
|
508
|
+
{
|
|
509
|
+
discardComments: {
|
|
510
|
+
removeAll: true,
|
|
503
511
|
},
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
)
|
|
513
|
-
|
|
514
|
-
builds.push(
|
|
515
|
-
mkdir( destDir, { recursive: true } ).then( () =>
|
|
516
|
-
copyFile( cssFile, destPath )
|
|
517
|
-
)
|
|
518
|
-
);
|
|
519
|
-
}
|
|
512
|
+
},
|
|
513
|
+
],
|
|
514
|
+
} ),
|
|
515
|
+
] ).process( content, {
|
|
516
|
+
from: cssFile,
|
|
517
|
+
to: minifiedPath,
|
|
518
|
+
} );
|
|
519
|
+
await writeFile( minifiedPath, result.css );
|
|
520
|
+
} )()
|
|
521
|
+
);
|
|
520
522
|
}
|
|
521
523
|
}
|
|
522
524
|
|
|
@@ -623,7 +625,10 @@ async function bundlePackage( packageName, options = {} ) {
|
|
|
623
625
|
?.map( ( d ) => d.replace( /'/g, '' ) ) || [];
|
|
624
626
|
}
|
|
625
627
|
|
|
626
|
-
const styleDeps = await inferStyleDependencies(
|
|
628
|
+
const styleDeps = await inferStyleDependencies(
|
|
629
|
+
scriptDependencies,
|
|
630
|
+
packageName
|
|
631
|
+
);
|
|
627
632
|
|
|
628
633
|
builtStyles.push( {
|
|
629
634
|
handle: `${ handlePrefix }-${ packageName }`,
|
|
@@ -647,14 +652,17 @@ async function bundlePackage( packageName, options = {} ) {
|
|
|
647
652
|
* 3. Actually have a built style.css file
|
|
648
653
|
*
|
|
649
654
|
* @param {string[]} scriptDependencies Array of script handles from asset file.
|
|
655
|
+
* @param {string} packageName Package name (short name) being bundled, for context-aware resolution.
|
|
650
656
|
* @return {Promise<string[]>} Array of style handles to depend on.
|
|
651
657
|
*/
|
|
652
|
-
async function inferStyleDependencies( scriptDependencies ) {
|
|
658
|
+
async function inferStyleDependencies( scriptDependencies, packageName ) {
|
|
653
659
|
if ( ! scriptDependencies || scriptDependencies.length === 0 ) {
|
|
654
660
|
return [];
|
|
655
661
|
}
|
|
656
662
|
|
|
657
663
|
const styleDeps = [];
|
|
664
|
+
// Get the resolve directory for context-aware package resolution
|
|
665
|
+
const resolveDir = path.join( PACKAGES_DIR, packageName );
|
|
658
666
|
|
|
659
667
|
for ( const scriptHandle of scriptDependencies ) {
|
|
660
668
|
// Skip non-package dependencies (like 'react', 'lodash', etc.)
|
|
@@ -662,13 +670,13 @@ async function inferStyleDependencies( scriptDependencies ) {
|
|
|
662
670
|
continue;
|
|
663
671
|
}
|
|
664
672
|
|
|
665
|
-
// Convert handle to package name: 'wp-components' → 'components'
|
|
673
|
+
// Convert handle to package name: 'wp-components' → '@wordpress/components'
|
|
666
674
|
const shortName = scriptHandle.replace( 'wp-', '' );
|
|
667
675
|
const depPackageName = `@wordpress/${ shortName }`;
|
|
668
676
|
|
|
669
|
-
// Read the dependency's package.json
|
|
677
|
+
// Read the dependency's package.json with context-aware resolution
|
|
670
678
|
try {
|
|
671
|
-
const depPackageJson = getPackageInfo( depPackageName );
|
|
679
|
+
const depPackageJson = getPackageInfo( depPackageName, resolveDir );
|
|
672
680
|
|
|
673
681
|
if ( ! depPackageJson ) {
|
|
674
682
|
continue;
|
|
@@ -766,14 +774,14 @@ async function generateScriptRegistrationPhp( scripts, replacements ) {
|
|
|
766
774
|
}
|
|
767
775
|
|
|
768
776
|
/**
|
|
769
|
-
* Generate PHP file for version
|
|
777
|
+
* Generate PHP file for constants (version and build URL).
|
|
770
778
|
*
|
|
771
779
|
* @param {Record<string, string>} replacements PHP template replacements.
|
|
772
780
|
*/
|
|
773
|
-
async function
|
|
781
|
+
async function generateConstantsPhp( replacements ) {
|
|
774
782
|
await generatePhpFromTemplate(
|
|
775
|
-
'
|
|
776
|
-
path.join( BUILD_DIR, '
|
|
783
|
+
'constants.php.template',
|
|
784
|
+
path.join( BUILD_DIR, 'constants.php' ),
|
|
777
785
|
replacements
|
|
778
786
|
);
|
|
779
787
|
}
|
|
@@ -1065,9 +1073,9 @@ async function transpilePackage( packageName ) {
|
|
|
1065
1073
|
relativePath = './' + relativePath;
|
|
1066
1074
|
}
|
|
1067
1075
|
|
|
1068
|
-
// Replace extension: make sure that file extension is always `.
|
|
1076
|
+
// Replace extension: make sure that file extension is always `.mjs` or `.cjs`.
|
|
1069
1077
|
const newExt =
|
|
1070
|
-
build.initialOptions.format === 'cjs' ? '.cjs' : '.
|
|
1078
|
+
build.initialOptions.format === 'cjs' ? '.cjs' : '.mjs';
|
|
1071
1079
|
relativePath = relativePath.replace( /\.[jt]sx?$/, newExt );
|
|
1072
1080
|
|
|
1073
1081
|
return {
|
|
@@ -1124,6 +1132,7 @@ async function transpilePackage( packageName ) {
|
|
|
1124
1132
|
entryPoints: srcFiles,
|
|
1125
1133
|
outdir: buildModuleDir,
|
|
1126
1134
|
outbase: srcDir,
|
|
1135
|
+
outExtension: { '.js': '.mjs' },
|
|
1127
1136
|
bundle: true,
|
|
1128
1137
|
platform: 'neutral',
|
|
1129
1138
|
format: 'esm',
|
|
@@ -1469,18 +1478,20 @@ async function buildAll( baseUrlExpression ) {
|
|
|
1469
1478
|
|
|
1470
1479
|
const startTime = Date.now();
|
|
1471
1480
|
|
|
1472
|
-
// Build maps: short name ↔ full name from package.json
|
|
1481
|
+
// Build maps: short name ↔ full name ↔ package.json from package.json files
|
|
1473
1482
|
const shortToFull = new Map();
|
|
1474
1483
|
const fullToShort = new Map();
|
|
1484
|
+
const fullToPackageJson = new Map();
|
|
1475
1485
|
for ( const pkg of PACKAGES ) {
|
|
1476
1486
|
const packageJson = getPackageInfoFromFile(
|
|
1477
1487
|
path.join( PACKAGES_DIR, pkg, 'package.json' )
|
|
1478
1488
|
);
|
|
1479
1489
|
shortToFull.set( pkg, packageJson.name );
|
|
1480
1490
|
fullToShort.set( packageJson.name, pkg );
|
|
1491
|
+
fullToPackageJson.set( packageJson.name, packageJson );
|
|
1481
1492
|
}
|
|
1482
1493
|
|
|
1483
|
-
const levels = groupByDepth(
|
|
1494
|
+
const levels = groupByDepth( fullToPackageJson );
|
|
1484
1495
|
|
|
1485
1496
|
console.log( '📝 Phase 1: Transpiling packages...\n' );
|
|
1486
1497
|
|
|
@@ -1628,7 +1639,7 @@ async function buildAll( baseUrlExpression ) {
|
|
|
1628
1639
|
generateModuleRegistrationPhp( modules, phpReplacements ),
|
|
1629
1640
|
generateScriptRegistrationPhp( scripts, phpReplacements ),
|
|
1630
1641
|
generateStyleRegistrationPhp( styles, phpReplacements ),
|
|
1631
|
-
|
|
1642
|
+
generateConstantsPhp( phpReplacements ),
|
|
1632
1643
|
generateRoutesRegistry( routes, phpReplacements ),
|
|
1633
1644
|
generateRoutesPhp( routes, phpReplacements ),
|
|
1634
1645
|
generatePagesPhp( pageData, phpReplacements ),
|
|
@@ -1667,17 +1678,18 @@ async function watchMode() {
|
|
|
1667
1678
|
let isRebuilding = false;
|
|
1668
1679
|
const needsRebuild = new Set();
|
|
1669
1680
|
|
|
1670
|
-
// Build maps: short name ↔ full name from package.json (once)
|
|
1681
|
+
// Build maps: short name ↔ full name ↔ package.json from package.json files (once)
|
|
1671
1682
|
const shortToFull = new Map();
|
|
1672
1683
|
const fullToShort = new Map();
|
|
1684
|
+
const fullToPackageJson = new Map();
|
|
1673
1685
|
for ( const pkg of PACKAGES ) {
|
|
1674
1686
|
const packageJson = getPackageInfoFromFile(
|
|
1675
1687
|
path.join( PACKAGES_DIR, pkg, 'package.json' )
|
|
1676
1688
|
);
|
|
1677
1689
|
shortToFull.set( pkg, packageJson.name );
|
|
1678
1690
|
fullToShort.set( packageJson.name, pkg );
|
|
1691
|
+
fullToPackageJson.set( packageJson.name, packageJson );
|
|
1679
1692
|
}
|
|
1680
|
-
const allFullNames = Array.from( shortToFull.values() );
|
|
1681
1693
|
|
|
1682
1694
|
// Get all routes for dependency tracking
|
|
1683
1695
|
const allRoutes = getAllRoutes( ROOT_DIR );
|
|
@@ -1700,7 +1712,7 @@ async function watchMode() {
|
|
|
1700
1712
|
const fullName = shortToFull.get( packageName );
|
|
1701
1713
|
const affectedScripts = findScriptsToRebundle(
|
|
1702
1714
|
fullName,
|
|
1703
|
-
|
|
1715
|
+
fullToPackageJson
|
|
1704
1716
|
);
|
|
1705
1717
|
|
|
1706
1718
|
for ( const fullScript of affectedScripts ) {
|
|
@@ -1723,7 +1735,7 @@ async function watchMode() {
|
|
|
1723
1735
|
// Find and rebuild affected routes
|
|
1724
1736
|
const affectedRoutes = findRoutesToRebuild(
|
|
1725
1737
|
fullName,
|
|
1726
|
-
|
|
1738
|
+
fullToPackageJson,
|
|
1727
1739
|
ROOT_DIR,
|
|
1728
1740
|
allRoutes
|
|
1729
1741
|
);
|
|
@@ -1918,7 +1930,7 @@ async function main() {
|
|
|
1918
1930
|
},
|
|
1919
1931
|
'base-url': {
|
|
1920
1932
|
type: 'string',
|
|
1921
|
-
default:
|
|
1933
|
+
default: 'plugin_dir_url( __FILE__ )',
|
|
1922
1934
|
},
|
|
1923
1935
|
},
|
|
1924
1936
|
} );
|