@@ -88,31 +88,31 @@ class WP_Script_Modules {
8888 * @since 6.5.0
8989 * @since 6.9.0 Added the $args parameter.
9090 *
91- * @param string $id The identifier of the script module. Should be unique. It will be used in the
92- * final import map.
93- * @param string $src Optional. Full URL of the script module, or path of the script module relative
94- * to the WordPress root directory. If it is provided and the script module has
95- * not been registered yet, it will be registered.
96- * @param array<string|array> $deps {
97- * Optional. List of dependencies.
98- *
99- * @type string|array ...$0 {
100- * An array of script module identifiers of the dependencies of this script
101- * module. The dependencies can be strings or arrays. If they are arrays,
102- * they need an `id` key with the script module identifier, and can contain
103- * an `import` key with either `static` or `dynamic`. By default,
104- * dependencies that don't contain an `import` key are considered static.
105- *
106- * @type string $id The script module identifier.
107- * @type string $import Optional. Import type. May be either `static` or
108- * `dynamic`. Defaults to `static`.
109- * }
110- * }
111- * @param string|false|null $version Optional. String specifying the script module version number. Defaults to false.
112- * It is added to the URL as a query string for cache busting purposes. If $version
113- * is set to false, the version number is the currently installed WordPress version.
114- * If $version is set to null, no version is added.
115- * @param array<string, string|bool> $args {
91+ * @param string $id The identifier of the script module. Should be unique. It will be used in the
92+ * final import map.
93+ * @param string $src Optional. Full URL of the script module, or path of the script module relative
94+ * to the WordPress root directory. If it is provided and the script module has
95+ * not been registered yet, it will be registered.
96+ * @param array<string|array<string, string>> $deps {
97+ * Optional. List of dependencies.
98+ *
99+ * @type string|array<string, string> ...$0 {
100+ * An array of script module identifiers of the dependencies of this script
101+ * module. The dependencies can be strings or arrays. If they are arrays,
102+ * they need an `id` key with the script module identifier, and can contain
103+ * an `import` key with either `static` or `dynamic`. By default,
104+ * dependencies that don't contain an `import` key are considered static.
105+ *
106+ * @type string $id The script module identifier.
107+ * @type string $import Optional. Import type. May be either `static` or
108+ * `dynamic`. Defaults to `static`.
109+ * }
110+ * }
111+ * @param string|false|null $version Optional. String specifying the script module version number. Defaults to false.
112+ * It is added to the URL as a query string for cache busting purposes. If $version
113+ * is set to false, the version number is the currently installed WordPress version.
114+ * If $version is set to null, no version is added.
115+ * @param array<string, string|bool> $args {
116116 * Optional. An array of additional args. Default empty array.
117117 *
118118 * @type bool $in_footer Whether to print the script module in the footer. Only relevant to block themes. Default 'false'. Optional.
@@ -260,31 +260,31 @@ public function set_in_footer( string $id, bool $in_footer ): bool {
260260 * @since 6.5.0
261261 * @since 6.9.0 Added the $args parameter.
262262 *
263- * @param string $id The identifier of the script module. Should be unique. It will be used in the
264- * final import map.
265- * @param string $src Optional. Full URL of the script module, or path of the script module relative
266- * to the WordPress root directory. If it is provided and the script module has
267- * not been registered yet, it will be registered.
268- * @param array<string|array> $deps {
269- * Optional. List of dependencies.
270- *
271- * @type string|array ...$0 {
272- * An array of script module identifiers of the dependencies of this script
273- * module. The dependencies can be strings or arrays. If they are arrays,
274- * they need an `id` key with the script module identifier, and can contain
275- * an `import` key with either `static` or `dynamic`. By default,
276- * dependencies that don't contain an `import` key are considered static.
277- *
278- * @type string $id The script module identifier.
279- * @type string $import Optional. Import type. May be either `static` or
280- * `dynamic`. Defaults to `static`.
281- * }
282- * }
283- * @param string|false|null $version Optional. String specifying the script module version number. Defaults to false.
284- * It is added to the URL as a query string for cache busting purposes. If $version
285- * is set to false, the version number is the currently installed WordPress version.
286- * If $version is set to null, no version is added.
287- * @param array<string, string|bool> $args {
263+ * @param string $id The identifier of the script module. Should be unique. It will be used in the
264+ * final import map.
265+ * @param string $src Optional. Full URL of the script module, or path of the script module relative
266+ * to the WordPress root directory. If it is provided and the script module has
267+ * not been registered yet, it will be registered.
268+ * @param array<string|array<string, string>> $deps {
269+ * Optional. List of dependencies.
270+ *
271+ * @type string|array<string, string> ...$0 {
272+ * An array of script module identifiers of the dependencies of this script
273+ * module. The dependencies can be strings or arrays. If they are arrays,
274+ * they need an `id` key with the script module identifier, and can contain
275+ * an `import` key with either `static` or `dynamic`. By default,
276+ * dependencies that don't contain an `import` key are considered static.
277+ *
278+ * @type string $id The script module identifier.
279+ * @type string $import Optional. Import type. May be either `static` or
280+ * `dynamic`. Defaults to `static`.
281+ * }
282+ * }
283+ * @param string|false|null $version Optional. String specifying the script module version number. Defaults to false.
284+ * It is added to the URL as a query string for cache busting purposes. If $version
285+ * is set to false, the version number is the currently installed WordPress version.
286+ * If $version is set to null, no version is added.
287+ * @param array<string, string|bool> $args {
288288 * Optional. An array of additional args. Default empty array.
289289 *
290290 * @type bool $in_footer Whether to print the script module in the footer. Only relevant to block themes. Default 'false'. Optional.
@@ -533,13 +533,87 @@ public function print_import_map() {
533533 * Returns the import map array.
534534 *
535535 * @since 6.5.0
536+ * @since 7.0.0 Script module dependencies ('module_dependencies') of classic scripts are now included.
537+ *
538+ * @global WP_Scripts $wp_scripts
536539 *
537540 * @return array<string, array<string, string>> Array with an `imports` key mapping to an array of script module
538541 * identifiers and their respective URLs, including the version query.
539542 */
540543 private function get_import_map (): array {
544+ global $ wp_scripts ;
545+
541546 $ imports = array ();
542- foreach ( array_keys ( $ this ->get_dependencies ( $ this ->queue ) ) as $ id ) {
547+
548+ // Identify script modules that are dependencies of classic scripts.
549+ $ classic_script_module_dependencies = array ();
550+ if ( $ wp_scripts instanceof WP_Scripts ) {
551+ $ handles = array_merge (
552+ $ wp_scripts ->queue ,
553+ $ wp_scripts ->to_do ,
554+ $ wp_scripts ->done
555+ );
556+
557+ $ processed = array ();
558+ while ( ! empty ( $ handles ) ) {
559+ $ handle = array_pop ( $ handles );
560+ if ( isset ( $ processed [ $ handle ] ) || ! isset ( $ wp_scripts ->registered [ $ handle ] ) ) {
561+ continue ;
562+ }
563+ $ processed [ $ handle ] = true ;
564+
565+ $ module_dependencies = $ wp_scripts ->get_data ( $ handle , 'module_dependencies ' );
566+ if ( is_array ( $ module_dependencies ) ) {
567+ $ missing_module_dependencies = array ();
568+ foreach ( $ module_dependencies as $ module ) {
569+ if ( is_string ( $ module ) ) {
570+ $ id = $ module ;
571+ } elseif ( is_array ( $ module ) && isset ( $ module ['id ' ] ) && is_string ( $ module ['id ' ] ) ) {
572+ $ id = $ module ['id ' ];
573+ } else {
574+ // Invalid module dependency was supplied by direct manipulation of the extra data.
575+ // Normally, this error scenario would be caught when WP_Scripts::add_data() is called.
576+ continue ;
577+ }
578+
579+ if ( ! isset ( $ this ->registered [ $ id ] ) ) {
580+ $ missing_module_dependencies [] = $ id ;
581+ } else {
582+ $ classic_script_module_dependencies [] = $ id ;
583+ }
584+ }
585+
586+ if ( count ( $ missing_module_dependencies ) > 0 ) {
587+ _doing_it_wrong (
588+ 'WP_Scripts::add_data ' ,
589+ sprintf (
590+ /* translators: 1: Script handle, 2: 'module_dependencies', 3: List of missing dependency IDs. */
591+ __ ( 'The script with the handle "%1$s" was enqueued with script module dependencies ("%2$s") that are not registered: %3$s. ' ),
592+ $ handle ,
593+ 'module_dependencies ' ,
594+ implode ( wp_get_list_item_separator (), $ missing_module_dependencies )
595+ ),
596+ '7.0.0 '
597+ );
598+ }
599+ }
600+
601+ foreach ( $ wp_scripts ->registered [ $ handle ]->deps as $ dep ) {
602+ if ( ! isset ( $ processed [ $ dep ] ) ) {
603+ $ handles [] = $ dep ;
604+ }
605+ }
606+ }
607+ }
608+
609+ // Note: the script modules in $this->queue are not included in the importmap because they get printed as scripts.
610+ $ ids = array_unique (
611+ array_merge (
612+ $ classic_script_module_dependencies ,
613+ array_keys ( $ this ->get_dependencies ( array_merge ( $ this ->queue , $ classic_script_module_dependencies ) ) )
614+ )
615+ );
616+ foreach ( $ ids as $ id ) {
543617 $ src = $ this ->get_src ( $ id );
544618 if ( '' !== $ src ) {
545619 $ imports [ $ id ] = $ src ;
0 commit comments