Build Tools: Scope wp-build's deregister-before-register to @wordpress/* modules#77465
Build Tools: Scope wp-build's deregister-before-register to @wordpress/* modules#77465retrofox wants to merge 1 commit into
Conversation
The deregister-before-register pattern in wp-build templates was introduced in #75909 so that Gutenberg-as-plugin can override Core's bundled @wordpress/* module versions. Core's wp_register_script_module() is idempotent (first-wins) with no override API, so deregister-then- register is the only path. Applied universally, the pattern creates silent last-plugin-wins collisions for any non-@wordpress/* module shared across plugins (plugin-local IDs, vendor packages) — with no upside, since these entries are never overriding Core defaults. Scope the pattern to @wordpress/* IDs — the only namespace Core registers by default. Plugin-local and shared-package IDs now rely on Core's idempotent first-wins semantics, matching the behavior the Script Modules API was designed for.
|
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. |
|
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.
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. |
What?
Scopes wp-build's deregister-before-register pattern to IDs in the
@wordpress/*namespace, leaving every other module ID to rely on Core's idempotentwp_register_script_module()first-wins semantics.Affects the two generated PHP templates:
packages/wp-build/templates/module-registration.php.templatepackages/wp-build/templates/routes-registration.php.templateWhy?
The deregister-before-register pattern was introduced in #75909 for a specific scenario: Gutenberg-as-plugin needs to override Core's bundled
@wordpress/*module versions, andWP_Script_Modules::register()is idempotent with no override API. Deregister-then-register is the only Core-sanctioned path.The fix worked, but was applied universally to every generated registration — including plugin-local modules and shared/vendor packages that were never overriding anything Core registers. For those IDs, the pattern creates silent last-plugin-wins collisions across plugins using wp-build, and each deregister also dequeues the module (see #76170, which added a static guard to work around that).
How?
Wrap each
wp_deregister_script_module()call in astr_starts_with( \$id, '@wordpress/' )check.@wordpress/*is the only namespace Core registers by default (seewp-includes/assets/script-modules-packages.php), so the Gutenberg-as-plugin override scenario is preserved. All other IDs fall through to Core's idempotent first-wins semantics.str_starts_withis safe here — WordPress Core polyfills it since 5.9 and Gutenberg already uses it unconditionally inlib/client-assets.php.Testing
build/modules.phpand route registration contain the conditional.@wordpress/*ID → first-plugin-wins, no cross-plugin dequeue. Load Gutenberg-as-plugin →@wordpress/*overrides still take precedence over Core.Follow-ups
packageSourcesbenefits from this fix (cross-plugin shared packages no longer collide silently).