CommonJS模块不能直接在浏览器或现代构建工具中作为ES Module使用,需借助Babel(配合@babel/plugin-transform-commonjs)、esbuild(--format=esm)、Rollup(@rollup/plugin-commonjs)或Webpack等工具进行AST级转换,解决模块解析、导出重映射与循环依赖等问题,并支持package.json中"type": "module"或"exports"字段实现渐进式共存。

CommonJS 模块(如 Node.js 中的 require() / module.exports)不能直接在浏览器或现代构建工具中作为 ES Module(import/export)使用,需要借助工具进行语法转换和模块系统适配。核心不是“单纯改写语法”,而是解决模块解析、导出重映射、循环依赖处理等运行时差异。
用 Babel 转换语法 + 插件补全语义
Babel 本身不处理模块语义,需配合插件将 CommonJS 转为 ES Module 语法,并确保导出行为一致:
- 安装
@babel/plugin-transform-modules-commonjs(旧版)或更推荐的@babel/plugin-transform-modules-umd+ 手动配置目标为esmodule - 实际常用的是
@babel/preset-env配合modules: 'auto'(根据打包器自动选择),但若明确要输出 ESM,设modules: false可保留import/export,再用其他工具处理 CJS 依赖 - 注意:
module.exports = xxx会被转成export default xxx;而exports.xxx = yyy或多次赋值需靠@babel/plugin-transform-commonjs(专为 CJS 转 ESM 设计)智能合并为具名导出
用 esbuild 或 SWC 做快速构建级转换
现代打包器内置高效转换能力,无需手写 Babel 配置:
-
esbuild:通过
--format=esm+--platform=node(或browsers)自动把输入的 CJS 文件转为 ESM 输出,同时解析require()并重写为import,支持package.json中"type": "module"提示 -
SWC:配置
jsc.transform.legacyDecorator不相关,关键是启用module: { type: 'es6' },它对module.exports的处理比 Babel 更贴近 Node 实际行为,且速度更快 - 两者都默认处理
__dirname、__filename等 CJS 特有变量,可选注入兼容 polyfill 或替换成静态字符串
Rollup 或 Webpack 的 resolve + plugin 协同处理
在打包流程中,不一定要提前“转换源码”,而是让打包器动态识别并桥接两种模块:
立即学习“Java免费学习笔记(深入)”;
-
Rollup:搭配
@rollup/plugin-commonjs,它会分析 CJS 文件的exports模式,生成对应的export语句,甚至提取require('fs')等内置模块调用做空替换或 external 处理 -
Webpack:5.x+ 默认启用
experiments.topLevelAwait: true和自动 CJS/ESM 互操作,配合resolve.fullySpecified: true可强制把无后缀导入(如import x from 'lodash')按 ESM 解析;也可用externalsType: 'module'输出纯 ESM 包 - 关键点:这些工具不是“文本替换”,而是 AST 分析 + 导出图构建,能正确处理
exports.xxx = ...、Object.defineProperty(module.exports, ...)等动态导出模式
Node.js 原生支持下的渐进迁移策略
Node 14+ 已支持 ESM,但混合模块仍需约定:
- 在
package.json中声明"type": "module",则所有.js文件按 ESM 解析;CJS 文件需显式用.cjs后缀 - 若想让一个 CJS 包被 ESM 项目
import,可在其package.json中设置"exports"字段,例如:"exports": { ".": { "import": "./index.mjs", "require": "./index.cjs" } }
这样同一包可同时提供两种格式入口 - 临时兼容方案:用
createRequire(import.meta.url)在 ESM 文件里加载 CJS 模块,避免语法报错


















