diff --git a/.github/workflows/check-package-changelogs.yml b/.github/workflows/check-package-changelogs.yml index 6550af69fe1bcd..ef92bb05f15b28 100644 --- a/.github/workflows/check-package-changelogs.yml +++ b/.github/workflows/check-package-changelogs.yml @@ -49,14 +49,13 @@ jobs: - interface - style-runtime - ui - - undo-manager - views + - widget-dashboard + - widget-primitives # Other packages - theme - components - private-apis - - widget-dashboard - - widget-primitives - wp-build steps: - name: 'Get PR commit count' diff --git a/packages/admin-ui/CHANGELOG.md b/packages/admin-ui/CHANGELOG.md index 78f9102e09a3d4..3571b3b9cb7cd6 100644 --- a/packages/admin-ui/CHANGELOG.md +++ b/packages/admin-ui/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Internal + +- Declare `wpScript: false` to mark the package as bundled rather than externalized. ([#79945](https://github.com/WordPress/gutenberg/pull/79945)) + ## 2.5.0 (2026-07-01) ## 2.4.0 (2026-06-24) diff --git a/packages/admin-ui/package.json b/packages/admin-ui/package.json index 8a1423a12cf9ac..fd02b97fffaaa3 100644 --- a/packages/admin-ui/package.json +++ b/packages/admin-ui/package.json @@ -39,6 +39,7 @@ }, "./package.json": "./package.json" }, + "wpScript": false, "types": "build-types", "sideEffects": [ "src/**/*.module.css" diff --git a/packages/dataviews/CHANGELOG.md b/packages/dataviews/CHANGELOG.md index ef6d8fc6c9f09e..a8ea917b4ede2f 100644 --- a/packages/dataviews/CHANGELOG.md +++ b/packages/dataviews/CHANGELOG.md @@ -8,6 +8,7 @@ ### Internal +- Declare `wpScript: false` to mark the package as bundled rather than externalized. ([#79945](https://github.com/WordPress/gutenberg/pull/79945)) - Update `@ariakit/react` to `0.4.32` ([#79860](https://github.com/WordPress/gutenberg/pull/79860)). ## 17.1.0 (2026-07-01) diff --git a/packages/dataviews/package.json b/packages/dataviews/package.json index 979568d6fde72e..46eb978465dcd2 100644 --- a/packages/dataviews/package.json +++ b/packages/dataviews/package.json @@ -48,6 +48,7 @@ }, "./build-style/": "./build-style/" }, + "wpScript": false, "types": "build-types", "sideEffects": false, "dependencies": { diff --git a/packages/dependency-extraction-webpack-plugin/CHANGELOG.md b/packages/dependency-extraction-webpack-plugin/CHANGELOG.md index fc4476f9b6810e..db6387dab8810f 100644 --- a/packages/dependency-extraction-webpack-plugin/CHANGELOG.md +++ b/packages/dependency-extraction-webpack-plugin/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancements + +- Determine bundled packages from `wpScript: false` in `package.json` instead of a hardcoded list. ([#79945](https://github.com/WordPress/gutenberg/pull/79945)) + ### Bug Fixes - Extract dynamically imported external modules that webpack code-splits into their own async chunk in the module build ([#79633](https://github.com/WordPress/gutenberg/pull/79633)). diff --git a/packages/dependency-extraction-webpack-plugin/lib/util.js b/packages/dependency-extraction-webpack-plugin/lib/util.js index 71a1002af83a9e..a3988296408672 100644 --- a/packages/dependency-extraction-webpack-plugin/lib/util.js +++ b/packages/dependency-extraction-webpack-plugin/lib/util.js @@ -1,17 +1,137 @@ const WORDPRESS_NAMESPACE = '@wordpress/'; -const BUNDLED_PACKAGES = [ - '@wordpress/admin-ui', - '@wordpress/dataviews', - '@wordpress/dataviews/wp', - '@wordpress/fields', - '@wordpress/grid', - '@wordpress/icons', - '@wordpress/interface', - '@wordpress/style-runtime', - '@wordpress/ui', - '@wordpress/undo-manager', - '@wordpress/views', -]; +const { readFileSync, existsSync } = require( 'fs' ); +const path = require( 'path' ); +const { createRequire } = require( 'module' ); + +const packageJsonCache = new Map(); +const packagePathCache = new Map(); + +/** + * Find the nearest package root directory by walking up from the given directory. + * Looks for a directory containing package.json. + * + * @param {string} startDir The directory to start searching from. + * @return {string} The package root directory, or the start directory if no package.json found. + */ +function findPackageRoot( startDir ) { + let current = startDir; + const root = path.parse( current ).root; + + while ( current !== root ) { + const packageJsonPath = path.join( current, 'package.json' ); + if ( existsSync( packageJsonPath ) ) { + return current; + } + current = path.dirname( current ); + } + + // Fallback to the start directory if no package.json found. + return startDir; +} + +/** + * Reads package.json info using Node's module resolution. + * + * @param {string} fullPackageName The full package name (e.g. '@wordpress/blocks'). + * @param {string|null} resolveDir Optional directory context for resolution. + * @return {{wpScript?: boolean, wpScriptModuleExports?: string|Object}|null} Package metadata when resolvable. + */ +function getPackageInfo( fullPackageName, resolveDir = null ) { + const packageRoot = resolveDir + ? findPackageRoot( resolveDir ) + : process.cwd(); + const cacheKey = `${ fullPackageName }@${ packageRoot }`; + + if ( packageJsonCache.has( cacheKey ) ) { + return packageJsonCache.get( cacheKey ); + } + + const contextPath = path.join( packageRoot, 'package.json' ); + const contextRequire = createRequire( contextPath ); + + let resolved; + try { + resolved = contextRequire.resolve( + `${ fullPackageName }/package.json` + ); + } catch ( error ) { + const code = error.code; + if ( + code === 'MODULE_NOT_FOUND' || + code === 'ERR_PACKAGE_PATH_NOT_EXPORTED' + ) { + packageJsonCache.set( cacheKey, null ); + return null; + } + throw error; + } + + const result = getPackageInfoFromFile( resolved ); + packageJsonCache.set( cacheKey, result ); + + return result; +} + +/** + * Reads package.json info from an explicit file path. + * + * @param {string} packageJsonPath Absolute path to package.json file. + * @return {{wpScript?: boolean, wpScriptModuleExports?: string|Object}|null} Package metadata when resolvable. + */ +function getPackageInfoFromFile( packageJsonPath ) { + if ( packagePathCache.has( packageJsonPath ) ) { + return packagePathCache.get( packageJsonPath ); + } + const packageJson = JSON.parse( readFileSync( packageJsonPath, 'utf8' ) ); + packagePathCache.set( packageJsonPath, packageJson ); + return packageJson; +} + +/** + * Read package metadata for an import request. + * + * @param {string} request Module request (the module name in `import from`). + * @return {{wpScript?: boolean, wpScriptModuleExports?: string|Object}|undefined} Package metadata when resolvable. + */ +function getPackageMetadata( request ) { + const packageName = getPackageNameFromRequest( request ); + + if ( ! packageName ) { + return; + } + + return getPackageInfo( packageName ); +} + +/** + * Determine whether a package should stay bundled in script builds. + * Packages are bundled only when they explicitly opt out of script registration + * via `wpScript: false`. + * + * @param {string} request Module request (the module name in `import from`). + * @return {boolean} True when package should remain bundled in scripts. + */ +function isBundledPackageForScripts( request ) { + const packageMetadata = getPackageMetadata( request ); + if ( ! packageMetadata ) { + return false; + } + + return packageMetadata.wpScript !== true; +} + +/** + * Extract package name (`@scope/name`) from an import request. + * + * @param {string} request Module request (the module name in `import from`). + * @return {string|undefined} Package name when request is namespaced. + */ +function getPackageNameFromRequest( request ) { + const parts = request.split( '/' ); + if ( parts[ 0 ]?.startsWith( '@' ) && parts.length >= 2 ) { + return `${ parts[ 0 ] }/${ parts[ 1 ] }`; + } +} /** * Default request to global transformation @@ -55,7 +175,7 @@ function defaultRequestToExternal( request ) { return 'ReactRefreshRuntime'; } - if ( BUNDLED_PACKAGES.includes( request ) ) { + if ( isBundledPackageForScripts( request ) ) { return undefined; } diff --git a/packages/dependency-extraction-webpack-plugin/test/util.js b/packages/dependency-extraction-webpack-plugin/test/util.js index 05e47b87ccb496..17617284178bb5 100644 --- a/packages/dependency-extraction-webpack-plugin/test/util.js +++ b/packages/dependency-extraction-webpack-plugin/test/util.js @@ -48,6 +48,16 @@ describe( 'defaultRequestToExternal', () => { ).toEqual( [ 'wp', 'someFuturePackage' ] ); } ); + test( 'Keeps bundled @wordpress packages internal', () => { + expect( defaultRequestToExternal( '@wordpress/ui' ) ).toBeUndefined(); + } ); + + test( 'Externalizes wpScript packages', () => { + expect( defaultRequestToExternal( '@wordpress/undo-manager' ) ).toEqual( + [ 'wp', 'undoManager' ] + ); + } ); + test( 'Handles react request', () => { expect( defaultRequestToExternal( 'react' ) ).toBe( 'React' ); } ); diff --git a/packages/fields/CHANGELOG.md b/packages/fields/CHANGELOG.md index 351e25af3c81a5..375999d5d85900 100644 --- a/packages/fields/CHANGELOG.md +++ b/packages/fields/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Internal + +- Declare `wpScript: false` to mark the package as bundled rather than externalized. ([#79945](https://github.com/WordPress/gutenberg/pull/79945)) + ## 0.42.0 (2026-07-01) ## 0.41.0 (2026-06-24) diff --git a/packages/fields/package.json b/packages/fields/package.json index b10cdba21d7862..d3d86ee086e14a 100644 --- a/packages/fields/package.json +++ b/packages/fields/package.json @@ -40,6 +40,7 @@ }, "./package.json": "./package.json" }, + "wpScript": false, "types": "build-types", "sideEffects": [ "build-style/**", diff --git a/packages/icons/CHANGELOG.md b/packages/icons/CHANGELOG.md index cf870a8b7779f7..65f16f835a7eca 100644 --- a/packages/icons/CHANGELOG.md +++ b/packages/icons/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Internal + +- Declare `wpScript: false` to mark the package as bundled rather than externalized. ([#79945](https://github.com/WordPress/gutenberg/pull/79945)) + ## 15.1.0 (2026-07-01) ## 15.0.0 (2026-06-24) diff --git a/packages/icons/package.json b/packages/icons/package.json index f6715f02ebb04f..7f0e11ca68291f 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -40,6 +40,7 @@ }, "./package.json": "./package.json" }, + "wpScript": false, "types": "build-types", "sideEffects": false, "dependencies": { diff --git a/packages/interface/CHANGELOG.md b/packages/interface/CHANGELOG.md index fc3f2a9ac35ac4..9ff42cf80df881 100644 --- a/packages/interface/CHANGELOG.md +++ b/packages/interface/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Internal + +- Declare `wpScript: false` to mark the package as bundled rather than externalized. ([#79945](https://github.com/WordPress/gutenberg/pull/79945)) + ## 9.35.0 (2026-07-01) ## 9.34.0 (2026-06-24) diff --git a/packages/interface/package.json b/packages/interface/package.json index 8d18b51fefdd18..ce4de006b8c7c1 100644 --- a/packages/interface/package.json +++ b/packages/interface/package.json @@ -41,6 +41,7 @@ "./package.json": "./package.json", "./build-style/": "./build-style/" }, + "wpScript": false, "sideEffects": [ "build-style/**", "src/**/*.scss", diff --git a/packages/style-runtime/CHANGELOG.md b/packages/style-runtime/CHANGELOG.md index e30f092bda717a..659fd9f3d25ca8 100644 --- a/packages/style-runtime/CHANGELOG.md +++ b/packages/style-runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Internal + +- Declare `wpScript: false` to mark the package as bundled rather than externalized. ([#79945](https://github.com/WordPress/gutenberg/pull/79945)) + ## 0.6.0 (2026-07-01) ## 0.5.0 (2026-06-24) diff --git a/packages/style-runtime/package.json b/packages/style-runtime/package.json index cdbd0bbc5d3836..408c86dc9ada64 100644 --- a/packages/style-runtime/package.json +++ b/packages/style-runtime/package.json @@ -39,6 +39,7 @@ }, "./package.json": "./package.json" }, + "wpScript": false, "types": "build-types", "sideEffects": false, "publishConfig": { diff --git a/packages/views/CHANGELOG.md b/packages/views/CHANGELOG.md index c2944b4d416140..89c601a6eccefa 100644 --- a/packages/views/CHANGELOG.md +++ b/packages/views/CHANGELOG.md @@ -2,4 +2,8 @@ ## Unreleased +### Internal + +- Declare `wpScript: false` to mark the package as bundled rather than externalized. ([#79945](https://github.com/WordPress/gutenberg/pull/79945)) + ## 1.17.0 (2026-07-01) diff --git a/packages/views/package.json b/packages/views/package.json index 644c3dff218ca7..09e51ef5af8ea8 100644 --- a/packages/views/package.json +++ b/packages/views/package.json @@ -39,6 +39,7 @@ }, "./package.json": "./package.json" }, + "wpScript": false, "types": "build-types", "dependencies": { "@wordpress/core-data": "file:../core-data",