是否可以通过require引入仅支持ESM格式的Node.js依赖包?
解决方案
可以实现CommonJS环境下引入仅支持ESM的包,共有以下几种可行方案:
方案1:使用原生异步import()加载(官方推荐)
Node.js 14.13.0及以上版本支持在CommonJS文件中调用import()异步方法加载ESM模块,不需要额外安装依赖,示例代码如下:
// 你的CommonJS脚本文件 async function useEsmPackage() { // 动态引入ESM包 const esmPackage = await import('目标ESM包名'); // 如果包导出的是default内容,取esmPackage.default即可 console.log(esmPackage.default) // 后续业务逻辑写在这里 } useEsmPackage()
如果你的上层逻辑支持异步改造,优先选择该方案。
方案2:使用esm加载器实现同步require
如果不想修改原有代码的同步逻辑,可以引入第三方加载器esm做兼容:
- 安装依赖:
npm install esm - 运行脚本时添加加载器参数:
node -r esm 你的脚本文件名.js
无需修改原有业务代码中的require语句,即可直接加载ESM包。
方案3:转译ESM包为CommonJS格式
如果需要完全脱离额外运行时参数,可以通过转译工具将目标ESM包预编译为CommonJS格式,以esbuild为例:
- 安装esbuild:
npm install esbuild -D - 执行转译命令:
esbuild node_modules/<目标ESM包名>/index.js --bundle --platform=node --format=cjs --outfile=./lib/<包名>.cjs
- 代码中直接引入转译后的文件:
const esmPkg = require('./lib/<包名>.cjs')
该方案适合对性能要求高、不想引入额外加载器的场景,注意如果ESM包存在嵌套ESM依赖,需要将所有依赖都纳入转译范围。
注意事项
- 所有方案都要求Node.js版本不低于14.13.0,低版本Node.js对ESM的原生支持存在缺陷,优先升级到LTS版本再操作
- 避免修改第三方包内部的package.json配置强制声明为CommonJS,可能会导致包内部逻辑异常
内容的提问来源于stack exchange,提问作者komoday
相关产品推荐
相关产品推荐

