Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
ee05251
add version number graphic to welcome banner
retrofox May 24, 2026
682417f
Merge branch 'update/add-welcome-widget-banner-bg' into trunk
retrofox May 25, 2026
b5d6eb9
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 25, 2026
3a3ff5f
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 25, 2026
a897825
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 25, 2026
f2917e0
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 25, 2026
4625fb1
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 25, 2026
c683724
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 25, 2026
853b9c8
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 25, 2026
0780c53
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 25, 2026
75810ab
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 26, 2026
9d8276a
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 26, 2026
b19ab13
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 26, 2026
1a142a3
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 26, 2026
59b8492
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 26, 2026
393837e
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 27, 2026
9c43e72
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 27, 2026
461a10d
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 27, 2026
e0fb835
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 28, 2026
b0b47e5
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 28, 2026
9eed995
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 28, 2026
84e31b1
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 28, 2026
28819df
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 28, 2026
5d29de8
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 28, 2026
c8260b6
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 29, 2026
ffa81fb
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox May 29, 2026
df47aeb
Build Tools: Use package.json name as the script-module ID
retrofox May 29, 2026
265c239
Build Tools: Discover script-module packages outside ./packages/ via …
retrofox May 29, 2026
25513d0
fix linting issue
retrofox May 29, 2026
3300f36
fix dual packages externalization in IIFE builds
retrofox May 29, 2026
6431dc5
use a single onResolve for internal package names
retrofox May 29, 2026
aca0b62
skip wpScript for convention-discovered packages
retrofox May 29, 2026
f99540e
update jsdoc for internalPackageNames
retrofox May 29, 2026
51c1663
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 1, 2026
82bd130
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 1, 2026
cdf4af3
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 2, 2026
a5afaf0
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 3, 2026
43e6540
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 3, 2026
32606e6
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 3, 2026
225a365
Merge branch 'trunk' into refactor/wp-build-name-as-module-id
retrofox Jun 3, 2026
64caef9
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 3, 2026
6087db1
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 3, 2026
66c67b0
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 4, 2026
25af734
Build Tools: Drop convention discovery
retrofox Jun 4, 2026
a9e9dca
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 5, 2026
da70022
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 6, 2026
d36316e
Merge branch 'trunk' of github.com:WordPress/gutenberg into trunk
retrofox Jun 6, 2026
371a7e3
Merge branch 'trunk' into refactor/wp-build-name-as-module-id
retrofox Jun 7, 2026
8a40c80
tweak jsdoc block
retrofox Jun 7, 2026
ddc46b0
Merge branch 'trunk' into refactor/wp-build-name-as-module-id
retrofox Jun 7, 2026
f7a4d7c
Merge remote-tracking branch 'origin/trunk' into refactor/wp-build-na…
Copilot Jun 12, 2026
02de0fc
Merge branch 'trunk' into refactor/wp-build-name-as-module-id
retrofox Jun 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/wp-build/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Enhancements

- Use each package's own `name` field as its script-module ID, and externalize internal-package imports by exact name. Decouples script-module identity from `wpPlugin.packageNamespace`, so the npm name survives end-to-end (npm name === import specifier === script-module ID). No-op for Core; lets consumers whose owned npm scope differs from `packageNamespace` keep a single identifier across npm, IDE, and the WordPress runtime.

## 0.16.0 (2026-06-10)

### Bug Fixes
Expand Down
28 changes: 24 additions & 4 deletions packages/wp-build/lib/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,19 @@ function getAllPackages() {
}

const PACKAGES = getAllPackages();

// The `name` field of every internal package, used by the externals
// plugin to externalize internal-package imports by exact name regardless
// of `packageNamespace`. Keeps script-module identity tied to a package's
// own `name` (npm name === import specifier === script-module ID).
const INTERNAL_PACKAGE_NAMES = new Set(
PACKAGES.map(
( packageName ) =>
getPackageInfoFromFile(
path.join( PACKAGES_DIR, packageName, 'package.json' )
).name
).filter( Boolean )
);
const ROOT_PACKAGE_JSON = getPackageInfoFromFile(
path.join( ROOT_DIR, 'package.json' )
);
Expand Down Expand Up @@ -155,7 +168,8 @@ const wordpressExternalsPlugin = createWordpressExternalsPlugin(
PACKAGE_NAMESPACE,
SCRIPT_GLOBAL,
EXTERNAL_NAMESPACES,
HANDLE_PREFIX
HANDLE_PREFIX,
INTERNAL_PACKAGE_NAMES
);

const styleRuntimeRequire = createNodeRequire( import.meta.url );
Expand Down Expand Up @@ -696,10 +710,16 @@ async function bundlePackage( packageName, options = {} ) {
);
}

