如何用ts-node搭建兼容ESM与CommonJS的TypeScript项目?
最佳方案:基于ts-node配置实现需求
不用从零搭建环境,ts-node配合针对性配置就能完全覆盖你的所有要求,以下是具体实现步骤:
1. 初始化项目并安装依赖
先初始化npm项目,安装核心工具依赖:
npm init -y npm install typescript ts-node @types/node @esbuild-kit/cjs-loader --save-dev
2. 配置package.json
- 设置
type: "module"启用ESM语法支持 - 添加启动脚本,通过双加载器同时兼容ESM和CommonJS模块
{ "type": "module", "scripts": { "start": "ts-node --loader ts-node/esm --loader @esbuild-kit/cjs-loader ./index.ts" } }
其中@esbuild-kit/cjs-loader专门解决type: module环境下无法导入CommonJS模块的问题。
3. 配置tsconfig.json
创建tsconfig.json,开启ESM解析规则并禁用编译输出:
{ "compilerOptions": { "target": "ESNext", "module": "ESNext", "moduleResolution": "NodeNext", "esModuleInterop": true, "skipLibCheck": true, "strict": true, "noEmit": true, // 关键:执行时不生成任何编译文件 "allowSyntheticDefaultImports": true }, "include": ["**/*.ts"] }
noEmit: true确保代码完全在内存中编译执行,不会生成dist或其他输出文件moduleResolution: NodeNext让TypeScript自动识别并兼容ESM/CommonJS模块的导入规则esModuleInterop: true自动处理CommonJS模块的默认导入兼容(比如import lodash from 'lodash')
4. 功能验证
完成配置后,你可以:
- 用纯ESM语法编写TypeScript源码(如
import foo from './utils.ts') - 直接导入用
module.exports = ...导出的CommonJS第三方模块 - 导入用
export default { ... }导出的ESM模块 - 执行
npm start直接运行index.ts,全程无额外文件生成 - 无需使用
.mjs扩展名
替代方案:esbuild(追求更高性能)
如果ts-node的编译速度无法满足需求,可以用esbuild替代,它支持内存编译且性能远超ts-node:
安装依赖:
npm install esbuild typescript --save-dev
package.json添加启动脚本(临时文件自动清理):
{ "type": "module", "scripts": { "start": "esbuild --bundle ./index.ts --platform=node --format=esm --outfile=./temp.js && node ./temp.js && rm ./temp.js" } }
该方案会临时生成一个temp.js文件,执行后自动删除,同样满足不保留输出文件的要求。
内容的提问来源于stack exchange,提问作者johann1301s
相关产品推荐
相关产品推荐

