1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
<header><h1><script type="importmap"></h1></header><div class="section-content">
<p>The <code>importmap</code> value of the <a href="../type"><code>type</code></a> attribute of the <a href="../../script"><code><script></code> element</a> indicates that the body of the element contains an import map.</p> <p> An import map is a JSON object that allows developers to control how the browser resolves module specifiers when importing <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules">JavaScript modules</a>. It provides a mapping between the text used as the module specifier in an <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import"><code>import</code> statement</a> or <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"><code>import()</code> operator</a>, and the corresponding value that will replace the text when resolving the specifier. The JSON object must conform to the <a href="#import_map_json_representation">Import map JSON representation format</a>. </p> <p> An import map is used to resolve module specifiers in static and dynamic imports, and therefore must be declared and processed before any <code><script></code> elements that import modules using specifiers declared in the map. Note that the import map applies only to module specifiers in the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import"><code>import</code> statement</a> or <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"><code>import()</code> operator</a>; it does not apply to the path specified in the <code>src</code> attribute of a <code><script></code> element. </p> <p>For more information, see the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#importing_modules_using_import_maps">Importing modules using import maps</a> section in the JavaScript modules guide.</p>
</div>
<h2 id="syntax">Syntax</h2>
<div class="section-content">
<div class="code-example">
<p class="example-header"><span class="language-name">html</span></p>
<pre data-signature="W1MLptakZGEpSqk/zmhXElBD9r/d2cSbR9iebIbrVMk=" data-language="html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>importmap<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript">
<span class="token comment">// JSON object defining import</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span>
</pre>
</div> <p>The <code>src</code>, <code>async</code>, <code>nomodule</code>, <code>defer</code>, <code>crossorigin</code>, <code>integrity</code>, and <code>referrerpolicy</code> attributes must not be specified.</p> <p>Only the first import map in the document with an inline definition is processed; any additional import maps and external import maps are ignored.</p>
</div>
<h3 id="exceptions">Exceptions</h3>
<div class="section-content">
<dl> <dt id="typeerror"><a href="#typeerror"><code>TypeError</code></a></dt> <dd> <p>The import map definition is not a JSON object, the <code>importmap</code> key is defined but its value is not a JSON object, or the <code>scopes</code> key is defined but its value is not a JSON object.</p> </dd> </dl> <p>Browsers generate console warnings for other cases where the import map JSON does not conform to the <a href="#import_map_json_representation">import map</a> schema.</p> <p> An <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event"><code>error</code> event</a> is fired at script elements with <code>type="importmap"</code> that are not processed. This might occur, for example, if module loading has already started when an import map is processed, or if multiple import maps are defined in the page. </p>
</div>
<h2 id="description">Description</h2>
<div class="section-content">
<p> When importing a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules">JavaScript module</a>, both the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import"><code>import</code> statement</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"><code>import()</code> operator</a> have a "module specifier" that indicates the module to be imported. A browser must be able to resolve this specifier to an absolute URL in order to import the module. </p> <p>For example, the following statements import elements from the module specifier <code>"./modules/shapes/square.js"</code>, which is a path relative to the base URL of the document, and the module specifier <code>"https://example.com/shapes/circle.js"</code>, which is an absolute URL.</p> <div class="code-example">
<p class="example-header"><span class="language-name">js</span></p>
<pre data-signature="TdazKExEZ3xZwWwxrYZ63SXM5jOwQS17lyhaRNA9Wcg=" data-language="js"><span class="token keyword">import</span> <span class="token punctuation">{</span> name <span class="token keyword">as</span> squareName<span class="token punctuation">,</span> draw <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./modules/shapes/square.js"</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> name <span class="token keyword">as</span> circleName <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"https://example.com/shapes/circle.js"</span><span class="token punctuation">;</span>
</pre>
</div> <p>Import maps allow developers to specify (almost) any text they want in the module specifier; the map provides a corresponding value that will replace the text when the module specifier is resolved.</p>
</div>
<h3 id="bare_modules">Bare modules</h3>
<div class="section-content">
<p>The import map below defines an <code>imports</code> key that has a "module specifier map" with properties <code>square</code> and <code>circle</code>.</p> <div class="code-example">
<p class="example-header"><span class="language-name">html</span></p>
<pre data-signature="B/cfwcu6SI60sb2KeAMZUKgjMFOGwdP0wPPOGdy3t2o=" data-language="html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>importmap<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript">
<span class="token punctuation">{</span>
<span class="token string-property property">"imports"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token string-property property">"square"</span><span class="token operator">:</span> <span class="token string">"./module/shapes/square.js"</span><span class="token punctuation">,</span>
<span class="token string-property property">"circle"</span><span class="token operator">:</span> <span class="token string">"https://example.com/shapes/circle.js"</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span>
</pre>
</div> <p>With this import map we can import the same modules as above, but using "bare modules" in our module specifiers:</p> <div class="code-example">
<p class="example-header"><span class="language-name">js</span></p>
<pre data-signature="3z7KTwOPwElmzvBo8T4qhEwW/oNOKzGT6BYzM4NAgYc=" data-language="js"><span class="token keyword">import</span> <span class="token punctuation">{</span> name <span class="token keyword">as</span> squareName<span class="token punctuation">,</span> draw <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"square"</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> name <span class="token keyword">as</span> circleName <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"circle"</span><span class="token punctuation">;</span>
</pre>
</div>
</div>
<h3 id="mapping_path_prefixes">Mapping path prefixes</h3>
<div class="section-content">
<p> A module specifier map key can also be used to remap a path prefix in a module specifier. Note that in this case the property and mapped path must both have a trailing forward slash (<code>/</code>). </p> <div class="code-example">
<p class="example-header"><span class="language-name">html</span></p>
<pre data-signature="f5rs688GUUvsEnWzZlDepvyQ/5tryJGGg5evMI+OE64=" data-language="html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>importmap<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript">
<span class="token punctuation">{</span>
<span class="token string-property property">"imports"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token string-property property">"shapes/"</span><span class="token operator">:</span> <span class="token string">"./module/shapes/"</span><span class="token punctuation">,</span>
<span class="token string-property property">"othershapes/"</span><span class="token operator">:</span> <span class="token string">"https://example.com/modules/shapes/"</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span>
</pre>
</div> <p>We could then import a circle module as shown.</p> <div class="code-example">
<p class="example-header"><span class="language-name">js</span></p>
<pre data-signature="zDvRPLz3TafP+QYSNrib1Y5i/YeVHa22088Ew3mpmiY=" data-language="js"><span class="token keyword">import</span> <span class="token punctuation">{</span> name <span class="token keyword">as</span> circleName <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"shapes/circle.js"</span><span class="token punctuation">;</span>
</pre>
</div>
</div>
<h3 id="paths_in_the_module_specifier_map_key">Paths in the module specifier map key</h3>
<div class="section-content">
<p> Module specifier keys do not have to be single word names ("bare names"). They can also contain or end with path separators, or be absolute URLs, or be relative URL paths that start with <code>/</code>, <code>./</code>, or <code>../</code>. </p> <div class="code-example">
<p class="example-header"><span class="language-name">json</span></p>
<pre data-signature="DBXMnfrlmdqP+n7HKzDapcJ/2W75k54eDV98rVgRjl4=" data-language="json"><span class="token punctuation">{</span>
<span class="token property">"imports"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token property">"modules/shapes/"</span><span class="token operator">:</span> <span class="token string">"./module/src/shapes/"</span><span class="token punctuation">,</span>
<span class="token property">"modules/square"</span><span class="token operator">:</span> <span class="token string">"./module/src/other/shapes/square.js"</span><span class="token punctuation">,</span>
<span class="token property">"https://example.com/modules/square.js"</span><span class="token operator">:</span> <span class="token string">"./module/src/other/shapes/square.js"</span><span class="token punctuation">,</span>
<span class="token property">"../modules/shapes/"</span><span class="token operator">:</span> <span class="token string">"/modules/shapes/"</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</pre>
</div> <p>If there are several module specifier keys in a module specifier map that might match, then the most specific key will be selected (i.e. the one with the longer path/value).</p> <p> A module specifier of <code>./foo/../js/app.js</code> would be resolved to <code>./js/app.js</code> before matching. This means that a module specifier key of <code>./js/app.js</code> would match the module specifier even though they are not exactly the same. </p>
</div>
<h3 id="scoped_module_specifier_maps">Scoped module specifier maps</h3>
<div class="section-content">
<p> You can use the <code>scopes</code> key to provide mappings that are only used if the script importing the module contains a particular URL path. If the URL of the loading script matches the supplied path, the mapping associated with the scope will be used. This allows different versions of the module to be used depending on what code is doing the importing. </p> <p>For example, the map below will only use the scoped map if the loading module has a URL that includes the path: "/modules/customshapes/".</p> <div class="code-example">
<p class="example-header"><span class="language-name">html</span></p>
<pre data-signature="/IkQBcDtg4JAWXEZRKtvhdJ2g4L0XrdJ9bc98PETRU8=" data-language="html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>importmap<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript">
<span class="token punctuation">{</span>
<span class="token string-property property">"imports"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token string-property property">"square"</span><span class="token operator">:</span> <span class="token string">"./module/shapes/square.js"</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token string-property property">"scopes"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token string-property property">"/modules/customshapes/"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token string-property property">"square"</span><span class="token operator">:</span> <span class="token string">"https://example.com/modules/shapes/square.js"</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span>
</pre>
</div> <p> If multiple scopes match the referrer URL, then the most specific scope path is used (the scope key name with the longest name). The browser falls back to the next most specific scoped path if there is no matching specifier, and so on, eventually falling back to the module specifier map in the <code>imports</code> key. </p>
</div>
<h2 id="import_map_json_representation">Import map JSON representation</h2>
<div class="section-content">
<p>The following is a "formal" definition of the import map JSON representation.</p> <p>The import map must be a valid JSON object that can define at most two optional keys: <code>imports</code> and <code>scopes</code>. Each key's value must be an object, which may be empty.</p> <dl> <dt id="imports">
<a href="#imports"><code>imports</code></a> <span class="badge inline optional">Optional</span>
</dt> <dd> <p>The value is a <a href="#module_specifier_map">module specifier map</a>, which provides the mappings between module specifier text that might appear in an <code>import</code> statement or <code>import()</code> operator, and the text that will replace it when the specifier is resolved.</p> <p>This is the fallback map that is searched for matching module specifiers if no <code>scopes</code> path URLs match, or if module specifier maps in matching <code>scopes</code> paths do not contain a key that matches the module specifier.</p> <dl> <dt id="module_specifier_map"><a href="#module_specifier_map"><code><module specifier map></code></a></dt> <dd> <p>A "module specifier map" is a valid JSON object where the <em>keys</em> are text that may be present in the module specifier when importing a module, and the corresponding <em>values</em> are the URLs or paths that will replace this text when the module specifier is resolved to an address.</p> <p>The module specifier map JSON object has the following requirements:</p> <ul> <li>None of the keys may be empty.</li> <li>All of the values must be strings, defining either a valid absolute URL or a valid URL string that starts with <code>/</code>, <code>./</code>, or <code>../</code>.</li> <li> If a key ends with <code>/</code>, then the corresponding value must also end with <code>/</code>. A key with a trailing <code>/</code> can be used as a prefix for when mapping (or remapping) modules addresses. </li> <li>The object properties' ordering is irrelevant: if multiple keys can match the module specifier, the most specific key is used (in other words, a specifier "olive/branch/" would match before "olive/").</li> </ul> </dd> </dl> </dd> <dt id="scopes">
<a href="#scopes"><code>scopes</code></a> <span class="badge inline optional">Optional</span>
</dt> <dd> <p>Scopes define path-specific <a href="#module_specifier_map">module specifier maps</a>, allowing the choice of map to depend on the path of the code importing the module.</p> <p>The scopes object is a valid JSON object where each property is a <code><scope key></code>, which is an URL path, with a corresponding value that is a <code><module specifier map></code>.</p> <p> If the URL of a script importing a module matches a <code><scope key></code> path, then the <code><module specifier map></code> value associated with the key is checked for matching specifiers first. If there are multiple matching scope keys, then the value associated with the most specific/nested scope paths are checked for matching module specifiers first. The fallback module specifier map in <code>imports</code> is used if there are no matching module specifier keys in any of the matching scoped module specifier maps. </p> <p>Note that the scope does not change how an address is resolved; relative addresses are always resolved to the import map base URL.</p> </dd> </dl>
</div>
<h2 id="specifications">Specifications</h2>
<div class="_table"><table class="standard-table">
<thead><tr><th scope="col">Specification</th></tr></thead>
<tbody><tr><td><a href="https://html.spec.whatwg.org/multipage/webappapis.html#import-map">HTML Standard <br><small># import-map</small></a></td></tr></tbody>
</table></div>
<h2 id="browser_compatibility">Browser compatibility</h2>
<div class="_table"><table>
<thead>
<tr id="bct-browser-type">
<th></th>
<th colspan="6">Desktop</th>
<th colspan="6">Mobile</th>
</tr>
<tr id="bct-browsers">
<th></th>
<th>Chrome</th>
<th>Edge</th>
<th>Firefox</th>
<th>Internet Explorer</th>
<th>Opera</th>
<th>Safari</th>
<th>WebView Android</th>
<th>Chrome Android</th>
<th>Firefox for Android</th>
<th>Opera Android</th>
<th>Safari on IOS</th>
<th>Samsung Internet</th>
</tr>
</thead>
<tbody><tr>
<th><code>importmap</code></th>
<td class="bc-supports-yes">89</td>
<td class="bc-supports-yes">89</td>
<td class="bc-supports-yes">108</td>
<td class="bc-supports-no">No</td>
<td class="bc-supports-yes">75</td>
<td class="bc-supports-yes">16.4</td>
<td class="bc-supports-yes">89</td>
<td class="bc-supports-yes">89</td>
<td class="bc-supports-yes">108</td>
<td class="bc-supports-yes">63</td>
<td class="bc-supports-yes">16.4</td>
<td class="bc-supports-yes">15.0</td>
</tr></tbody>
</table></div>
<h2 id="see_also">See also</h2>
<div class="section-content"><ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#importing_modules_using_import_maps">JavaScript modules > Importing modules using import maps</a></li> <li><a href="../../script#type">The <code>type</code> attribute of HTML <code><script></code> elements</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import"><code>import</code> statement</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"><code>import()</code> operator</a></li> </ul></div><div class="_attribution">
<p class="_attribution-p">
© 2005–2023 MDN contributors.<br>Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.<br>
<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap" class="_attribution-link">https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap</a>
</p>
</div>
|