<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[59083] trunk: Build: Prepare for more Script Modules</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/59083">59083</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/59083","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>gziolo</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2024-09-24 07:33:55 +0000 (Tue, 24 Sep 2024)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Build: Prepare for more Script Modules

This is a companion to https://github.com/WordPress/gutenberg/pull/65460 that requires syncing in WordPress Core. Namely, the block-library changes require registration with their updated script module IDs so that the blocks continue to work correctly.

They key improvement is script modules registration is handled in one central place, and a combined asset file is used to improve the performance by avoiding multiple disk operations for every individual file.

Props jonsurrell, gziolo, wildworks, noisysocks.
See <a href="https://core.trac.wordpress.org/ticket/60647">#60647</a>, <a href="https://core.trac.wordpress.org/ticket/59462">#59462</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkgitignore">trunk/.gitignore</a></li>
<li><a href="#trunkGruntfilejs">trunk/Gruntfile.js</a></li>
<li><a href="#trunksrcwpincludesdefaultfiltersphp">trunk/src/wp-includes/default-filters.php</a></li>
<li><a href="#trunksrcwpincludesinteractivityapiclasswpinteractivityapiphp">trunk/src/wp-includes/interactivity-api/class-wp-interactivity-api.php</a></li>
<li><a href="#trunksrcwpincludesscriptmodulesphp">trunk/src/wp-includes/script-modules.php</a></li>
<li><a href="#trunktestsphpunittestsinteractivityapiwpInteractivityAPIphp">trunk/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php</a></li>
<li><a href="#trunktoolswebpacksharedjs">trunk/tools/webpack/shared.js</a></li>
<li><a href="#trunkwebpackconfigjs">trunk/webpack.config.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesassetsscriptmodulespackagesminphp">trunk/src/wp-includes/assets/script-modules-packages.min.php</a></li>
<li><a href="#trunktoolswebpackscriptmodulesjs">trunk/tools/webpack/script-modules.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunktoolswebpackmodulesjs">trunk/tools/webpack/modules.js</a></li>
</ul>

