Skip to content

wp-build: Add configurable script registration priority#75650

Closed
dhasilva wants to merge 1 commit intoWordPress:trunkfrom
dhasilva:fix/wp-build-script-priority
Closed

wp-build: Add configurable script registration priority#75650
dhasilva wants to merge 1 commit intoWordPress:trunkfrom
dhasilva:fix/wp-build-script-priority

Conversation

@dhasilva
Copy link
Copy Markdown
Contributor

@dhasilva dhasilva commented Feb 18, 2026

What?

Closes #75440

Expands on #75460 by adding a scriptRegistrationPriority parameter to wpPlugin.

Why?

See #75440
Without this, Gutenberg registers scripts with the same priority as the other plugins, which causes a mismatch of the private-apis versions, crashing the page of the plugin.

How?

The configurable scriptRegistrationPriority allows Gutenberg to raise its priority above other plugins while other plugins that use wp-build continue with a priority above core's. The default priority is 9, so other plugins do not need to change this value, only Gutenberg needs to raise it.

Testing Instructions

1 - Clone https://github.com/dhasilva/minimal-wp-build-test locally
2 - Uncomment these lines to avoid an unrelated problem
4 - pnpm install and build the test plugin with pnpm run build
5 - Go to Tools > Minimal WP-Build Test
6 - Check that you see the error in the linked issue
7 - Symlink wp-build to the plugin's dependencies:

cd <your-wp-plugins-folder>/minimal-wp-build-test
rm -rf node_modules/@wordpress/build
ln -s <your-gutenberg-folder>/packages/wp-build node_modules/@wordpress/build

8 - Rebuild the test plugin: pnpm run build
9 - Check /build/scripts.php, it should register scripts with priority 9: add_action( 'wp_default_scripts', 'minimal_wp_build_test_register_package_scripts', 9 );
10 - Rebuild Gutenberg
11 - Check Gutenbergs' /build/scripts.php, it should have priority 10
12 - Go to Tools > Minimal WP-Build Test again
13 - Check that the page loads

Testing Instructions for Keyboard

Screenshots or screencast

Before After
Screenshot from 2026-02-17 21-18-14 Screenshot from 2026-02-17 21-16-49

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 19, 2026

Warning: Type of PR label mismatch

To merge this PR, it requires exactly 1 label indicating the type of PR. Other labels are optional and not being checked here.

  • Required label: Any label starting with [Type].
  • Labels found: [Package] wp-build.

Read more about Type labels in Gutenberg. Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 19, 2026

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 props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: dhasilva <thehenridev@git.wordpress.org>
Co-authored-by: youknowriad <youknowriad@git.wordpress.org>
Co-authored-by: jsnajdr <jsnajdr@git.wordpress.org>
Co-authored-by: aduth <aduth@git.wordpress.org>
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: simison <simison@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@dhasilva
Copy link
Copy Markdown
Contributor Author

Using IS_GUTENBERG_PLUGIN would not work because it would be true for all plugins, but I wonder if there is a more elegant or standard way.

cc @youknowriad

@dhasilva dhasilva force-pushed the fix/wp-build-script-priority branch from dca321b to ab333e4 Compare February 19, 2026 17:09
@youknowriad
Copy link
Copy Markdown
Contributor

For me the solution in this PR is ok but I honestly don't know what's the exact impact here. Like what happens when core gets updated and the plugin is using older "private-apis" than the one used in core... I feel like there's some edge case that we might be missing.

@dhasilva dhasilva force-pushed the fix/wp-build-script-priority branch from ab333e4 to 8919c2c Compare February 19, 2026 19:30
@dhasilva
Copy link
Copy Markdown
Contributor Author

Like what happens when core gets updated and the plugin is using older "private-apis" than the one used in core

This is the case on trunk already. If Gutenberg is not installed, the plugin already overrides core with an older version of private-apis.
We are just adjusting the priorities so that the plugin does not override Gutenberg if both are installed and activated.

This seems like it needs a separate issue.

@youknowriad
Copy link
Copy Markdown
Contributor

the plugin already overrides core with an older version of private-apis.

But isn't that a problem, the plugin is going to break other functionality in this case no?

@dhasilva
Copy link
Copy Markdown
Contributor Author

But isn't that a problem, the plugin is going to break other functionality in this case no?

I think it will, yes. And the private api package is just the most visible problem, the other packages would cause problems as well. But it is hard to test this because core, as I understand, is way behind 🤔

The thing is, it is not related to this PR, it is a pre-existing problem, that is why I think the best approach here is to open a separate issue to find a general solution.

@youknowriad
Copy link
Copy Markdown
Contributor

For me it is related to this PR, but just another symptom of it. Personally, I'm starting to think that there's no solution here.

In other words, plugins replacing "boot" or "theme" or "private-apis" scripts or modules in Core is a no go. I only see two potential valid solutions:

1- Plugins building using "wp-build" should have a minimal core supported version of 7.0 (where build, theme packages are in Core)

