如何让TypeScript编译器输出import而非require的代码适配Node.js
解决TypeScript编译后Node.js ESM兼容问题(ERR_REQUIRE_ESM/exports未定义)
你的问题核心是TypeScript默认编译输出CommonJS格式代码,但Node.js v20结合"type": "module"时要求ESM格式,导致语法冲突。以下是正式解决方案:
1. 创建并配置tsconfig.json
TypeScript默认输出CommonJS,必须显式配置让它生成ESM代码。在项目根目录创建tsconfig.json,添加以下配置:
{ "compilerOptions": { "module": "NodeNext", // 匹配Node.js的ESM模块系统 "moduleResolution": "NodeNext", // 对应Node.js的模块解析规则 "target": "ES2020", // 适配Node.js v20支持的JS版本 "outDir": "./dist", // 可选,指定编译输出目录 "strict": true // 可选,开启严格类型检查 }, "include": ["**/*.ts"] // 匹配所有TS文件,可根据实际路径调整 }
2. 正确配置package.json
保留"type": "module",同时添加编译/运行脚本:
{ "type": "module", "scripts": { "build": "tsc", "start": "node dist/your-entry-file.js" } }
3. 验证编译结果
执行npm run build后,检查dist目录下的.js文件:
- 导入语句应为
import remark from 'remark'而非const remark = require('remark') - 导出语句应为
export default ...而非module.exports = ...
为什么之前的尝试无效?
- 仅添加
"type": "module"到package.json时,TypeScript仍按默认配置输出CommonJS代码,Node.js把这些.js文件当作ESM处理,自然会报exports未定义的错误 - 改
.ts为.mts是临时方案,因为TypeScript对.mts文件默认按ESM编译输出.mjs,但全局配置tsconfig.json能统一管理所有TS文件的编译规则
额外注意事项
- 若依赖的第三方模块是CommonJS格式,Node.js v20会自动兼容,无需额外处理
- 若需编译为更通用的ESM格式,可将
module设为ESNext,但NodeNext更贴合Node.js的实际模块行为
内容的提问来源于stack exchange,提问作者Att Righ
相关产品推荐
相关产品推荐

