type="importmap"
和 type="module"
不是严格意义上的“成对出现”,但它们需要配合使用才能发挥完整作用,同时也可以分开使用(需满足特定条件)。以下是详细分析:
1. 二者关系解析
-
<script type="module">
声明脚本为 ES 模块,支持import/export
语法(现代浏览器必备)。 -
<script type="importmap">
定义模块路径映射(将裸模块名如"lodash"
映射到具体 URL),必须配合模块脚本才能生效。
2. 能否分开使用?
✅ 情况1:单独使用 type="module"
(无需 type="importmap"
)
<!-- 直接使用绝对/相对路径导入模块 -->
<script type="module">
import utils from '/path/to/utils.js'; // ✅ 有效
</script>
结论:type="module"
可独立工作,不依赖 type="importmap"
。
✅ 情况2:单独使用 type="importmap"
(但需有模块脚本)
<!-- 定义 importmap -->
<script type="importmap">
{
"imports": {
"lodash": "https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"
}
}
</script>
<!-- 没有模块脚本时,importmap 无作用(但不会报错) -->
<script>
console.log("普通脚本无法使用 importmap");
</script>
结论:type="importmap"
可单独存在,但必须与后续的模块脚本配合才能生效。若无模块脚本,它会被忽略。
❌ 无效情况:type="importmap"
在模块脚本之后
<script type="module">
import lodash from 'lodash'; // ❌ 报错:找不到模块
</script>
<!-- importmap 必须在模块脚本之前! -->
<script type="importmap">
{ "imports": { "lodash": "..." } }
</script>
结论:type="importmap"
必须出现在所有模块脚本之前,否则映射失效。
3. 正确配合使用方式
<!-- 1. 先定义 importmap -->
<script type="importmap">
{
"imports": {
"moment": "/node_modules/moment/moment.js"
}
}
</script>
<!-- 2. 再使用模块脚本 -->
<script type="module">
import moment from 'moment'; // ✅ 根据 importmap 解析路径
console.log(moment().format());
</script>
4. 其他注意事项
-
一个页面只能有一个
type="importmap"
:重复定义会被忽略(规范要求)。 -
动态 import 支持:
type="importmap"
也适用于动态导入:const module = await import('my-module'); // 依赖 importmap 映射
-
浏览器兼容性:
type="importmap"
在 Chrome 89+、Edge 89+、Firefox 108+ 支持,Safari 16.4+ 支持。
结论
-
可以分开使用:
type="module"
可独立工作;type="importmap"
需模块脚本配合(且顺序在前)。 -
最佳实践:二者配合实现裸模块导入,但需严格保证
type="importmap"
定义在所有模块脚本之前。
延申
由此可以理解Vue官方文档中的的两种框架导入方式:
✅ 情况1:单独使用 type="module"
(无需 type="importmap"
)
<div id="app">{{ message }}</div>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
✅ 情况2:配合使用 type="module"和
type="importmap"
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
}
}
</script>
<div id="app">{{ message }}</div>
<script type="module">
import { createApp } from 'vue'
createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>