Node 10中无需Babel将ESM导入CJS的正确方式
在Node.js 10环境下CJS导入ESM的正确方式
Node.js 10对ESM(.mjs)的支持还处于实验性阶段,而且原生环境下CJS(.js)和ESM的互操作有严格限制——CJS模块不能直接用require加载.mjs,也没有原生的import()函数可以异步导入ESM,这就是你触发「Not supported」错误的核心原因(你在CJS里用了ESM专属的await import()语法,Node 10的CJS环境根本不识别这个)。
下面给你两种不依赖Babel的可行方案:
方案一:用第三方库esm实现互操作
esm是一个轻量的模块加载器,能让Node.js在CJS环境中直接加载ESM,不需要大幅修改现有代码结构:
- 先安装依赖:
npm install esm --save - 启动你的Node应用时,加上
-r esm参数来注入加载器:node -r esm your-cjs-file.js - 之后在你的CJS代码里,就可以用
require加载.mjs文件了:const fs = require('fs'); const path = require('path'); const commandFiles = fs.readdirSync(folderPath); for (const file of commandFiles) { // 加载ESM模块,默认导出会被映射到module.exports.default const commandModule = require(path.join(folderPath, file)); const command = commandModule.default; // 获取ESM的默认导出 // 这里处理你的command逻辑 }
方案二:将CJS转为ESM(更原生的方式)
如果可以调整你的模块类型,把CJS文件改成ESM(重命名为.mjs),就能用Node 10的实验性ESM支持来动态导入:
- 把你的
.js文件改成.mjs,代码调整为ESM语法:import fs from 'fs'; import path from 'path'; const commandFiles = fs.readdirSync(folderPath); for (const file of commandFiles) { // 用动态import()加载ESM模块,这在Node 10的实验性ESM中是支持的 const commandModule = await import(path.join(folderPath, file)); const command = commandModule.default; // 处理command逻辑 } - 启动时必须加上
--experimental-modulesflag:node --experimental-modules your-esm-file.mjs
注意:Node 10的ESM支持有不少细节坑,比如文件路径必须完整(不能省略.mjs后缀),部分内置模块的导入方式也有差异,如果你选择方案二,建议多测试场景细节。
内容的提问来源于stack exchange,提问作者IDS
相关产品推荐
相关产品推荐

