我的项目中有使用CJS require和ES import语法的文件,如下所示:
const multer = require('multer');
import multerS3 from './multer-s3-storage-engine.js';
const ExpressRouter = require('express').Router();
....
....
module.exports = ExpressRouter;我知道我们不应该把这些混为一谈,但我认为这就是babel的目的,就是把所有的东西都转移到工作中去。
在开发中,我使用babel-node启动dev版本,如下所示:
"dev": "babel-node -r dotenv/config src/server.js"上面的工作正常,我所有的混合CJS和ES文件工作。然而,当谈到生产建设时,Webpack失败了,并抛出了这个错误:
throw new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);
Error: ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: 262262指的是上面代码中的module.exports = ExpressRouter;部分。
构建的Webpack 5配置文件如下所示:
const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals');
const utils = require('./utils');
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
entry: {
server: utils.resolve('/src/server.js')
},
target: 'node',
// This tells the server bundle to use Node-style exports
output: {
path: utils.resolve('/dist'),
filename: '[name].js',
sourceMapFilename: isProduction ? '[name].[hash].js.map' : '[name].js.map',
libraryTarget: 'commonjs2'
},
node: {
// Need this when working with express, otherwise the build fails
__dirname: false,
__filename: false,
},
externals: nodeExternals({
allowlist: [
/^vue-meta*/,
/\.(css|sass|scss|vue|html)$/,
]
}),
optimization: {
minimize: isProduction ? true : false,
minimizer:[
(compiler) => ({
terserOptions: {
compress: {drop_console: isProduction ? true : false},
format: {
comments: isProduction ? false : true
},
}
})
]
},
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.m?jsx?$/,
exclude: ['/node_modules/', /\bcore-js\b/, /\bwebpack\/buildin\b/, /@babel\/runtime-corejs3/],
use: {
loader: 'babel-loader',
options: {
babelrc: false,
sourceType: "unambiguous",
presets: [
["@babel/preset-env", {
modules: false,
corejs: {
version: "3.9.0",
proposals: true
},
}
]
],
}
}
},
]
}
};在package.json中,我还有以下配置:
"babel": {
"presets": [
"@babel/preset-env"
],
"sourceType": "unambiguous"
}为什么它适用于babel-node而不是babel-loader?
发布于 2022-07-29 17:14:21
原因似乎是这个modules: false设置的@babel/preset-env,虽然默认值"auto“会产生同样的错误,但选择modules: 'commonjs'解决了问题。
让我们深入研究一下这个https://babeljs.io/docs/en/babel-preset-env#modules
允许将ES模块的语法转换为另一种模块类型。请注意,cjs只是公共cjs的别名。
关键是它从ES模块转换为其他模块(transpiles,现代的,兼容的)
因此,Babel似乎可以提取import和export语句并将它们转换为其他语法,如require和module.exports,但是它不能做相反的事情,比如将这个module.exports = ExpressRouter;语句转换为export default ExpressRouter; --它只能保留原始代码。
如果您正在寻找一个解决方案,这取决于您需要什么,如果您确实希望输出es6模块(因此是modules: false),那么您似乎必须摆脱module.exports语句,或者尝试找到一个把公共插件转换为es6的babel插件。
否则,您可以切换到另一个模块输出,如umd (通用模块定义)或commonjs
您的目标似乎是Node和一个commonjs输出(libraryTarget:'commonjs2'),您也有这样的注释:// Transpiles ES6-8 into ES5,因此您可能可以指定commonjs为模块类型。
https://stackoverflow.com/questions/68756951
复制相似问题