<script type="module">
是 HTML 中用来加载 JavaScript ES Module(ESM) 的一种方式。它与传统的 <script>
标签不同,具有模块化、作用域隔离、支持 import/export
等特性。
JavaScript ES Module(ESM)
指的是 ECMAScript 6.0(ES6)引入的官方模块系统,它为 JavaScript 提供了标准化的模块导入 / 导出语法,解决了早期模块规范(如 CommonJS、AMD)的局限性。
一、基本用法
js
<script type="module">
import { sayHi } from './greetings.js';
sayHi('world');
</script>
或者
js
<script type="module" src="./main.js"></script>
二、 核心特性详解
1. 支持 import / export
ES Module 语法天生支持模块化,使用 import
引入模块,export
导出内容。
js
// greetings.js
export function sayHi(name) {
console.log(`Hi, ${name}!`);
}
// main.js
import { sayHi } from './greetings.js';
sayHi('ChatGPT');
2. 模块是默认严格模式(strict mode)
所有模块文件自动以 use strict
模式执行,不需要显式声明。
3. 模块代码是作用域隔离的
不像普通 <script>
,模块不会污染全局变量:
js
<script>
var foo = 123; // 全局变量
</script>
<script type="module">
var foo = 456; // 局部模块作用域,互不影响
</script>
4. 模块只加载一次(即使被多次引用)
- 普通
<script>
:✅ 每次遇到<script>
标签(或动态插入脚本),都会重新执行脚本内容,可能重复初始化逻辑。 <script type="module">
:✅ 模块脚本只执行一次,后续无论多少次引用(如重复import
同一模块),都复用首次执行的结果,避免重复初始化。
js
// a.js
console.log('Module A loaded');
export const a = 1;
即使多次 import './a.js'
,只执行一次。
5. 模块通过 CORS 加载
模块默认使用 CORS(跨源资源共享) 策略。跨域模块必须正确设置 Access-Control-Allow-Origin
,否则加载失败。
6. 模块加载是异步的
- 普通
<script>
:❌ 默认同步加载,会阻塞 HTML 解析渲染;需手动加defer
(按顺序异步执行)或async
(完全异步,不保证顺序)控制。 <script type="module">
:✅ 天生异步加载,不阻塞页面渲染,且多个模块脚本按在 HTML 中的顺序执行,兼顾性能与依赖顺序。
三、与默认 script 不同点对比
特性 | <script> (普通脚本) |
<script type="module"> (ES模块) |
---|---|---|
模块系统支持 | ❌ 不支持 import /export |
✅ 原生支持 ES6 模块语法 |
严格模式 | ❌ 默认非严格模式 | ✅ 自动启用严格模式 ('use strict' ) |
作用域 | ❌ 变量挂载到全局作用域 (window ) |
✅ 独立作用域,不污染全局 |
加载顺序 | ❌ 同步加载,阻塞 HTML 解析 | ✅ 异步加载,不阻塞页面渲染 |
执行顺序 | ❌ 按加载完成顺序执行 | ✅ 按在 HTML 中出现的顺序执行 |
重复执行 | ✅ 每次加载都会重新执行 | ✅ 模块只执行一次,后续复用结果 |
路径要求 | ❌ 相对路径可省略扩展名 | ✅ 必须使用完整路径(如 ./module.js ) |
兼容性 | ✅ 所有浏览器支持 | ✅ 现代浏览器支持(IE 不支持) |
四、注意点
1 本地模块加载
js
<script type="module" src="./main.js"></script>
注意路径需要以 ./
或 /
开头,不能省略(不能直接写 main.js
)。