// The script-module ID is the package's own `name` field, so the
// npm name survives end-to-end (npm name === import specifier ===
// script-module ID). The PHP registry, the asset manifest, and
// `wp_register_script_module` all treat the ID as an opaque string.
// Falls back to the legacy `@<packageNamespace>/<dirName>` shape only
// when `name` is missing (e.g. an unnamed local package).
const packageId =
packageJson.name || `@${ packageNamespace }/${ packageName }`;
const scriptModuleId =
exportName === '.'
? `@${ packageNamespace }/${ packageName }`
: `@${ packageNamespace }/${ packageName }/${ fileName }`;
exportName === '.' ? packageId : `${ packageId }/${ fileName }`;

builtModules.push( {
id: scriptModuleId,
Expand Down
90 changes: 85 additions & 5 deletions packages/wp-build/lib/wordpress-externals-plugin.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,19 @@ async function generateContentHash(
* This plugin handles WordPress package externals and vendor libraries,
* treating them as external dependencies available via global variables.
*
* @param {string} packageNamespace Custom package namespace (e.g., 'wordpress', 'my-plugin').
* @param {string|false} scriptGlobal Global variable name (e.g., 'wp', 'myPlugin') or false to disable globals.
* @param {Object} externalNamespaces Additional namespaces to externalize (e.g., { 'woo': { global: 'woo', handlePrefix: 'woocommerce' } }).
* @param {string} handlePrefix Handle prefix for main package (e.g., 'wp', 'mp'). Defaults to packageNamespace.
* @param {string} packageNamespace Custom package namespace (e.g., 'wordpress', 'my-plugin').
* @param {string|false} scriptGlobal Global variable name (e.g., 'wp', 'myPlugin') or false to disable globals.
* @param {Object} externalNamespaces Additional namespaces to externalize (e.g., { 'woo': { global: 'woo', handlePrefix: 'woocommerce' } }).
* @param {string} handlePrefix Handle prefix for main package (e.g., 'wp', 'mp'). Defaults to packageNamespace.
* @param {Set<string>} [internalPackageNames] `name` fields of every internal package. Imports matching any of these are externalized by exact name, regardless of `packageNamespace`.
* @return {Function} Function that creates the esbuild plugin instance.
*/
export function createWordpressExternalsPlugin(
packageNamespace,
scriptGlobal,
externalNamespaces = {},
handlePrefix
handlePrefix,
internalPackageNames = new Set()
) {
/**
* WordPress externals plugin for esbuild.
Expand Down Expand Up @@ -199,6 +201,84 @@ export function createWordpressExternalsPlugin(
);
}

// Externalize imports of internal packages by their exact `name`. They are
// matched by name rather than by scope, since a package's scope may also hold
// unrelated third-party packages that scope matching would externalize too.
if ( internalPackageNames.size > 0 ) {
// Longest-first: avoids `@org/block` shadowing `@org/block-editor`.
const namesSorted = Array.from( internalPackageNames ).sort(
( a, b ) => b.length - a.length
);
const escapedNames = namesSorted.map( ( n ) =>
n.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' )
);
const internalNamesFilter = new RegExp(
`^(?:${ escapedNames.join( '|' ) })(?:/|$)`
);

build.onResolve(
{ filter: internalNamesFilter },
/** @param {import('esbuild').OnResolveArgs} args */
( args ) => {
const head = args.path.startsWith( '@' )
? args.path.split( '/', 2 ).join( '/' )
: args.path.split( '/', 1 )[ 0 ];

if ( ! internalPackageNames.has( head ) ) {
return undefined;
}

const subpath =
args.path.length > head.length
? args.path.slice( head.length + 1 )
: null;

const packageJson = getPackageInfo(
head,
args.resolveDir
);

if ( ! packageJson ) {
return undefined;
}

const isScriptModule = isScriptModuleImport(
packageJson,
subpath
);
const isScript = !! packageJson.wpScript;

// Dual packages: IIFE yields to the namespace handler.
let externalize = isScriptModule;
if ( isScriptModule && isScript ) {
externalize = buildFormat === 'esm';
}
if ( ! externalize ) {
return undefined;
}

const kind =
args.kind === 'dynamic-import'
? 'dynamic'
: 'static';

if ( kind === 'static' ) {
moduleDependencies.set( args.path, 'static' );
} else if (
! moduleDependencies.has( args.path )
) {
moduleDependencies.set( args.path, 'dynamic' );
}

return {
path: args.path,
external: true,
sideEffects: !! packageJson.sideEffects,
};
}
);
}

// Handle package namespace externals (wordpress and custom)
for ( const externalConfig of packageExternals ) {
build.onResolve(
Expand Down
Loading