欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 谈谈 TypeScript 中的模块系统,如何使用 ES Modules 和 CommonJS 模块?

谈谈 TypeScript 中的模块系统,如何使用 ES Modules 和 CommonJS 模块?

2025/3/19 14:00:57 来源:https://blog.csdn.net/liangzai215/article/details/146354694  浏览:    关键词:谈谈 TypeScript 中的模块系统,如何使用 ES Modules 和 CommonJS 模块?

模块系统是 TypeScript 项目组织代码的核心机制,主要用于代码拆分、复用和依赖管理。

TypeScript 支持 ​ES Modules(ESM)​ 和 ​CommonJS 两种主流模块系统,理解它们的差异和使用场景是前端开发中的必备技能。

以下从基础语法、配置、互操作性到实战建议展开说明。


一、ES Modules(ESM):标准化的模块系统

1. 基础语法
ESM 使用 import/export 语法,是 ECMAScript 官方标准,适用于现代浏览器和 Node.js(需配置)。

// math.ts
// 具名导出
export const add = (a: number, b: number): number => a + b;
// 默认导出
export default function subtract(a: number, b: number): number {return a - b;
}// app.ts
import { add } from './math.js';  // 导入具名导出(注意编译后路径)
import subtract from './math.js'; // 导入默认导出console.log(add(1, 2));      // 3
console.log(subtract(5, 3)); // 2

关键点

  • 导入路径需明确文件扩展名(如 .js),因编译后代码为 JS。
  • 默认导出和具名导出需区分使用(影响导入语法)。

二、CommonJS:Node.js 的传统模块系统

1. 基础语法
CommonJS 使用 require/module.exports,常见于 Node.js 环境。

// math.ts
// 具名导出
exports.add = (a: number, b: number): number => a + b;
// 默认导出(需特殊处理)
export default function subtract(a: number, b: number): number {return a - b;
}// app.ts
const math = require('./math'); // 导入整个模块
const { add } = require('./math'); // 解构具名导出
const subtract = require('./math').default; // 导入默认导出(需配置支持)console.log(add(1, 2));      // 3
console.log(subtract(5, 3)); // 2

关键点

  • 默认导出需通过 module.exports 或 exports.default 处理。
  • 直接使用 require 可能导致类型丢失,需配合 TypeScript 类型声明。

三、配置 TypeScript 模块解析

1. tsconfig.json 核心配置项

  • module: 指定编译后的模块系统(如 "ES6" 或 "CommonJS")。
  • esModuleInterop: 允许 ESM 和 CommonJS 的互操作性(建议开启)。
  • allowSyntheticDefaultImports: 兼容无默认导出的模块。
{"compilerOptions": {"module": "ES6","esModuleInterop": true,"allowSyntheticDefaultImports": true}
}

四、模块互操作性:混用 ESM 和 CommonJS

1. 在 ESM 中导入 CommonJS 模块
需开启 esModuleInterop,TypeScript 会自动处理兼容。

// 导入 CommonJS 模块(如 lodash)
import _ from 'lodash'; // 默认导入(esModuleInterop 生效)
import * as lodash from 'lodash'; // 命名空间导入(无 esModuleInterop 时)

2. 在 CommonJS 中导入 ESM 模块
需使用动态 import() 或编译为 CommonJS 格式。

// 动态导入(Node.js 环境)
const math = await import('./math.js');
console.log(math.add(1, 2));

五、实战建议与避坑指南

1. 统一模块系统

  • 新项目优先使用 ​ESM,尤其是前端项目或 Node.js 新版本。
  • 旧项目沿用 ​CommonJS,避免混用导致编译后代码混乱。

2. 第三方库兼容性

  • 检查库的模块格式:
    • ESM 库通常包含 "type": "module"
    • CommonJS 库可能需 @types/xxx 补充类型。

3. 默认导出陷阱

  • CommonJS 默认导出需显式声明:
// 错误:默认导出未正确处理
module.exports = { add, subtract };
// 正确:需通过 default 或 esModuleInterop
export default { add, subtract };

4. 路径与扩展名

  • ESM 严格依赖完整路径(如 './math.js'),CommonJS 可省略扩展名。
  • TypeScript 编译时自动处理路径,但需确保运行时路径正确。

5. 循环依赖

  • 避免模块 A 导入 B,同时 B 导入 A,可能导致未定义行为。
  • 重构代码或使用延迟加载(如函数内导入)。

六、总结

TypeScript 的模块系统选择需结合项目环境:

  • 前端项目/现代 Node.js:ESM 是未来趋势,配合 esModuleInterop 实现平滑迁移。
  • 传统 Node.js 项目:CommonJS 更稳定,注意默认导出的兼容性处理。

核心配置建议

  • 开启 esModuleInterop 和 allowSyntheticDefaultImports
  • 模块路径统一使用相对路径,避免运行时错误。

通过合理配置和规范使用,可高效管理代码依赖,避免常见的模块陷阱。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词