692 字
3 分钟
11 · 模块与命名空间
NOTE模块化是现代 JS/TS 的基石。本篇讲清 ES Module 在 TS 里的写法、模块解析规则,以及为什么
namespace基本被淘汰。
1. 导出 export
export const PI = 3.14;export function square(n: number): number { return n * n; }export interface Point { x: number; y: number }
// 或集中导出const add = (a: number, b: number) => a + b;export { add };类型(interface/type)也能 export,编译后会被擦除,只用于类型检查。
2. 导入 import
import { PI, square, type Point } from "./math";import * as MathUtils from "./math"; // 命名空间式导入import defaultExport from "./mod"; // 默认导入用 type 前缀(或 import type)只导入类型,配合 isolatedModules 更安全、且不会被编译进 JS:
import type { Point } from "./math"; // 纯类型,编译后整行消失3. 默认导出 vs 命名导出
| 默认导出 | 命名导出 | |
|---|---|---|
| 写法 | export default | export const/function |
| 导入 | 任意名字 | 必须同名(可重命名) |
| 数量 | 每文件一个 | 多个 |
| 推荐 | 一个文件一个主产物时用 | 多数情况更推荐 |
推荐命名导出:可静态分析、重构友好、IDE 补全好。默认导出适合”一个模块一个类/函数”的场景。
4. 重命名与聚合
import { square as sq } from "./math"; // 导入时改名export { square as pow2 } from "./math"; // 重新导出
// 聚合多个模块export * from "./math";export * from "./string";5. 动态 import()
运行时按需加载,返回 Promise:
button.onclick = async () => { const { heavyCalc } = await import("./heavy"); heavyCalc();};动态 import() 让代码分割/懒加载成为可能,是前端性能优化关键点。
6. 模块解析 moduleResolution
tsconfig 的 moduleResolution 决定 TS 怎么找模块:
{ "module": "ESNext", "moduleResolution": "Bundler" // 或 Node / Node16 / NodeNext}Node/NodeNext:模拟 Node 的node_modules解析,需写扩展名(NodeNext 要求)。Bundler:给 Vite/webpack 等打包器用,不用写.js扩展名,最省心(现代前端首选)。
路径别名也要在此生效:
{ "baseUrl": ".", "paths": { "@/*": ["src/*"] }}7. namespace(遗留,谨慎)
TS 早期用 namespace 做全局命名隔离:
namespace Geometry { export function area(r: number) { return Math.PI * r * r; }}Geometry.area(1);但在 ES Module 时代,几乎不再需要 namespace——文件即模块,用 export/import 即可。仅维护老代码时可能遇到,新项目请直接用 ES Module。
小结
export/import是模块标准;import type只导类型,编译后消失。- 优先命名导出(可分析、可重构)。
- 动态
import()实现懒加载。 moduleResolution选Bundler(前端)或NodeNext(Node)。namespace是旧时代产物,新项目用 ES Module 替代。
练习
- 建
string.ts导出capitalize与truncate,在main.ts用命名导入调用。 - 把上题改成默认导出一个对象,再改回命名导出,体会差异。
- 配置
paths别名@/* -> src/*,用import { x } from "@/utils"验证。 - 用动态
import()在按钮点击时加载一个含大函数模块。