You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Commander开发Node CLI遇ESM与CommonJS兼容错误求解决

解决Node CLI中ESM与CommonJS的冲突问题

1. 保留package.json的ESM配置

必须保留 "type": "module" —— 你依赖的chalk、Commander等目前多为纯ESM包,移除该配置会触发ERR_REQUIRE_ESM错误,这是无法绕过的。

2. 修正TypeScript配置(tsconfig.json)

按照Node 16官方规范调整TS编译参数,确保输出纯ESM格式,避免生成CommonJS的exports语法:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "NodeNext",
    "esModuleInterop": false,
    "skipLibCheck": true,
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "resolveJsonModule": true,
    "declaration": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

关键参数说明:

  • module: "ESNext" + moduleResolution: "NodeNext":确保TS编译输出完全符合Node ESM规范
  • 关闭esModuleInterop:ESM环境不需要这个CommonJS兼容选项,开启反而可能导致语法冲突

3. 修正桶文件(barrel)的导出语法

桶文件绝对不能使用CommonJS的module.exports,必须统一用ESM的export语法:
错误写法(会触发exports is not defined):

module.exports = {
  foo: require('./foo'),
  bar: require('./bar')
};

正确写法:

// 单个导出
export { default as foo } from './foo';
export { bar } from './bar';

// 或批量导出
export * from './foo';
export * from './bar';

4. 调整CLI入口的执行逻辑

在package.json中配置正确的bin字段,指向编译后的ESM入口文件:

{
  "type": "module",
  "bin": {
    "your-cli-name": "./dist/bin/cli.js"
  },
  "scripts": {
    "build": "tsc",
    "start": "node ./dist/bin/cli.js"
  }
}

开发阶段若要直接运行TS文件,建议使用tsx替代ts-node(ts-node对ESM的支持需要复杂配置):

npm install -D tsx

然后修改开发脚本:

"scripts": {
  "dev": "tsx ./src/bin/cli.ts"
}

5. 清理残留的CommonJS语法

全局检查所有源码文件,确保没有使用require()、module.exports、exports.xxx这类CommonJS语法,全部替换为ESM的import/export。


错误根源说明

  • 保留"type": "module"时触发ReferenceError:你的代码(大概率是桶文件)存在CommonJS导出语法,ESM环境不允许这类写法。
  • 移除"type": "module"时触发ERR_REQUIRE_ESM:chalk、Commander等依赖是纯ESM包,无法在CommonJS环境中用require()引入。

内容的提问来源于stack exchange,提问作者octavemirbeau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:21:49