首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么babel-加载程序会失败,但是babel节点可以很好地混合ES、导入和CJ模块?

为什么babel-加载程序会失败,但是babel节点可以很好地混合ES、导入和CJ模块?
EN

Stack Overflow用户
提问于 2021-08-12 11:51:17
回答 1查看 491关注 0票数 1

我的项目中有使用CJS require和ES import语法的文件,如下所示:

代码语言:javascript
复制
const multer = require('multer');
import multerS3 from './multer-s3-storage-engine.js';
const ExpressRouter = require('express').Router();
....
....
module.exports = ExpressRouter;

我知道我们不应该把这些混为一谈,但我认为这就是babel的目的,就是把所有的东西都转移到工作中去。

在开发中,我使用babel-node启动dev版本,如下所示:

代码语言:javascript
复制
"dev": "babel-node -r dotenv/config src/server.js"

上面的工作正常,我所有的混合CJS和ES文件工作。然而,当谈到生产建设时,Webpack失败了,并抛出了这个错误:

代码语言:javascript
复制
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: 262

262指的是上面代码中的module.exports = ExpressRouter;部分。

构建的Webpack 5配置文件如下所示:

代码语言:javascript
复制
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中,我还有以下配置:

代码语言:javascript
复制
 "babel": {
    "presets": [
      "@babel/preset-env"
    ],
    "sourceType": "unambiguous"
  }

为什么它适用于babel-node而不是babel-loader

EN

回答 1

Stack Overflow用户

发布于 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似乎可以提取importexport语句并将它们转换为其他语法,如requiremodule.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为模块类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68756951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档