【问题标题】:JavaScript - babel-preset-env not transpiling arrow functions for IE11JavaScript - babel-preset-env 不为 IE11 转换箭头函数
【发布时间】:2019-03-20 03:48:06
【问题描述】:

我很难将 Babel 配置为转译 IE11 可以理解的代码,特别是箭头函数。使用我的配置运行 npx webpack --mode=development 不会转换代码中的箭头函数:在生成的代码中的 eval() 语句中,我可以看到所有实例都未转换。

this question 中引用的控制台输出不同,我没有提到“使用目标”或“使用预设”。我不知道这是否与使用npx webpack 而不是npm run build 有关。

这是我 package.json 的 Babel 部分:

{
  // name, version etc. snipped
  "devDependencies": {
    "@babel/core": "^7.1.2",
    "@babel/plugin-transform-async-to-generator": "^7.1.0",
    "@babel/plugin-transform-es2015-arrow-functions": "^6.22.0",
    "@babel/plugin-transform-es2015-modules-commonjs": "^6.26.2",
    "@babel/preset-env": "^7.1.0",
    "ajv": "^6.5.4",
    "copy-webpack-plugin": "^4.5.2",
    "eslint-plugin-jest": "^21.24.1",
    "jest": "^23.6.0",
    "jest-dom": "^2.0.4",
    "webpack": "^4.20.2",
    "webpack-cli": "^3.1.2"
  },
  "babel": {
    "presets": [
      [
        "@babel/preset-env",
        {
          "targets": {
            "ie": "11"
          }
        }
      ]
    ],
    "env": {
      "development": {
        "plugins": [
          "transform-es2015-arrow-functions",
          "transform-es2015-modules-commonjs"
        ]
      },
      "test": {
        "plugins": [
          "transform-es2015-arrow-functions",
          "transform-es2015-modules-commonjs"
        ]
      }
    }
  }
}

我的webpack.config.js 看起来像:

const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require("path");

module.exports = {
    entry: "./src/thing.js",
    optimization: {
        minimize: false
    },
    output: {
        filename: "thing.js",
        path: path.resolve(__dirname, "dist")
    },
    plugins: [
        new CopyWebpackPlugin([
            // snipped
        ])
    ]
};

我在这里阅读了关于 Babel 配置的其他问题,以及 babel-preset-env docs 和非常轻薄的 babel-plugin-transform-es2015-arrow-functions docsthis very similar question 的答案(没有接受的答案)根本没有提到那个插件,有人建议使用 polyfill,这似乎涉及在你的实际代码中而不是在这个阶段加载一个库?

一般来说,我对使用 Webpack 非常陌生,不明白 "env"(在很多问题中提到)和 "@babel/preset-env" 之间有什么区别。或者实际上是前者的一般含义;如果您在文档导航中单击“env”,它会将您带到@babel/preset-env 的页面。

我做错了什么?

【问题讨论】:

  • 你在使用github.com/babel/babel-loader吗?看起来你已经安装了 Babel,但实际上并没有在 Webpack 中启用它。
  • @loganfsmyth 我非常高兴地报告说不,我不是,并且解决了它。如果您将其作为答案提交,我会将其标记为已接受。
  • 我要稍微发泄一下……在 Babel 文档中没有对此进行解释真的很烦人。只提到in the sentence“Babel 集成的用户,如 babel-loader 或 @babel/register 不太可能使用这些。”我现在知道,如果你是通过 Webpack 文档加载器来了解的,但是在 Babel 站点登陆时,我(一个学习者)碰壁了。如果有指向the Webpack loaders docs 的链接,它会节省很多令人沮丧的时间。
  • 我们有一个“设置”顶级页面:babeljs.io/setup。 “Webpack”部分介绍了使用 babel-loader 的步骤。
  • 谢谢,这是有用的反馈。该页面已经有一段时间没有更新了,几乎可以肯定我们可以做一些其他的事情来让它对初学者更友好。

标签: javascript webpack babeljs


【解决方案1】:

除了解决问题的 loganfsmyth 的回答之外,我想提醒任何其他阅读本文的初学者,我后来通过将 Babel 配置从 package.json 移到 .babelrc 来让自己的生活更轻松。

我还发现我需要的插件,例如我上面提到的插件babel-plugin-transform-es2015-arrow-functions,有更新版本的不同命名方案 - 例如@babel/plugin-transform-arrow-functions。旧版本的文档页面没有提到这一点。

我的webpack.config.jsmodule 部分现在看起来像:

module: {
    rules: [
        {
            test: /\.m?js$/,
            exclude: /node_modules/,
            use: {
                loader: "babel-loader"
            }
        }
    ]
}

我的.babelrc 看起来像:

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "targets": {
                    "ie": "11"
                },
                "useBuiltIns": "entry"
            }
        ]
    ],
    "plugins": [
        "@babel/transform-async-to-generator",
        "@babel/transform-arrow-functions",
        "@babel/transform-modules-commonjs"
    ],
    "env": {
        "development": {},
        "test": {},
        "production": {}
    }
}

2021 年更新As of Webpack version 5,默认输出 ES6 代码。如果您不希望发生这种情况,则需要添加配置设置。见Giorgio Tempesta's answer

【讨论】:

  • 我做了同样的事情,但在 IE11 中仍然出现箭头功能错误。有什么想法吗?
  • 嗨,Yogen,您可以粘贴您收到的错误消息吗?
  • IE11 "SCRIPT1002 syntax error" 我发现如果我删除箭头功能 => 那么它工作正常。
  • npm install @babel/transform-arrow-functions了吗?但是,您最好提出自己的问题,而不是试图在此处的 cmets 中寻求帮助。如果需要,您可以在问题中链接回此答案。
  • 为什么重复的配置?在 webpack.config.js .babelrc 中定义预设和插件就足够了,不是吗?
【解决方案2】:

如果您使用的是 Webpack 5,则需要在 ouput.environment 配置中指定要转译的功能,如下所述:https://webpack.js.org/configuration/output/#outputenvironment

output: {
  // ... other configs
  environment: {
    arrowFunction: false,
    bigIntLiteral: false,
    const: false,
    destructuring: false,
    dynamicImport: false,
    forOf: false,
    module: false,
  },
}

【讨论】:

  • 哇,这什么时候开始需要发生的? ? 谢谢乔治!
  • @ScottMartin 我不知道,可能是从 Webpack 5 开始。我删除了使用 Webpack 4 的 Laravel Mix 并同时切换到 Webpack 5,所以我不得不添加这个配置来制作它工作。
  • 啊,你成功了。查看产生此问题的原始项目,它仍在使用 Webpack 4。我将参考您的更新我的答案。
  • 现在有一个target setting for this that accepts browserslist syntax,显然可以与你的 Babel 配置一致。太好了。
【解决方案3】:

我遇到了同样的问题。结果发现并不是我的所有代码都有箭头函数,而只有一个库。我进入了我构建的包,并搜索了带有箭头函数的代码 (=>)。然后我在它周围搜索并复制了一些看起来很独特的名字,并设法在node_modules 的所有文件中找到它的来源。在我的例子中,带有箭头函数的代码来自名为 unfetch 的 fetch polyfill。我不确定为什么它没有被插件转译,但我将它切换到“whatwg-fetch”并且它工作得很好 - 捆绑中不再有箭头功能。您可以尝试使用相同的技术来发现您的情况是什么原因造成的。

【讨论】:

    【解决方案4】:

    Babel 本身是一个转换库,但它本身不会集成到任何特定的工具中。要将 Babel 与 Webpack 一起使用,您需要安装 babel-loader 包并在您的 Webpack 配置中使用类似于

    的内容进行配置
    module: {
      rules: [
        {
          test: /\.m?js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
          }
        }
      ]
    }
    

    【讨论】:

    • 这是我在设置过程中遗漏的关键元素。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2020-06-26
    • 2018-11-17
    • 1970-01-01
    • 2018-04-27
    • 2021-03-03
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    相关资源
    最近更新 更多