import/export 模块与导出(含 CommonJS 互操作)
最后更新:2026-10-23
import/export 模块与导出(含 CommonJS 互操作)
ES Modules 是 JavaScript 官方的模块标准,TypeScript 完整沿用 export/import 语法,并把"类型"也纳入模块系统:类型可以导出导入,import type 只导入类型、编译后完全消失。桶文件(barrel,通常是 index.ts)集中再导出多个模块,让外部只需要一个导入入口。与 CommonJS 的互操作由 module / esModuleInterop 等编译选项决定。
| 分组 | 工程与实战 |
|---|---|
| 类型 | 语法 |
| 严格模式 | 不需要 |
ℹ️ 说明 编辑器将 TypeScript 转译为 JavaScript 后运行(不做类型检查);类型检查结果见示例 Output。
📝 语法
// 导出
export interface User { id: number; name: string } // 导出类型
export const add = (a: number, b: number) => a + b; // 导出值
export default function greet() {} // 默认导出
// 导入
import greet, { add } from "./math"; // 默认 + 具名
import type { User } from "./types"; // 仅类型,编译后消失
export * from "./math"; // 桶文件再导出
⚙️ 参数
| export default | 模块的"默认出口",每个模块最多一个;导入时可用任意名字且不加花括号 |
|---|---|
| export * from / re-export | 桶文件的核心写法:把子模块的全部具名导出转发出去,import type 的类型也会被转发 |
| import type / inline type | import type { User } 与 import { type User }(内联修饰符)等价,都声明"只导入类型",编译后不留任何运行时代码 |
返回值:模块本身无返回值;export 的值与类型共同构成模块的公共接口,供其他模块 import。
▶ 示例
修改下面的代码,点击试一试查看转译运行结果:
输出:
Hello, Ada!
add === add2: true
(转译后运行输出;本编辑器在浏览器内联脚本中运行,无法真正跨文件 import,因此上方用注释标出模块边界、以等价写法演示——真实项目中仍是 types.ts / math.ts / utils.ts / main.ts 四个独立文件,User 是纯类型,import type 编译后不留痕迹)
💡 要点
ℹ️ 说明 import type 与普通 import 导入同名类型的效果相同,但语义更明确且能配合 isolatedModules 安全使用;编译后两者导出的类型部分都会消失。
💡 提示 桶文件放 src 目录根(index.ts),内容只有一行行 export * from / export { x } from;好处是调用方写 @/utils 而不是 @/utils/math 这类深层路径,重构目录结构时只需改桶文件。
⚠️ 注意 与 CommonJS 互操作是重灾区:TS 编译出的 CJS 里 import default 与 module.exports 的对应关系容易出错,开启 esModuleInterop(配合 module: commonjs)后行为才与 ES 规范一致;module 设为 node16/nodenext 时还要求相对导入写全扩展名。
🏷️ 相关工程与实战
💡 相关案例
更多案例即将上线。
📚 相关教程
❓ 常见问题
Q import type 和普通 import 有什么区别?
A 普通 import 导入的内容可能被编译成 require 调用(哪怕你只用了它的类型);import type 保证只导入类型、绝不产生运行时代码。在 isolatedModules 或打包器 tree-shaking 场景下,用它可避免"只为类型而保留整包"的问题。
Q 什么时候值得建桶文件?
A 当一个目录对外暴露的模块多于三四个、且调用方经常同时导入其中多个时。注意桶文件会让所有子模块进入同一依赖图,可能影响打包器的 tree-shaking;纯工具库可以建,组件多、体积敏感的场景要评估。
Q 运行时报 "Cannot use import statement outside a module" 怎么回事?
A 运行环境不认识 ESM 语法:产物里的 import 没被转换(target 太新或 module 配置错),或 Node 把 .js 当 CJS 执行。解决:module 设为 commonjs(或打包器处理 ESM),ESM 文件用 .mjs 或在 package.json 里声明 "type": "module"。