开发npm工具时ES模块与CommonJS语法冲突的解决方法咨询
解决ESM与CommonJS在CLI入口的冲突问题
这里有三种实用方案可以解决你的冲突:
方案一:将CLI入口改为ESM格式
直接把.bin/cli.js的require替换成ESM的import语法,因为你的package.json已经设置了"type": "module",Node.js会把这个文件当作ESM处理:
#!/usr/bin/env node import '../dist/index.js';
同时确保TypeScript编译输出的是ESM,在tsconfig.json里配置:
{ "compilerOptions": { "module": "ESNext", "moduleResolution": "NodeNext", "target": "ES2020", "outDir": "./dist" } }
这个方案最贴合你整体的ESM配置,没有额外的兼容成本。
方案二:给CLI文件单独指定CommonJS模式
Node.js允许通过文件扩展名区分模块类型,把.bin/cli.js重命名为.bin/cli.cjs,这样Node.js会自动把它当作CommonJS处理,原有的require写法可以保留:
#!/usr/bin/env node require('../dist/index.js')
记得在package.json的bin字段里更新路径:
{ "bin": { "your-cli-name": "./.bin/cli.cjs" } }
这个方案适合不想修改原有CLI入口代码的场景。
方案三:用动态import()兼容两种模式
如果不想改扩展名或入口语法,用动态import()替代require,它在CommonJS和ESM环境下都能正常工作:
#!/usr/bin/env node import('../dist/index.js').catch(err => { console.error('加载CLI模块失败:', err); process.exit(1); });
注意动态import是异步的,不过CLI脚本里这种写法完全够用,不需要额外调整编译配置。
内容的提问来源于stack exchange,提问作者Lina Gong
相关产品推荐
相关产品推荐