<h3>Property Changed</h3>
<ul>
<li><a href="#trunksrcwpincludesassets">trunk/src/wp-includes/assets/</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkgitignore"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/.gitignore</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/.gitignore  2024-09-23 22:15:11 UTC (rev 59082)
+++ trunk/.gitignore    2024-09-24 07:33:55 UTC (rev 59083)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -31,6 +31,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /src/wp-admin/js
</span><span class="cx" style="display: block; padding: 0 10px"> /src/wp-includes/assets/*
</span><span class="cx" style="display: block; padding: 0 10px"> !/src/wp-includes/assets/script-loader-packages.min.php
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+!/src/wp-includes/assets/script-modules-packages.min.php
</ins><span class="cx" style="display: block; padding: 0 10px"> /src/wp-includes/js
</span><span class="cx" style="display: block; padding: 0 10px"> /src/wp-includes/css/dist
</span><span class="cx" style="display: block; padding: 0 10px"> /src/wp-includes/css/*.min.css
</span></span></pre></div>
<a id="trunkGruntfilejs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/Gruntfile.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/Gruntfile.js        2024-09-23 22:15:11 UTC (rev 59082)
+++ trunk/Gruntfile.js  2024-09-24 07:33:55 UTC (rev 59083)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -56,6 +56,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        'wp-includes/css/dist',
</span><span class="cx" style="display: block; padding: 0 10px">                        'wp-includes/blocks/**/*.css',
</span><span class="cx" style="display: block; padding: 0 10px">                        '!wp-includes/assets/script-loader-packages.min.php',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        '!wp-includes/assets/script-modules-packages.min.php',
</ins><span class="cx" style="display: block; padding: 0 10px">                 ],
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Prepend `dir` to `file`, and keep `!` in place.
</span><span class="cx" style="display: block; padding: 0 10px">Index: trunk/src/wp-includes/assets
</span><span class="cx" style="display: block; padding: 0 10px">===================================================================
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">--- trunk/src/wp-includes/assets 2024-09-23 22:15:11 UTC (rev 59082)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+++ trunk/src/wp-includes/assets  2024-09-24 07:33:55 UTC (rev 59083)
</ins></span></pre></div>
<a id="trunksrcwpincludesassets"></a>
<div class="propset"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Property changes: trunk/src/wp-includes/assets</h4>
<pre class="diff"><span>
</span></pre></div>
<a id="svnignore"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: svn:ignore</h4></div>
<span class="cx" style="display: block; padding: 0 10px"> script-loader-packages.php
</span><span class="cx" style="display: block; padding: 0 10px"> script-loader-react-*.php
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+script-modules-packages.php
</ins><a id="trunksrcwpincludesassetsscriptmodulespackagesminphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/assets/script-modules-packages.min.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/assets/script-modules-packages.min.php                              (rev 0)
+++ trunk/src/wp-includes/assets/script-modules-packages.min.php        2024-09-24 07:33:55 UTC (rev 59083)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?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'), 'v
 ersion' => '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'));
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/src/wp-includes/assets/script-modules-packages.min.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunksrcwpincludesdefaultfiltersphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/default-filters.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/default-filters.php 2024-09-23 22:15:11 UTC (rev 59082)
+++ trunk/src/wp-includes/default-filters.php   2024-09-24 07:33:55 UTC (rev 59083)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -570,6 +570,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // Script Loader.
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'wp_default_scripts', 'wp_default_scripts' );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'wp_default_scripts', 'wp_default_packages' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+add_action( 'wp_default_scripts', 'wp_default_script_modules' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'wp_enqueue_scripts', 'wp_localize_jquery_ui_datepicker', 1000 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'wp_enqueue_scripts', 'wp_common_block_scripts_and_styles' );
</span></span></pre></div>
<a id="trunksrcwpincludesinteractivityapiclasswpinteractivityapiphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/interactivity-api/class-wp-interactivity-api.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/interactivity-api/class-wp-interactivity-api.php    2024-09-23 22:15:11 UTC (rev 59082)
+++ trunk/src/wp-includes/interactivity-api/class-wp-interactivity-api.php      2024-09-24 07:33:55 UTC (rev 59083)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -281,21 +281,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * Registers the `@wordpress/interactivity` script modules.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @deprecated 6.7.0 Script Modules registration is handled by {@see wp_default_script_modules()}.
+        *
</ins><span class="cx" style="display: block; padding: 0 10px">          * @since 6.5.0
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function register_script_modules() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $suffix = wp_scripts_get_suffix();
-
-               wp_register_script_module(
-                       '@wordpress/interactivity',
-                       includes_url( "js/dist/interactivity$suffix.js" )
-               );
-
-               wp_register_script_module(
-                       '@wordpress/interactivity-router',
-                       includes_url( "js/dist/interactivity-router$suffix.js" ),
-                       array( '@wordpress/interactivity' )
-               );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         _deprecated_function( __METHOD__, '6.7.0', 'wp_default_script_modules' );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -302,12 +293,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * Adds the necessary hooks for the Interactivity API.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 6.5.0
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @since 6.7.0 Use the {@see "script_module_data_{$module_id}"} filter to pass client-side data.
</del><span class="cx" style="display: block; padding: 0 10px">          */
</span><span class="cx" style="display: block; padding: 0 10px">        public function add_hooks() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                add_action( 'wp_enqueue_scripts', array( $this, 'register_script_modules' ) );
-               add_action( 'admin_enqueue_scripts', array( $this, 'register_script_modules' ) );
-
</del><span class="cx" style="display: block; padding: 0 10px">                 add_filter( 'script_module_data_@wordpress/interactivity', array( $this, 'filter_script_module_interactivity_data' ) );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpincludesscriptmodulesphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/script-modules.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/script-modules.php  2024-09-23 22:15:11 UTC (rev 59082)
+++ trunk/src/wp-includes/script-modules.php    2024-09-24 07:33:55 UTC (rev 59083)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -123,3 +123,53 @@
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_deregister_script_module( string $id ) {
</span><span class="cx" style="display: block; padding: 0 10px">        wp_script_modules()->deregister( $id );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * 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
+                */
+               $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'] );
+       }
+}
</ins></span></pre></div>
<a id="trunktestsphpunittestsinteractivityapiwpInteractivityAPIphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php        2024-09-23 22:15:11 UTC (rev 59082)
+++ trunk/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php  2024-09-24 07:33:55 UTC (rev 59083)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -212,6 +212,17 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Test that the deprecated register_script_modules method is deprecated but does not throw.
+        *
+        * @ticket 60647
+        *
+        * @expectedDeprecated WP_Interactivity_API::register_script_modules
+        */
+       public function test_register_script_modules_deprecated() {
+               $this->interactivity->register_script_modules();
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Sets up an activity, runs an optional callback, and returns a MockAction for inspection.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 6.7.0
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -221,7 +232,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        private function get_script_data_filter_result( ?Closure $callback = null ): MockAction {
</span><span class="cx" style="display: block; padding: 0 10px">                $this->interactivity->add_hooks();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->interactivity->register_script_modules();
</del><span class="cx" style="display: block; padding: 0 10px">                 wp_enqueue_script_module( '@wordpress/interactivity' );
</span><span class="cx" style="display: block; padding: 0 10px">                $filter = new MockAction();
</span><span class="cx" style="display: block; padding: 0 10px">                add_filter( 'script_module_data_@wordpress/interactivity', array( $filter, 'filter' ) );
</span></span></pre></div>
<a id="trunktoolswebpackmodulesjs"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/tools/webpack/modules.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tools/webpack/modules.js    2024-09-23 22:15:11 UTC (rev 59082)
+++ trunk/tools/webpack/modules.js      2024-09-24 07:33:55 UTC (rev 59083)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,76 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * WordPress dependencies
- */
-const DependencyExtractionPlugin = require( '@wordpress/dependency-extraction-webpack-plugin' );
-
-/**
- * Internal dependencies
- */
-const {
-       baseDir,
-       getBaseConfig,
-       normalizeJoin,
-       MODULES,
-       WORDPRESS_NAMESPACE,
-} = require( './shared' );
-
-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: MODULES.map( ( packageName ) =>
-                       packageName.replace( WORDPRESS_NAMESPACE, '' )
-               ).reduce( ( memo, packageName ) => {
-                       const path =
-                               'development' === mode && 'interactivity' === packageName
-                                       ? 'interactivity/build-module/debug'
-                                       : packageName;
-                       memo[ packageName ] = {
-                               import: normalizeJoin(
-                                       baseDir,
-                                       `node_modules/@wordpress/${ path }`
-                               ),
-                       };
-
-                       return memo;
-               }, {} ),
-               experiments: {
-                       outputModule: true,
-               },
-               output: {
-                       devtoolNamespace: 'wp',
-                       filename: `[name]${ suffix }.js`,
-                       path: normalizeJoin( baseDir, `${ buildTarget }/js/dist` ),
-                       library: {
-                               type: 'module',
-                       },
-                       environment: { module: true },
-               },
-               externalsType: 'module',
-               externals: {
-                       '@wordpress/interactivity': '@wordpress/interactivity',
-                       '@wordpress/interactivity-router':
-                               'import @wordpress/interactivity-router',
-               },
-               plugins: [
-                       ...baseConfig.plugins,
-                       new DependencyExtractionPlugin( {
-                               injectPolyfill: false,
-                               useDefaults: false,
-                       } ),
-               ],
-       };
-
-       return config;
-};
</del></span></pre></div>
<a id="trunktoolswebpackscriptmodulesjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tools/webpack/script-modules.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tools/webpack/script-modules.js                             (rev 0)
+++ trunk/tools/webpack/script-modules.js       2024-09-24 07:33:55 UTC (rev 59083)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,119 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * 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;
+};
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/tools/webpack/script-modules.js
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunktoolswebpacksharedjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tools/webpack/shared.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tools/webpack/shared.js     2024-09-23 22:15:11 UTC (rev 59082)
+++ trunk/tools/webpack/shared.js       2024-09-24 07:33:55 UTC (rev 59083)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -102,6 +102,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">        '@wordpress/interactivity',
</span><span class="cx" style="display: block; padding: 0 10px">        '@wordpress/interactivity-router',
</span><span class="cx" style="display: block; padding: 0 10px"> ];
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+const SCRIPT_AND_MODULE_DUAL_PACKAGES = [
+       '@wordpress/block-library',
+];
</ins><span class="cx" style="display: block; padding: 0 10px"> const WORDPRESS_NAMESPACE = '@wordpress/';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> module.exports = {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -111,5 +114,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">        stylesTransform,
</span><span class="cx" style="display: block; padding: 0 10px">        BUNDLED_PACKAGES,
</span><span class="cx" style="display: block; padding: 0 10px">        MODULES,
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        SCRIPT_AND_MODULE_DUAL_PACKAGES,
</ins><span class="cx" style="display: block; padding: 0 10px">         WORDPRESS_NAMESPACE,
</span><span class="cx" style="display: block; padding: 0 10px"> };
</span></span></pre></div>
<a id="trunkwebpackconfigjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/webpack.config.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/webpack.config.js   2024-09-23 22:15:11 UTC (rev 59082)
+++ trunk/webpack.config.js     2024-09-24 07:33:55 UTC (rev 59083)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,7 +2,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> const developmentConfig = require( './tools/webpack/development' );
</span><span class="cx" style="display: block; padding: 0 10px"> const mediaConfig = require( './tools/webpack/media' );
</span><span class="cx" style="display: block; padding: 0 10px"> const packagesConfig = require( './tools/webpack/packages' );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-const modulesConfig = require( './tools/webpack/modules' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+const scriptModulesConfig = require( './tools/webpack/script-modules' );
</ins><span class="cx" style="display: block; padding: 0 10px"> const vendorsConfig = require( './tools/webpack/vendors' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> module.exports = function( env = { environment: "production", watch: false, buildTarget: false } ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -19,7 +19,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                ...developmentConfig( env ),
</span><span class="cx" style="display: block; padding: 0 10px">                mediaConfig( env ),
</span><span class="cx" style="display: block; padding: 0 10px">                packagesConfig( env ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                modulesConfig( env ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         scriptModulesConfig( env ),
</ins><span class="cx" style="display: block; padding: 0 10px">                 ...vendorsConfig( env ),
</span><span class="cx" style="display: block; padding: 0 10px">        ];
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre>
</div>
</div>

</body>
</html>