Widget Primitives: Ship as a script module; register field types at page init#80149
Widget Primitives: Ship as a script module; register field types at page init#80149retrofox wants to merge 3 commits into
Conversation
|
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. |
1ca4874 to
d1ed2ae
Compare
widget-primitives becomes a shared script module
d1ed2ae to
1b478fe
Compare
|
Size Change: +55.9 kB (+0.73%) Total Size: 7.76 MB 📦 View Changed
|
|
Flaky tests detected in 1b478fe. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/29211442980
|
Depends on #80148 (branch based on
update/field-type-registry; only the last two commits belong to this PR).What
Exposes
@wordpress/widget-primitivesas a WordPress script module (wpScriptModuleExports) and moves the dashboard's field type registration from the stage route intopackages/dashboard-init, together with thecore/locationcontrol it registers.Why
The field type registry introduced in #80148 is module-scope state (a
Map), and bundled packages produce one copy per consumer bundle. A registry inside a per-bundle copy is a dead registry for every other bundle: registering from the page init module while the route resolves against its own copy would silently no-op, since unresolved names degrade without warning by design.Shipping the package as a script module makes the import map resolve one shared, singly-evaluated instance for every consumer. That is what allows the vocabulary to move where it belongs: the page's init module, which already registers the widget-modules discovery entity, runs in both boot modes before anything renders, and covers every route of the page rather than one of them.
Deduplication is the same property seen from the build side: each consumer stops bundling its own copy of the package, and package updates no longer invalidate consumer bundles. With two consumers today (the route bundle and the init module) the byte savings are modest; they compound with every host, route, or page that joins.
Worth noting for review: registering the module does not load it on unrelated admin pages. Static module dependencies are fetched only where the graph imports them, preloaded in parallel and evaluated in dependency order, which is exactly the ordering guarantee registration-before-render relies on. npm consumers are unaffected: the field only adds the WordPress module build; bundling consumers keep bundling.
What this enables next
Not a motivation for this PR, but a direct consequence: with
@wordpress/widget-primitivesin the import map, independently built widget modules can importregisterFieldTypeand reach the same shared registry. That is the mechanical prerequisite for third-party widgets registering their own field types, tracked as a follow-up in #80148 (the remaining work there is API and policy, not infrastructure).How
packages/widget-primitives/package.json: addwpScriptModuleExports, so wp-build emitsbuild/modules/widget-primitives/and consumers externalize the package to the import map instead of bundling it.packages/dashboard-init:init()callsregisterDashboardFieldTypes()before registering the discovery entity; the field type vocabulary (src/field-types/) and thecore/locationcontrol (LocationControl,LocationPicker) move here fromroutes/dashboard/.routes/dashboard:stage.tsxdrops the module-scope registration;@wordpress/dataviews,@wordpress/icons, and@wordpress/uimove from the route's dependencies todashboard-init's.packages/dashboard-init/tsconfig.json: new, with references for every@wordpressdependency, wired into the roottsconfig.json.Testing
npm run build(ornpm start) and open the dashboard with thegutenberg-dashboard-widgetsexperiment enabled.build/modules/widget-primitives/exists and is registered (build/modules.php).build/routes/dashboard/content.min.asset.php) lists@wordpress/widget-primitivesas a static module dependency instead of bundling it, and that the dashboard-init module asset does too.Follow-ups
@wordpress/dataviews, where deduplication is the primary motivation (it ships today inside the route bundle and inside every widget that renders with DataViews).