close
Skip to content

Widget Primitives: Ship as a script module - #80149

Merged
retrofox merged 2 commits into
trunkfrom
update/widget-primitives-script-module
Jul 17, 2026
Merged

Widget Primitives: Ship as a script module#80149
retrofox merged 2 commits into
trunkfrom
update/widget-primitives-script-module

Conversation

@retrofox

@retrofox retrofox commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

What

Ships @wordpress/widget-primitives as a WordPress script module (wpScriptModuleExports).

Why

The package holds module-scope state: the field type registry is a Map in the module. Bundled, the package produces one copy per consumer bundle, so state registered against one copy is invisible to every other, and the package is duplicated across consumers.

As a script module it resolves one shared, singly-evaluated instance from the import map. Consumers externalize the package instead of bundling their own copy. The dedup and the single-instance guarantee compound as more consumers appear (route bundles, and independently built widget render modules).

How

  • packages/widget-primitives/package.json: add wpScriptModuleExports, so wp-build emits build/modules/widget-primitives/ and consumers externalize the package to the import map instead of bundling it.

Testing

  1. Build (npm run build) and confirm build/modules/widget-primitives/ exists and is registered in build/modules.php.
  2. Confirm a module consumer (e.g. the dashboard route asset, build/routes/dashboard/content.min.asset.php) lists @wordpress/widget-primitives as a module dependency instead of bundling it.

Follow-ups

  • Move the dashboard's field type registration into the page init module without inflating it. The location control it registers pulls in the @wordpress/ui autocomplete stack, which isn't a script module yet, so it inlines into the init module (on the critical path). Fix by externalizing @wordpress/ui as a shared module, or by loading the control as a separate script module (the @wordpress/latex-to-mathml pattern). Tracked in #TBD.

@retrofox retrofox self-assigned this Jul 12, 2026
@github-actions

github-actions Bot commented Jul 12, 2026

Copy link
Copy Markdown

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: retrofox <retrofox@git.wordpress.org>
Co-authored-by: chihsuan <chihsuan@git.wordpress.org>

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

@retrofox
retrofox force-pushed the update/widget-primitives-script-module branch 2 times, most recently from d1ed2ae to 1b478fe Compare July 12, 2026 22:23
@github-actions

github-actions Bot commented Jul 12, 2026

Copy link
Copy Markdown

Size Change: +1.15 kB (+0.01%)

Total Size: 7.73 MB

📦 View Changed
Filename Size Change
build/modules/widget-primitives/index.min.js 1.15 kB +1.15 kB (new file) 🆕

compressed-size-action

@github-actions

github-actions Bot commented Jul 12, 2026

Copy link
Copy Markdown

Flaky tests detected in 3b51525.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/29519291761
📝 Reported issues:

Base automatically changed from update/field-type-registry to trunk July 14, 2026 07:18
@retrofox
retrofox requested a review from desrosj as a code owner July 15, 2026 10:18
@github-actions

Copy link
Copy Markdown

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: .

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.

@retrofox
retrofox force-pushed the update/widget-primitives-script-module branch from 55c0ec2 to ee6d599 Compare July 15, 2026 10:33
@retrofox
retrofox requested review from chihsuan and simison July 15, 2026 10:57
@retrofox
retrofox force-pushed the update/widget-primitives-script-module branch from 3de2eed to 6918da0 Compare July 15, 2026 11:57

@chihsuan chihsuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @retrofox shipping @wordpress/widget-primitives as a script module makes sense to me!

I just have one concern:

build/modules/dashboard-init/index.min.js 81.6 kB +81 kB (+13641.92%) 🆘

The compressed-size report shows the init module growing by roughly 81 kB, and it must finish loading before the dashboard can render.

The dashboard route also continues to use much of the same UI stack through widget-dashboard, so some of that code is duplicated.

Would it be possible to consider one of these alternatives?

  1. Keeping registration in the route. This is simpler and avoids the extra init bundle, but registration remains route-specific and tied to module evaluation.
  2. Keeping registration in init while lazy-loading LocationControl. This preserves centralized ownership but adds loading complexity and may not remove all duplication.

Both have tradeoffs, so I’d also be interested in any other approach you have. 🙂

One small documentation follow-up: docs/explanations/architecture/dashboard-widgets.md still says the dashboard route registers its field types, so that description should be updated if the current approach remains.

ship the package as a shared WordPress script module
@retrofox retrofox changed the title Widget Primitives: Ship as a script module; register field types at page init Widget Primitives: Ship as a script module Jul 16, 2026
@retrofox
retrofox force-pushed the update/widget-primitives-script-module branch from 6918da0 to 3b51525 Compare July 16, 2026 17:19
@retrofox

Copy link
Copy Markdown
Contributor Author

Thanks, @chihsuan. You were right to flag the init module.

I first went down the lazy-loading path, but the weight comes from @wordpress/ui, and since it isn't a script module yet, it inlines into whatever bundle imports the control.

The init module stayed heavy either way. Moving registration into init only pays off if that code can be deferred, and right now it can't.

So I go back to registration, staying on the route where the UI stack is already bundled, so there's no extra init module. This PR is now just the wpScriptModuleExports change for @wordpress/widget-primitives.

The good thing is that since registration is back in the route, the dashboard-widgets.md note is accurate again 😅

@chihsuan chihsuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for digging into it! @retrofox Totally agree on staying on the route for now. LGTM 👍

@retrofox
retrofox merged commit e7690ec into trunk Jul 17, 2026
60 checks passed
@retrofox
retrofox deleted the update/widget-primitives-script-module branch July 17, 2026 07:01
@github-actions github-actions Bot added this to the Gutenberg 23.7 milestone Jul 17, 2026
shail-mehta pushed a commit that referenced this pull request Jul 17, 2026
* add wpScriptModuleExports to widget-primitives

ship the package as a shared WordPress script module

* simplify CHANGELOG entry
@jonathanbossenger jonathanbossenger added [Type] Enhancement A suggestion for improvement. [Package] Widget primitives /packages/widget-primitives labels Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Widget primitives /packages/widget-primitives [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants