【问题标题】:How to remove arrow functions from webpack output如何从 webpack 输出中删除箭头函数
【发布时间】:2021-12-27 02:57:48
【问题描述】:

通过 webpack 运行我的代码后,它包含箭头函数。我需要代码在 ie11 中工作,所以我需要摆脱箭头函数。

我正在对所有 .js 文件使用 babel-loader。

我写了一个加载器来检查箭头函数的代码,并在 babel-loader 之后运行它并且没有得到任何箭头函数,所以我知道 babel 的输出是好的。

我也尝试过 babel-polyfill 和用于转换箭头功能的 babel 插件。

据我所知,babel-loader 输出的代码不错,我怀疑它可能是一个插件,但我不能只禁用它们进行测试,因为这会破坏构建。

开发中使用的Webpack插件:

  plugins: [
    new webpack.DefinePlugin({
      'process.env': require('../config/dev.env')
    }),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
    new webpack.NoEmitOnErrorsPlugin(),
    // https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    }),
    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.dev.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ]

问题也出现在 prod 中,但是在 dev 中修复它应该告诉我如何在 prod 中修复它。

我不知道箭头函数可能来自其他任何地方,所以我希望从本质上获得适用于 ie11 的代码,但是有箭头函数来自某个地方,所以它不起作用。

这不是我的代码,所以我不能全部发布。但是,我可以发布相关的 sn-ps,但我不知道问题出在哪里,所以我还不知道什么是相关的。

【问题讨论】:

    标签: javascript webpack internet-explorer-11 babeljs arrow-functions


    【解决方案1】:

    我遇到了同样的问题,找到了原因和解决办法。

    原因

    babel-loader 将 es6 及更高版本的语法转换为 es5。但是,由于转换是由 loader 完成的,因此转换仅发生在捆绑之前的每个文件中。 loader 完成转换后,webpack 开始打包。然而,webpack 在打包文件时并不关心 babel-loader 的目标版本。它只是将文件与其默认 ECMA 版本(可能是 es6 或更高版本)的语法捆绑在一起。这就是为什么捆绑结果包含箭头函数等es6语法的原因。

    初始步骤

    • file1 (es6)
    • file2 (es6)
    • file3 (es6)

    加载器工作后

    • file1' (es5)
    • file2' (es5)
    • file3' (es5)

    webpack 打包文件后

    • 捆绑文件 (es6)

    解决方案

    您只需在 webpack.config.js 中添加 target: "es5" 即可处理此问题。之后,webpack 以 es5 的语法打包文件

    // .babelrc
    {
      "presets": ["@babel/preset-env"]
    }
    
    // webpack.config.js
    module: {
       ...
       target: "es5", // include this!!
       loaders: [
         {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
         }
      ]
    }
    

    在 webpack 5 中:

    module.exports = {
        target: ['web', 'es5']
    }
    

    target 位于配置模式的根目录,需要知道它是针对节点还是 Web 环境

    参考资料:

    【讨论】:

    • 这非常有帮助——我花了大约 6 个小时试图弄清楚为什么 Babel 会在 @babel/preset-env 中包含箭头函数,这个答案终于让我意识到这是一个 Webpack 问题,不是巴别塔问题。谢谢!
    • TL;DR ... babel 正在做正确的事情,webpack 正在使用箭头函数。将 target: "es5" 设置为 webpack 的配置选项,以使其做正确的事情。
    • target 属性无效。当你添加它并尝试运行 Webpack 时会发生以下情况:[webpack-cli] Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration.module has an unknown property 'target'. These properties are valid: object { defaultRules?, exprContextCritical?, exprContextRecursive?, exprContextRegExp?...
    【解决方案2】:

    你可以使用 babel。由于 es6 自带箭头函数,所以可以使用 babel 来转换 es5。这个链接也可以帮助Webpack not converting ES6 to ES5

    下面给出的 webpack 配置是我用于 babel 的。

    module: {
       loaders: [
         {
            test: /\.(js|jsx)$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
               babelrc: false,
               presets: ["@babel/preset-env", "@babel/preset-react","es2015"]
             }
         }
      ]
    }     
    

    【讨论】:

    • 也许我应该更明确一点,但我使用的是 babel,它输出正确的代码,没有箭头函数。
    • "webpack.js.org/concepts/loaders/#loader-features" 如 webpacks 文档中所写,“加载器可以被链接。链中的每个加载器都将转换应用于处理的资源。链以相反的顺序执行。第一个加载器通过它的结果(应用了转换的资源)到下一个,依此类推。最后,webpack 期望 JavaScript 由链中的最后一个加载器返回。”因此,也许您可​​以将 babel 添加到您创建的每个加载程序链中。因此,无论每个加载器返回什么,它都会被 babel 翻译。
    • @BjørnMoholt 您的节点模块是否由 babel 转译?也许这就是问题所在。
    • 尝试参考下面的链接可能会帮助您正确配置 Webpack 可能有助于解决问题。 medium.com/daily-js-tips/…
    • @ysnfrk 好主意!试过了,没用。不过编译需要一些时间。
    猜你喜欢
    • 2019-01-02
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2017-05-06
    • 1970-01-01
    • 2021-02-13
    相关资源
    最近更新 更多