@wordpress/build 0.8.1-next.v.202602271551.0 → 0.10.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/.eslintrc.cjs CHANGED
@@ -4,5 +4,11 @@ module.exports = {
4
4
  rules: {
5
5
  // Console should be allowed in a build tool
6
6
  'no-console': 'off',
7
+ /*
8
+ * These rules are designed for source files processed by esbuild, not for the build script itself,
9
+ * which runs directly in Node.js.
10
+ */
11
+ '@wordpress/no-wp-process-env': 'off',
12
+ '@wordpress/wp-global-usage': 'off',
7
13
  },
8
14
  };
package/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.10.0 (2026-03-18)
6
+
7
+ ### Breaking Changes
8
+
9
+ - `@wordpress/boot`, `@wordpress/route`, `@wordpress/theme`, and `@wordpress/private-apis` are no longer bundled. They are now expected to be provided by WordPress Core (7.0+) or the Gutenberg plugin.
10
+
11
+ ### Enhancements
12
+
13
+ - Avoid unexpected results when typecasting `IS_GUTENBERG_PLUGIN` and `IS_WORDPRESS_CORE` values to Booleans ([#75844](https://github.com/WordPress/gutenberg/pull/75844)).
14
+ - Skip PHP transforms during builds when building for WordPress Core ([#75844](https://github.com/WordPress/gutenberg/pull/75844)).
15
+
16
+ ## 0.9.0 (2026-03-04)
17
+
5
18
  ## 0.8.0 (2026-02-18)
6
19
 
7
20
  ## 0.7.0 (2026-01-29)
package/lib/build.mjs CHANGED
@@ -113,12 +113,32 @@ const HANDLE_PREFIX = WP_PLUGIN_CONFIG.handlePrefix || PACKAGE_NAMESPACE;
113
113
  const EXTERNAL_NAMESPACES = WP_PLUGIN_CONFIG.externalNamespaces || {};
114
114
  const PAGES = WP_PLUGIN_CONFIG.pages || [];
115
115
 
116
+ /**
117
+ * Interprets a configuration value as a boolean, where `"true"` and `"1"`
118
+ * are considered true while all other values are false.
119
+ *
120
+ * @param {string|undefined} value The configuration value to interpret.
121
+ * @return {boolean|undefined} Boolean interpretation of the given configuration value, or undefined if not set.
122
+ */
123
+ const boolConfigVal = ( value ) => {
124
+ if ( value === undefined ) {
125
+ return undefined;
126
+ }
127
+ return [ 'true', '1' ].includes( value.toLowerCase() );
128
+ };
129
+
116
130
  const baseDefine = {
117
131
  'globalThis.IS_GUTENBERG_PLUGIN': JSON.stringify(
118
- Boolean( process.env.npm_package_config_IS_GUTENBERG_PLUGIN )
132
+ boolConfigVal( process.env.IS_GUTENBERG_PLUGIN ) ??
133
+ boolConfigVal(
134
+ process.env.npm_package_config_IS_GUTENBERG_PLUGIN
135
+ ) ??
136
+ false
119
137
  ),
120
138
  'globalThis.IS_WORDPRESS_CORE': JSON.stringify(
121
- Boolean( process.env.npm_package_config_IS_WORDPRESS_CORE )
139
+ boolConfigVal( process.env.IS_WORDPRESS_CORE ) ??
140
+ boolConfigVal( process.env.npm_package_config_IS_WORDPRESS_CORE ) ??
141
+ false
122
142
  ),
123
143
  };
124
144
  const getDefine = ( scriptDebug ) => ( {
@@ -228,6 +248,7 @@ function createStyleBundlingPlugins( workingDir ) {
228
248
  // Handle CSS modules (.module.css and .module.scss)
229
249
  sassPlugin( {
230
250
  embedded: true,
251
+ sourceMap: false,
231
252
  filter: /\.module\.(css|scss)$/,
232
253
  transform: compileInlineStyle( { cssModules: true } ),
233
254
  type: inlineStyle,
@@ -237,6 +258,7 @@ function createStyleBundlingPlugins( workingDir ) {
237
258
  // Note: .module.css and .module.scss already handled by plugin above
238
259
  sassPlugin( {
239
260
  embedded: true,
261
+ sourceMap: false,
240
262
  filter: /\.(css|scss)$/,
241
263
  transform: compileInlineStyle(),
242
264
  type: inlineStyle,
@@ -264,8 +286,11 @@ const wasmInlinePlugin = {
264
286
  try {
265
287
  const resolved = require.resolve( args.path );
266
288
  return {
267
- path: resolved,
289
+ path: normalizePath(
290
+ path.relative( ROOT_DIR, resolved )
291
+ ),
268
292
  namespace: 'wasm-inline',
293
+ pluginData: { resolvedPath: resolved },
269
294
  };
270
295
  } catch {
271
296
  // If resolution fails, let other plugins handle it.
@@ -279,7 +304,9 @@ const wasmInlinePlugin = {
279
304
  build.onLoad(
280
305
  { filter: /.*/, namespace: 'wasm-inline' },
281
306
  async ( args ) => {
282
- const wasmBuffer = await readFile( args.path );
307
+ const wasmBuffer = await readFile(
308
+ args.pluginData.resolvedPath
309
+ );
283
310
  const base64 = wasmBuffer.toString( 'base64' );
284
311
  const dataUrl = `data:application/wasm;base64,${ base64 }`;
285
312
 
@@ -313,6 +340,19 @@ function transformPhpContent( content, transforms ) {
313
340
 
314
341
  content = content.toString();
315
342
 
343
+ /*
344
+ * Transforms are used to modify PHP files that are committed to version
345
+ * control in their wordpress-develop state (`wp_` function prefixes, `WP_`
346
+ * class prefixes, etc.). When building for WordPress Core, it's not
347
+ * necessary to perform these steps.
348
+ */
349
+ if (
350
+ boolConfigVal( process.env.IS_WORDPRESS_CORE ) ??
351
+ boolConfigVal( process.env.npm_package_config_IS_WORDPRESS_CORE )
352
+ ) {
353
+ return content;
354
+ }
355
+
316
356
  if ( prefixFunctions.length ) {
317
357
  content = content.replace(
318
358
  new RegExp( prefixFunctions.join( '|' ), 'g' ),
@@ -1769,11 +1809,23 @@ async function buildAll( baseUrlExpression ) {
1769
1809
  id: page.id,
1770
1810
  init: page.init || [],
1771
1811
  title: page.title || undefined,
1812
+ experimental: page.experimental || false,
1772
1813
  };
1773
1814
  } );
1774
1815
 
1775
- const pageData = normalizedPages.map( ( page ) => {
1776
- const pageRoutes = routes.filter( ( r ) => r.page === page.id );
1816
+ // When building for WordPress Core, exclude experimental pages.
1817
+ const isCoreBuild =
1818
+ boolConfigVal( process.env.IS_WORDPRESS_CORE ) ??
1819
+ boolConfigVal( process.env.npm_package_config_IS_WORDPRESS_CORE );
1820
+ const activePages = isCoreBuild
1821
+ ? normalizedPages.filter( ( page ) => ! page.experimental )
1822
+ : normalizedPages;
1823
+
1824
+ const activePageIds = new Set( activePages.map( ( p ) => p.id ) );
1825
+ const activeRoutes = routes.filter( ( r ) => activePageIds.has( r.page ) );
1826
+
1827
+ const pageData = activePages.map( ( page ) => {
1828
+ const pageRoutes = activeRoutes.filter( ( r ) => r.page === page.id );
1777
1829
  return {
1778
1830
  slug: page.id,
1779
1831
  routes: pageRoutes,
@@ -1782,51 +1834,6 @@ async function buildAll( baseUrlExpression ) {
1782
1834
  };
1783
1835
  } );
1784
1836
 
1785
- // Bundle boot, route, and theme packages from node_modules when pages exist
1786
- if ( pageData.length > 0 ) {
1787
- try {
1788
- const { createRequire } = await import( 'module' );
1789
- const require = createRequire( import.meta.url );
1790
-
1791
- // Resolve the @wordpress packages directory from node_modules
1792
- const bootPackageJson = require.resolve(
1793
- '@wordpress/boot/package.json',
1794
- { paths: [ ROOT_DIR ] }
1795
- );
1796
- const wordpressPackagesDir = path.dirname(
1797
- path.dirname( bootPackageJson )
1798
- );
1799
-
1800
- // Bundle boot, route, theme, and private-apis packages
1801
- const externalPackages = [
1802
- 'boot',
1803
- 'route',
1804
- 'theme',
1805
- 'private-apis',
1806
- ];
1807
- for ( const pkgName of externalPackages ) {
1808
- const result = await bundlePackage( pkgName, {
1809
- sourceDir: wordpressPackagesDir,
1810
- handlePrefix: 'wp',
1811
- scriptGlobal: 'wp',
1812
- packageNamespace: 'wordpress',
1813
- } );
1814
-
1815
- if ( result && result.modules ) {
1816
- modules.push( ...result.modules );
1817
- }
1818
- if ( result && result.scripts ) {
1819
- scripts.push( ...result.scripts );
1820
- }
1821
- }
1822
- } catch ( error ) {
1823
- console.warn(
1824
- '\n⚠️ Warning: Could not bundle WordPress packages for pages:',
1825
- error.message
1826
- );
1827
- }
1828
- }
1829
-
1830
1837
  console.log( '\n📄 Generating PHP registration files...\n' );
1831
1838
  const phpReplacements = await getPhpReplacements(
1832
1839
  ROOT_DIR,
@@ -1838,8 +1845,8 @@ async function buildAll( baseUrlExpression ) {
1838
1845
  generateScriptRegistrationPhp( scripts, phpReplacements ),
1839
1846
  generateStyleRegistrationPhp( styles, phpReplacements ),
1840
1847
  generateConstantsPhp( phpReplacements ),
1841
- generateRoutesRegistry( routes, phpReplacements ),
1842
- generateRoutesPhp( routes, phpReplacements ),
1848
+ generateRoutesRegistry( activeRoutes, phpReplacements ),
1849
+ generateRoutesPhp( activeRoutes, phpReplacements ),
1843
1850
  generatePagesPhp( pageData, phpReplacements ),
1844
1851
  ] );
1845
1852
  console.log( ' ✔ Generated build/build.php' );
@@ -2128,7 +2135,13 @@ async function main() {
2128
2135
  },
2129
2136
  'base-url': {
2130
2137
  type: 'string',
2131
- default: 'plugin_dir_url( __FILE__ )',
2138
+ default:
2139
+ boolConfigVal( process.env.IS_WORDPRESS_CORE ) ??
2140
+ boolConfigVal(
2141
+ process.env.npm_package_config_IS_WORDPRESS_CORE
2142
+ )
2143
+ ? "includes_url( 'build/' )"
2144
+ : 'plugin_dir_url( __FILE__ )',
2132
2145
  },
2133
2146
  },
2134
2147
  strict: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/build",
3
- "version": "0.8.1-next.v.202602271551.0+464abe399",
3
+ "version": "0.10.0",
4
4
  "description": "Build tool for WordPress plugins.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -77,5 +77,5 @@
77
77
  "publishConfig": {
78
78
  "access": "public"
79
79
  },
80
- "gitHead": "95aa7055a5757219e2d96a91efc69f7dd1b2d4c3"
80
+ "gitHead": "c20787b1778ae64c2db65643b1c236309d68e6ba"
81
81
  }
@@ -6,44 +6,52 @@
6
6
  * @package {{PREFIX}}
7
7
  */
8
8
 
9
- if ( ! function_exists( '{{PREFIX}}_register_script_modules' ) ) {
10
- /**
11
- * Register all script modules.
12
- */
13
- function {{PREFIX}}_register_script_modules() {
14
- // Load build constants
15
- $build_constants = require __DIR__ . '/constants.php';
16
- $modules_dir = __DIR__ . '/modules';
17
- $modules_file = $modules_dir . '/registry.php';
18
-
19
- if ( ! file_exists( $modules_file ) ) {
20
- return;
21
- }
22
-
23
- $modules = require $modules_file;
24
- $base_url = $build_constants['build_url'] . 'modules/';
25
- $extension = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '.js' : '.min.js';
26
-
27
- foreach ( $modules as $module ) {
28
- $asset_path = $modules_dir . '/' . $module['asset'];
29
- $asset = file_exists( $asset_path ) ? require $asset_path : array();
30
-
31
- // Deregister first to override any previously registered version
32
- // (e.g., Core's default modules when running as a plugin).
33
- wp_deregister_script_module( $module['id'] );
34
-
35
- wp_register_script_module(
36
- $module['id'],
37
- $base_url . $module['path'] . $extension,
38
- $asset['module_dependencies'] ?? array(),
39
- $asset['version'] ?? false,
40
- array(
41
- 'fetchpriority' => 'low',
42
- 'in_footer' => true,
43
- )
44
- );
45
- }
9
+ /**
10
+ * Register all script modules.
11
+ */
12
+ function {{PREFIX}}_register_script_modules() {
13
+ // Ensure this only runs once. wp_default_scripts can fire multiple times,
14
+ // and each wp_deregister_script_module() call also dequeues the module.
15
+ // If a module was enqueued between calls, repeated deregister/register
16
+ // cycles would lose the enqueue state.
17
+ static $already_registered = false;
18
+ if ( $already_registered ) {
19
+ return;
20
+ }
21
+ $already_registered = true;
22
+
23
+ // Load build constants
24
+ $build_constants = require __DIR__ . '/constants.php';
25
+ $modules_dir = __DIR__ . '/modules';
26
+ $modules_file = $modules_dir . '/registry.php';
27
+
28
+ if ( ! file_exists( $modules_file ) ) {
29
+ return;
46
30
  }
47
31
 
48
- add_action( 'wp_default_scripts', '{{PREFIX}}_register_script_modules' );
32
+ $modules = require $modules_file;
33
+ $base_url = $build_constants['build_url'] . 'modules/';
34
+ $extension = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '.js' : '.min.js';
35
+
36
+ foreach ( $modules as $module ) {
37
+ $asset_path = $modules_dir . '/' . $module['asset'];
38
+ $asset = file_exists( $asset_path ) ? require $asset_path : array();
39
+
40
+ // Deregister first to override any previously registered version
41
+ // (e.g., Core's default modules when running as a plugin).
42
+ wp_deregister_script_module( $module['id'] );
43
+
44
+ wp_register_script_module(
45
+ $module['id'],
46
+ $base_url . $module['path'] . $extension,
47
+ $asset['module_dependencies'] ?? array(),
48
+ $asset['version'] ?? false,
49
+ array(
50
+ 'fetchpriority' => 'low',
51
+ 'in_footer' => true,
52
+ )
53
+ );
54
+ }
49
55
  }
56
+
57
+ add_action( 'wp_default_scripts', '{{PREFIX}}_register_script_modules' );