如何通过Babel或Webpack在ES6模块中使用Node.js CommonJS模块
CommonJS模块完全可以转译适配ES模块项目,你遇到的Uncaught TypeError: Cannot assign to read only property 'exports' of object错误,本质是Babel将你的CommonJS格式配置文件判定为ES模块,ES模块规范下exports、module.exports为只读属性,赋值操作就会触发报错。
可行解决方案
方案1:调整Babel预设配置(最推荐,全局兼容所有CommonJS文件)
修改你的babelrc.js中@babel/preset-env的配置,增加sourceType: 'unambiguous'参数,Babel会自动根据文件内容判断模块类型:
module.exports = { presets: [ // 修改这里的@babel/preset-env配置 ['@babel/preset-env', { sourceType: 'unambiguous', modules: 'auto' }], '@babel/preset-react' ], // 剩下的原有配置保持不变 plugins: [ ['@babel/plugin-proposal-class-properties', { loose: true }], ['@babel/plugin-transform-runtime', { regenerator: true }], '@babel/plugin-syntax-dynamic-import', '@babel/plugin-proposal-optional-chaining' ], env: { production: { plugins: [ [ "transform-react-remove-prop-types", { removeImport: true } ], ] } } }
方案2:修改配置文件后缀
将你的CommonJS格式配置文件后缀从.js改为.cjs,Babel和Webpack会自动将.cjs后缀文件识别为CommonJS模块,不需要修改其他配置,导入时正常写import config from './xxx.cjs'即可。
方案3:排除配置文件的Babel转译
Webpack原生支持CommonJS模块导入,你可以把该配置文件加入babel-loader的排除规则,跳过Babel处理即可:
{ test: /\.(js|jsx)$/, // 替换为你的配置文件实际路径 exclude: [/node_modules/, /path\/to\/your\/config.js/], use: [ { loader: 'babel-loader', options: { cacheDirectory: true, cacheCompression: false, envName: isModeProduction ? 'production' : 'development' } } ] }
方案4:手动转换配置文件为ES模块格式
如果你可以修改配置文件的代码,直接将导出语法替换为ES模块语法即可彻底解决问题:
- 原CommonJS写法:
module.exports = { xxx }替换为export default { xxx } - 若有单独导出:
exports.aaa = bbb替换为export const aaa = bbb
如果需要批量转译大量CommonJS文件为ES模块格式,也可以使用对应的命令行转换工具完成批量操作。
内容的提问来源于stack exchange,提问作者sgarcia.dev
相关产品推荐
相关产品推荐