2- Remove the use of "theme" package from "boot" package entirely for now (a bit unfortunate) and each page builds its own "boot" module (so it wouldn't be named "boot" in the output of wp-build) to avoid conflicting with the "boot" package registered by Core/Gutenberg. the latter is ok, but the former is unclear, because if you remove the "theme" package it means there's no clear way for these routes/pages to be "themed" properly according to the WP user profile, usage of @wordpress/ui components might not be safe 100%.

@dhasilva how acceptable is option 1 for you, it seems like the "only" safe solution for now :(

cc @aduth @jsnajdr I'd appreciate some help, I'm a bit stuck to be honest. (We want to allow third-parties to use wp-build to build pages without requiring latest WordPress and without conflicting within WP scripts and modules)

@jsnajdr
Copy link
Copy Markdown
Member

jsnajdr commented Feb 20, 2026

The root cause is somewhere else, and changing the script priority merely covers up the issue instead of solving it.

The build folder of the minimal-wp-build-test plugin contains several scripts and modules that it shouldn't contain:

  • build/modules/boot
  • build/scripts/private-apis
  • build/scripts/theme

These are Core modules and scripts and for some reason the wp-build script decided that it won't property externalize them as:

  • import '@wordpress/boot'
  • window.wp.privateApis
  • window.wp.theme

but instead it builds its own version from the packages installed in node_modules. That's the bug, and wp-build should be fixed.

Plugins building using "wp-build" should have a minimal core supported version of 7.0 (where build, theme packages are in Core)

Yes, this sounds like a very natural requirement. The minimal-wp-build-test plugin is clearly using new 7.0 APIs for route registration. Of course that works only on 7.0 and depends on presence of Core modules and scripts. Plugins can't really "bring their own Core modules", replacing wp.theme with their own version. That's an inevitable compat disaster.

@dhasilva
Copy link
Copy Markdown
Contributor Author

dhasilva commented Feb 20, 2026

how acceptable is option 1 for you

Honestly, I don't think it is at all.
We support the last 2 versions of WP, and 7.0 will be released in April. So until version 7.1 is out we will be in a situation where the plugin is broken for users in a supported version if we go ahead with using wp-build. 😞

@jsnajdr
Copy link
Copy Markdown
Member

jsnajdr commented Feb 23, 2026

The build folder of the minimal-wp-build-test plugin contains several scripts and modules that it shouldn't contain:

Now I understand that this is an intentional feature added in #73379. If a plugin ships any pages, wp-build will also add a polyfill for selected Core packages, namely route, boot, private-apis and theme.

This polyfilling always overrides the Core/Gutenberg scripts with the plugin version, but that's too naive. First of all, it should be the plugin's responsibility to register the polyfills with a high priority number, so that the registration runs late and can see what others (Core or Gutenberg) have already registered. It should check the already registered versions and override only if it has something newer.

One of the polyfills is the private-apis package. The reason for polyfilling is probably the CORE_MODULES_USING_PRIVATE_APIS array and nothing else. The plugin needs to make sure that it includes the route and boot packages, so that these packages can register (lock) and use (unlock) private APIs. But if the plugin ships an older version of the private-apis polyfill, then new Core/Gutenberg additions will be missing. In our example, the array doesn't include rich-text and that causes the crashes reported in #75440.

If the plugin registered private-apis polyfill only after checking that it really has a newer version, that would probably solve this bug.

By the way, this also shows a neat way how to circumvent all private-apis checks once and for all: override the Core script with your own version that lets anyone call __dangerousOptInToUnstableAPIsOnlyForCoreModules without any checks.

If Gutenberg started registering its scripts with a higher priority number (causing them to register later), it wouldn't really solve the #75440 bug, because it doesn't deal with scripts registered in Core. What I have WP 7.0 with private-apis that allows rich-text, but then my plugin registers an older version that doesn't allow rich-text. In this "no Gutenberg" scenario, the crash is still there.

@aduth
Copy link
Copy Markdown
Member

aduth commented Feb 23, 2026

I'm not sure how much it helps, but to the point of removing theme usage from boot, the work in #75589 is also working toward the goal of offering backwards-compatibility for versions of WordPress that don't yet have these dependencies. With the issue flagged at Trac#64698, I'm already thinking #75589 and removing reliance on theme tokens being loaded by @wordpress/boot is a short-term solution for WordPress 7.0. That doesn't help the user theme preference aspect, which is something I was hoping we could keep in @wordpress/boot.

To the @wordpress/private-apis issue, it's trickier, and the issue of bundling multiple copies keeps coming up.

One thought is: If we're talking about trying to fix this in the context of bundling and wp-build specifically, could we not make it so that the bundling itself effectively inlines/unfurls those internal private APIs? So not that we're inlining @wordpress/private-apis itself, but rather resolve the locking and unlocking so that private-apis doesn't exist in the built copies. A simpler equivalent would be something like #75352, which still internally uses private APIs without going through the actual @wordpress/private-apis aparatus. The downside of this approach is that I'm not sure we can or want to bundle an extra copy of the private APIs being used.

I also tried thinking about ways we could make private APIs work better across multiple "versions", like additively building up CORE_MODULES_USING_PRIVATE_APIS to avoid one version replacing another. But I think it's tricky to do without losing "privateness" that would prevent third-party consumers from also extending it. The most viable idea I had here is some sort of private/public key verification, where the list can be additively extended, but the list is expected to contain encrypted package names that must pass public key verification. But that entails headaches around how to manage and use the private key.

@dhasilva
Copy link
Copy Markdown
Contributor Author

dhasilva commented Mar 4, 2026

Closing in favor of #75987

@dhasilva dhasilva closed this Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] wp-build /packages/wp-build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WP Build: Page crashes with "Element type is invalid" error.

5 participants