@@ -4,17 +4,68 @@ type Style = {
44 version ?: string ;
55 media ?: string ;
66} ;
7-
87type InlineStyle = string | string [ ] ;
9-
108type Script = {
119 src : string ;
1210 deps ?: string [ ] ;
1311 version ?: string ;
1412 in_footer ?: boolean ;
1513} ;
16-
1714type InlineScript = string | string [ ] ;
15+ type ScriptModules = Record < string , string > ;
16+
17+ /**
18+ * Injects or extends the import map with new module entries.
19+ *
20+ * @param scriptModules - Object mapping module specifiers to URLs
21+ */
22+ function injectImportMap ( scriptModules : Record < string , string > ) : void {
23+ if ( ! scriptModules || Object . keys ( scriptModules ) . length === 0 ) {
24+ return ;
25+ }
26+
27+ // Find the existing import map script element
28+ const existingMapElement = document . querySelector < HTMLScriptElement > (
29+ 'script#wp-importmap[type=importmap]'
30+ ) ;
31+
32+ if ( existingMapElement ) {
33+ try {
34+ // Parse the existing import map
35+ const existingMap = JSON . parse ( existingMapElement . text ) ;
36+
37+ // Ensure the imports object exists
38+ if ( ! existingMap . imports ) {
39+ existingMap . imports = { } ;
40+ }
41+
42+ // Merge new imports with existing ones (new entries take precedence)
43+ existingMap . imports = {
44+ ...existingMap . imports ,
45+ ...scriptModules ,
46+ } ;
47+
48+ // Update the script element's content
49+ existingMapElement . text = JSON . stringify ( existingMap , null , 2 ) ;
50+ } catch ( error ) {
51+ // eslint-disable-next-line no-console
52+ console . error ( 'Failed to parse or update import map:' , error ) ;
53+ }
54+ } else {
55+ // If no import map exists, create a new one
56+ const script = document . createElement ( 'script' ) ;
57+ script . type = 'importmap' ;
58+ script . id = 'wp-importmap' ;
59+ script . text = JSON . stringify (
60+ {
61+ imports : scriptModules ,
62+ } ,
63+ null ,
64+ 2
65+ ) ;
66+ document . head . appendChild ( script ) ;
67+ }
68+ }
1869
1970function loadStylesheet ( handle : string , styleData : Style ) : Promise < void > {
2071 return new Promise ( ( resolve ) => {
@@ -197,8 +248,14 @@ async function loadAssets(
197248 inlineScripts : Record < 'before' | 'after' , Record < string , InlineScript > > ,
198249 stylesData : Record < string , Style > ,
199250 inlineStyles : Record < 'before' | 'after' , Record < string , InlineStyle > > ,
200- htmlTemplates ?: string [ ]
251+ htmlTemplates ?: string [ ] ,
252+ scriptModules ?: ScriptModules
201253) : Promise < void > {
254+ // Inject import map first so script modules can be resolved
255+ if ( scriptModules ) {
256+ injectImportMap ( scriptModules ) ;
257+ }
258+
202259 // Build dependency-ordered lists
203260 const orderedStyles = buildDependencyOrderedList ( stylesData ) ;
204261 const orderedScripts = buildDependencyOrderedList ( scriptsData ) ;
0 commit comments