-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Build: Prepare for more Script Modules #7360
Changes from all commits
d6de7d0
54476a9
17e7dbc
bdd5123
a3011f4
b207015
b2547a2
502f146
1f65609
96a28a8
d2317ab
fb04163
47524d4
02deb22
7047c60
92aa6f9
d864449
7836320
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<?php return array('interactivity/index.min.js' => array('dependencies' => array(), 'version' => '2d6d1fdbcb3fda39c768', 'type' => 'module'), 'interactivity/debug.min.js' => array('dependencies' => array(), 'version' => '1ccc67b05c275e51a8f8', 'type' => 'module'), 'interactivity-router/index.min.js' => array('dependencies' => array('@wordpress/interactivity'), 'version' => '64645ef3cd2d32860d7d', 'type' => 'module'), 'block-library/file/view.min.js' => array('dependencies' => array('@wordpress/interactivity'), 'version' => 'fdc2f6842e015af83140', 'type' => 'module'), 'block-library/image/view.min.js' => array('dependencies' => array('@wordpress/interactivity'), 'version' => 'acfec7b3c0be4a859b31', 'type' => 'module'), 'block-library/navigation/view.min.js' => array('dependencies' => array('@wordpress/interactivity'), 'version' => '8ff192874fc8910a284c', 'type' => 'module'), 'block-library/query/view.min.js' => array('dependencies' => array('@wordpress/interactivity', array('id' => '@wordpress/interactivity-router', 'import' => 'dynamic')), 'version' => 'f4c91c89fa5271f3dad9', 'type' => 'module'), 'block-library/search/view.min.js' => array('dependencies' => array('@wordpress/interactivity'), 'version' => '2a73400a693958f604de', 'type' => 'module')); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -123,3 +123,53 @@ function wp_dequeue_script_module( string $id ) { | |
function wp_deregister_script_module( string $id ) { | ||
wp_script_modules()->deregister( $id ); | ||
} | ||
|
||
/** | ||
* Registers all the default WordPress Script Modules. | ||
* | ||
* @since 6.7.0 | ||
*/ | ||
function wp_default_script_modules() { | ||
$suffix = defined( 'WP_RUN_CORE_TESTS' ) ? '.min' : wp_scripts_get_suffix(); | ||
|
||
/* | ||
* Expects multidimensional array like: | ||
* | ||
* 'interactivity/index.min.js' => array('dependencies' => array(…), 'version' => '…'), | ||
* 'interactivity/debug.min.js' => array('dependencies' => array(…), 'version' => '…'), | ||
* 'interactivity-router/index.min.js' => … | ||
*/ | ||
$assets = include ABSPATH . WPINC . "/assets/script-modules-packages{$suffix}.php"; | ||
|
||
foreach ( $assets as $file_name => $script_module_data ) { | ||
/* | ||
* Build the WordPress Script Module ID from the file name. | ||
* Prepend `@wordpress/` and remove extensions and `/index` if present: | ||
* - interactivity/index.min.js => @wordpress/interactivity | ||
* - interactivity/debug.min.js => @wordpress/interactivity/debug | ||
* - block-library/query/view.js => @wordpress/block-library/query/view | ||
Comment on lines
+148
to
+150
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if these paths are the same on Windows. The challenge is that for regular scripts, the path contains only the file name. In this case, it's also folders so let's confirm that there isn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe @t-hamano could help with that like in WordPress/gutenberg#65064 (comment). After
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested this PR on a Windows host OS. From my understanding, In both commands, the I then replaced the core files in my local WordPress environment on my Windows host OS with the files built in this PR. The image lightbox works and scripts seem to be enqueued correctly. The navigation block works fine too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you 👍
Perfect, so that file should be stable across different systems and working correctly 👌 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @t-hamano, thank you so much for testing and confirming it works the same on Windows. |
||
*/ | ||
$script_module_id = '@wordpress/' . preg_replace( '~(?:/index)?(?:\.min)?\.js$~D', '', $file_name, 1 ); | ||
|
||
switch ( $script_module_id ) { | ||
/* | ||
* Interactivity exposes two entrypoints, "/index" and "/debug". | ||
* "/debug" should replalce "/index" in devlopment. | ||
*/ | ||
case '@wordpress/interactivity/debug': | ||
if ( ! SCRIPT_DEBUG ) { | ||
continue 2; | ||
} | ||
$script_module_id = '@wordpress/interactivity'; | ||
break; | ||
case '@wordpress/interactivity': | ||
if ( SCRIPT_DEBUG ) { | ||
continue 2; | ||
} | ||
break; | ||
} | ||
|
||
$path = "/wp-includes/js/dist/script-modules/{$file_name}"; | ||
wp_register_script_module( $script_module_id, $path, $script_module_data['dependencies'], $script_module_data['version'] ); | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
const { createRequire } = require( 'node:module' ); | ||
const { dirname } = require( 'node:path' ); | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
const DependencyExtractionPlugin = require( '@wordpress/dependency-extraction-webpack-plugin' ); | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
const { | ||
baseDir, | ||
getBaseConfig, | ||
normalizeJoin, | ||
MODULES, | ||
SCRIPT_AND_MODULE_DUAL_PACKAGES, | ||
WORDPRESS_NAMESPACE, | ||
} = require( './shared' ); | ||
|
||
/** @type {Map<string, string>} */ | ||
const scriptModules = new Map(); | ||
for ( const packageName of MODULES.concat( SCRIPT_AND_MODULE_DUAL_PACKAGES ) ) { | ||
const packageRequire = createRequire( | ||
`${ dirname( require.resolve( `${ packageName }/package.json` ) ) }/` | ||
); | ||
|
||
const depPackageJson = packageRequire( './package.json' ); | ||
if ( ! Object.hasOwn( depPackageJson, 'wpScriptModuleExports' ) ) { | ||
continue; | ||
} | ||
|
||
const moduleName = packageName.substring( WORDPRESS_NAMESPACE.length ); | ||
let { wpScriptModuleExports } = depPackageJson; | ||
|
||
// Special handling for { "wpScriptModuleExports": "./build-module/index.js" }. | ||
if ( typeof wpScriptModuleExports === 'string' ) { | ||
wpScriptModuleExports = { '.': wpScriptModuleExports }; | ||
} | ||
|
||
if ( Object.getPrototypeOf( wpScriptModuleExports ) !== Object.prototype ) { | ||
throw new Error( 'wpScriptModuleExports must be an object' ); | ||
} | ||
|
||
for ( const [ exportName, exportPath ] of Object.entries( | ||
wpScriptModuleExports | ||
) ) { | ||
if ( typeof exportPath !== 'string' ) { | ||
throw new Error( 'wpScriptModuleExports paths must be strings' ); | ||
} | ||
|
||
if ( ! exportPath.startsWith( './' ) ) { | ||
throw new Error( | ||
'wpScriptModuleExports paths must start with "./"' | ||
); | ||
} | ||
|
||
const name = | ||
exportName === '.' ? 'index' : exportName.replace( /^\.\/?/, '' ); | ||
|
||
scriptModules.set( | ||
`${ moduleName }/${ name }`, | ||
packageRequire.resolve( exportPath ) | ||
); | ||
} | ||
} | ||
|
||
module.exports = function ( | ||
env = { environment: 'production', watch: false, buildTarget: false } | ||
) { | ||
const mode = env.environment; | ||
const suffix = mode === 'production' ? '.min' : ''; | ||
let buildTarget = env.buildTarget | ||
? env.buildTarget | ||
: mode === 'production' | ||
? 'build' | ||
: 'src'; | ||
buildTarget = buildTarget + '/wp-includes'; | ||
|
||
const baseConfig = getBaseConfig( env ); | ||
const config = { | ||
...baseConfig, | ||
entry: Object.fromEntries( scriptModules.entries() ), | ||
experiments: { | ||
outputModule: true, | ||
}, | ||
output: { | ||
devtoolNamespace: 'wp', | ||
filename: `[name]${ suffix }.js`, | ||
path: normalizeJoin( | ||
baseDir, | ||
`${ buildTarget }/js/dist/script-modules` | ||
), | ||
library: { | ||
type: 'module', | ||
}, | ||
environment: { module: true }, | ||
module: true, | ||
chunkFormat: 'module', | ||
asyncChunks: false, | ||
}, | ||
plugins: [ | ||
...baseConfig.plugins, | ||
new DependencyExtractionPlugin( { | ||
injectPolyfill: false, | ||
combineAssets: true, | ||
combinedOutputFile: normalizeJoin( | ||
baseDir, | ||
`${ buildTarget }/assets/script-modules-packages${ suffix }.php` | ||
), | ||
} ), | ||
], | ||
}; | ||
|
||
return config; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m not sure if this should still live here. Could get wired in
wp_default_script_modules
next to handlers for script modules. No strong preferences, though.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. My first thought is that this is specific to Interactivity API and it should manage its script module data filters, but it's true that other script modules may have their data filters added in a more generic place.
I'm inclined to leave it now just because there's no obvious reason to move it now. Maybe in time these core script module data filters should all be registered in one place if there are many of them.
I don't feel strongly one way or another.