wp-build: Stop bundling Core packages, generate prerequisites asset instead#75987
Conversation
packages/wp-build/lib/build.mjs
Outdated
| * WordPress's script dependency system handles transitive dependencies | ||
| * automatically, so we only need to capture direct dependencies. | ||
| */ | ||
| async function generatePagePrerequisitesAsset() { |
There was a problem hiding this comment.
AFAIK, We don't need this at all, the "boot" package is going to be registered by Core and Gutenberg as a regular module it will be available already.
There was a problem hiding this comment.
Boot will be available as a module, yes, but when on Core < 7.0 and Gutenberg disabled, the page template still needs to enqueue boot's classic script dependencies. Without this, pages using wp-build in these conditions will still fail to load.
There was a problem hiding this comment.
I thought the whole idea of this PR is to remove support for Core < 7.0, no?
There was a problem hiding this comment.
The idea is to remove the bundled modules while making it possible to polyfill them temporarily. Without this, the polyfill won't work.
There was a problem hiding this comment.
It's still a bit unclear to me, why can't the polyfill, provide these packages by building them from npm and using the generated asset file that the polyfill provides, why do we need to keep this code here?
There was a problem hiding this comment.
In my mind, the polyfill would do that basically, It would build the "boot" package using through the regular pipeline which would also result in the asset file generated properly. What's the purpose of the polyfill otherwise?
There was a problem hiding this comment.
In my mind, the polyfill would do that basically, It would build the "boot" package using through the regular pipeline which would also result in the asset file generated properly.
I updated the code to remove the generatePagePrerequisitesAsset function. The issue is that for plugins using wp-build before 7.0, we need to run bundlePackage('boot', ...) and then discard everything except for the asset file here then. We can't completely remove this.
What's the purpose of the polyfill otherwise?
To bundle the modules. Those are two distinct issues, the problem here is enqueing the classic scripts that the modules need, bundled or not.
There was a problem hiding this comment.
The issue is that for plugins using wp-build before 7.0, we need to run bundlePackage('boot', ...) and then discard everything except for the asset file here then. We can't completely remove this.
Building regular packages using wp-build already builds the output of the script modules and also generates the assets file. So what I'm suggesting personally is to build the "@wordpress/boot" package in the polyfill and generating the assets file there as well and just do nothing here. I don't really know how straightforward is this. Maybe it means doing export * from '@wordpress/build' or something like that in a custom boot package or maybe it means a custom build script or trying to reproduce the "gutenberg" folder structure in a temporary folder in the build script... But I don't think building half of the things here (assets) and the other half (the code) in the polyfill is a good approach, it results in quick inconsistency.
I don't believe these are distinct issues, when you build a module/script/package you need to extract its dependencies and that's what the asset file is about.
There was a problem hiding this comment.
The problem, and the reason I kept trying to keep the asset file definition here, is that the asset file location is hardcoded on the template files, so they end up in the build directory, that can't be edited reliably, nor copied to in runtime.
This makes it necessary to run a post-build script to copy the asset file to the expected folder, which IMO is a hacky solution.
That said, I removed the entire asset enqueing and module bundling logic, as requested.
There was a problem hiding this comment.
the reason I kept trying to keep the asset file definition here, is that the asset file location is hardcoded on the template files, so they end up in the build directory, that can't be edited reliably, nor copied to in runtime.
This is a good point, if you think it helps we can potentially make the "boot package" or the "boot package assets" a config or something if it helps.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
589d181 to
76ee64e
Compare
76ee64e to
d16c311
Compare
49c3e05 to
b6cc9cc
Compare
…nstead wp-build previously bundled boot, route, theme, and private-apis from node_modules and registered them as WordPress scripts/modules. This caused the plugin to overwrite Core's or Gutenberg's versions at runtime, which is particularly dangerous for private-apis (Symbol/WeakMap mismatch causes silent failures). Replace the bundling block with a new generatePagePrerequisitesAsset() function that statically analyzes @wordpress/boot's package.json to produce a build/page-prerequisites.asset.php file listing the classic script handles WordPress needs to load. The 4 packages are now treated as external dependencies provided by Core (WP 7.0+) or Gutenberg. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of statically analyzing boot's package.json to generate a separate page-prerequisites.asset.php, use the asset file that esbuild naturally produces when building boot as a module. For Gutenberg, boot is already built in Phase 2. For external plugins, build boot from node_modules solely for the asset file, then clean up the unused JS output. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
b6cc9cc to
21e9e9f
Compare
youknowriad
left a comment
There was a problem hiding this comment.
👍
Let's add a breaking change changelog entry to ensure folks know that 7.0 is now a requirement for this.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
For anyone affected by this change in wp-build, I have a sample polyfill here. |
What?
Follow-up to #75650
wp-buildwas bundlingboot,route,theme, andprivate-apisfromnode_modulesand registering them as WordPress scripts/modules. This caused the plugin to overwrite Core's or Gutenberg's versions at runtime.This PR replaces the bundling approach with a static analysis step that generates a
page-prerequisites.asset.phpfile listing the classic script handles WordPress needs to load.Why?
As identified in this comment, the root cause of the
private-apisversion mismatch issue (see #75440) is thatwp-buildwas bundling its own copies of Core packages instead of externalizing them. This is particularly dangerous forprivate-apis, where a Symbol/WeakMap mismatch causes silent failures and page crashes.Plugins using
wp-buildwith pages should rely on Core (WP 7.0+) or Gutenberg to provide these packages, rather than shipping their own copies.How?
bundlePackage()calls forboot,route,theme, andprivate-apisin the page build flow.generatePagePrerequisitesAsset()function that reads@wordpress/boot'spackage.jsondependencies and produces abuild/page-prerequisites.asset.phpfile with the corresponding WordPress script handles.vendorExternalsmap to module scope inwordpress-externals-plugin.mjsso it can be shared with the prerequisites generator.page-prerequisites.asset.phppath instead of the oldmodules/boot/index.min.asset.php.Testing Instructions
Without polyfills:
pnpm installbuildfolder if it is therewp-buildto the test repo:rm -rf node_modules/@wordpress/build && ln -s <gutenberg path>/packages/wp-build node_modules/@wordpress/buildpnpm run buildbuild/page-prerequisites.asset.phpexists and contains the expected script handlesbuild/modules/boot/,build/scripts/private-apis/,build/scripts/theme/are not generatedWith a polyfill:
test/wp-build-polyfillbranchpnpm installbuildfolder if it is therewp-buildto the test repo:rm -rf node_modules/@wordpress/build && ln -s <gutenberg path>/packages/wp-build node_modules/@wordpress/buildpnpm run buildbuild/page-prerequisites.asset.phpexists and contains the expected script handlesbuild/modules/boot/,build/scripts/private-apis/,build/scripts/theme/are not generatedTesting Instructions for Keyboard
N/A — no UI changes.
Screenshots or screencast
N/A — build tooling change only.