模块化:import / export
模块让代码组织清晰、依赖显式、便于复用与打包。
javascript
// math.js
export function add(a, b) {
return a + b;
}
export const PI = 3.14159;
// main.js
import { add, PI } from "./math.js";
console.log(add(2, 3), PI);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
注意:
- 使用相对路径或别名路径;
- 在浏览器中需配合构建工具或设置
type="module"
; - 默认导出:
export default
,导入使用自定义名称。
命名导出 vs 默认导出
javascript
// utils.js
export function clamp(x, min, max) {
return Math.min(max, Math.max(min, x));
}
export const EPS = 1e-6;
export default function lerp(a, b, t) {
return a + (b - a) * t;
}
// main.js
import lerp, { clamp, EPS } from "./utils.js";
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
要点:
- 默认导出每个模块仅一个;导入时可自定义名称。
- 命名导出可有多个;必须用相同名称导入(或
as
重命名)。
重导出与命名空间导入
javascript
// math/index.js
export { add } from "./add.js";
export { sub as minus } from "./sub.js";
export * from "./vector.js";
// 统一导入
import * as MathX from "./math/index.js";
console.log(MathX.add(1, 2), MathX.minus(3, 1));
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
模块作用域与“实时绑定”(live bindings)
- 模块顶层即模块作用域,默认是严格模式;
- 导出的是“绑定”而非值的快照:如果导出变量在模块内改变,导入方读取到的新值会更新。
javascript
// counter.js
export let count = 0;
export function inc() {
count++;
}
// app.js
import { count, inc } from "./counter.js";
console.log(count); // 0
inc();
console.log(count); // 1(live binding)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
浏览器中使用 ESM 与打包工具
浏览器:
- 需
<script type="module" src="/main.js"></script>
; - 路径需要带扩展名(如
./utils.js
); - 同源策略与 CORS 需正确配置。
打包工具(Vite/Webpack/Rollup):
- 支持别名路径、按需编译转译、Polyfill;
- 生产构建会做代码分割、压缩与缓存优化。
Tree-shaking 提示
- 使用 ESM 静态导入(
import { x } from
)有利于摇树优化; - 避免在导入后通过对象聚合暴露所有方法(影响静态分析);
- 导出未使用的符号会在生产构建中被移除(取决于工具配置)。
常见陷阱
- 在浏览器直接使用相对路径但遗漏
.js
扩展名会 404; - 循环依赖可能导致导入为
undefined
或部分初始化,需拆分依赖; - 默认导出与命名导出混淆,导致导入写法出错;
- 在 Node 中使用 ESM 需设置
"type": "module"
或使用.mjs
扩展名(取决于环境)。
最佳实践
- 一个模块只承担一个清晰职责;
- 优先使用命名导出,默认导出保留给模块“主功能”;
- 统一导出入口(index.js)收敛对外 API;
- 在大型项目中配合 TS/ESLint 做导出/导入检查。
练习
- 将分散在多个文件的工具函数重构为
utils/
模块目录,并通过utils/index.js
统一导出。 - 编写一个
counter
模块并在多个导入方中共享(验证 live binding)。 - 在浏览器使用
type="module"
引用模块,体验路径与 CORS 要求。