Skip to content

Build: Add externals option to load packages from a script module - #85407

Open
tbradsha wants to merge 8 commits into
WordPress:trunkfrom
tbradsha:try/build/support_externals
Open

tbradsha wants to merge 8 commits into
WordPress:trunkfrom
tbradsha:try/build/support_externals

Conversation

@tbradsha

@tbradsha tbradsha commented Oct 22, 2026 •

Copy link
Copy Markdown

What?

Closes #85385 - Add @wordpress/build externals option to load packages from a script module

Why?

Before this PR, every package or route built with @wordpress/build bundles its own copy of each dependency that isn't a WordPress script, such as @wordpress/ui or @wordpress/dataviews. That means that if a plugin consumes multiple packages, it ends up with many copies of the same dependency bundled, which can significantly balloon the size of the final parent build.

This PR allows a plugin's bundles to import a package from a script module the plugin registers, instead of bundling their own copy or using the version that comes with Core.

How?

Adds a wpPlugin.externals option that maps a package to a script module ID. The createWordpressExternalsPlugin plugin then rewrites imports of that package to the ID and adds it to module_dependencies instead of bundling it.

Testing Instructions

In some directory, create the below files and then run npm build:before and npm build:after. You'll see a size difference.

Standing in the Gutenberg root dir, create sizes.mjs and run it with node sizes.mjs. Compare the files it created and confirm it's doing what we want.

sizes.mjs:

import { statSync } from 'fs';
import { build } from './packages/wp-build/node_modules/esbuild/lib/main.js';
import { createWordpressExternalsPlugin } from './packages/wp-build/lib/wordpress-externals-plugin.mjs';

const runs = {
	before: {},
	after: { '@wordpress/ui': { module: 'my-plugin/wp-ui' } },
};

for ( const [ label, externals ] of Object.entries( runs ) ) {
	await build( {
		// admin-ui depends on @wordpress/ui, so the import resolves from there.
		stdin: { contents: `import { Button } from '@wordpress/ui'; console.log( Button );`, resolveDir: 'packages/admin-ui' },
		bundle: true,
		minify: true,
		format: 'esm',
		outfile: `${ label }.js`,
		plugins: [ createWordpressExternalsPlugin( undefined, undefined, {}, undefined, externals )( label, 'esm' ) ],
	} );
	console.log( `${ label }:`, statSync( `${ label }.js` ).size, 'bytes' );
}

Testing Instructions for Keyboard

Screenshots or screencast

Use of AI Tools

The proposed changes were reviewed locally by Claude.

@github-actions github-actions Bot added the [Package] wp-build /packages/wp-build label Oct 22, 2026
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

Preview in WordPress Playground

🎉 Props

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: tbradsha <bradshawtm@git.wordpress.org>
Co-authored-by: youknowriad <youknowriad@git.wordpress.org>

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

Updated as activity occurs, without notifying anyone named here. Add the props-bot label to refresh.

🏷️ Labels

This pull request needs exactly one label indicating its type, and has 0.

  • Required: any label starting with [Type].
  • Found: none.

Read more about Type labels in Gutenberg. If you cannot add labels yourself, a reviewer can do it for you.

@tbradsha
tbradsha marked this pull request as ready for review October 22, 2026 19:23
@simison
simison requested a review from youknowriad October 22, 2026 19:26
@youknowriad

Copy link
Copy Markdown
Contributor

The packages mentioned on the PR are meant to be bundled, it's a choice of the components team. This feels like it goes against that decision, so I'm not really sure we should do this.

This branch has not been deployed

No deployments
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.

@wordpress/build: support externalization of packages to a custom handle

2 participants