JavaScript - babel-preset-env没有为IE11转换箭头功能

Sco*_*tin 9 javascript webpack babeljs

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

此问题中引用的控制台输出不同,我的"使用目标"或"使用预设"中没有提及.这是否与使用有关npx webpack而不是npm run build我不知道.

这是我的Babel部分package.json:

{
  // 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"
        ]
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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
        ])
    ]
};
Run Code Online (Sandbox Code Playgroud)

我从这里读到了关于Babel配置,babel-preset-env文档以及非常简洁的babel-plugin-transform-es2015-arrow-functions文档的其他问题.对这些问题的答案这个非常类似的问题(没有公认的答案)不提及插件可言的,一个建议使用填充工具,这似乎涉及装载在实际的代码,而不是在这个阶段图书馆吗?

我一般都很擅长使用Webpack,并且不了解它们之间的区别"env"(在很多问题中都提到了)和"@babel/preset-env".或者真的是前者所暗示的; 如果您单击文档导航中的"env",则会转到该页面@babel/preset-env.

我究竟做错了什么?

Gio*_*sta 15

如果您使用的是 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,
  },
}
Run Code Online (Sandbox Code Playgroud)

编辑 08/10/22

在对我的 webpack 配置进行一些重构时,我发现箭头已经停止转译(或者也许我在给出原始答案时没有进行广泛的测试)。

有两件事设置不正确:target密钥丢失,并且 babel 配置的值错误。

为了支持旧版浏览器,目标键需要这样设置:

target: ['web', 'es5']
Run Code Online (Sandbox Code Playgroud)

而在 Babel 配置中,我在 Babel loader'not dead'下的 browserslist 配置中添加了targets这一配置,因此由于 IE11 现在在技术上已经失效,因此该配置删除了箭头函数的翻译。

因此,如果您仍然需要转译箭头函数,这将是 Babel 配置中的相关部分。

module: {
  rules: [
    {
      test: /\.m?js$/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: [
            [
              '@babel/preset-env',
              {
                useBuiltIns: 'entry',
                targets: {
                  // be sure not to add 'not dead' here 
                  browsers: ['> 1%', 'last 2 versions', 'Firefox ESR']
                },
                corejs: {
                  version: 3,
                  proposals: false,
                },
              },
            ],
          ],
          plugins: [['@babel/plugin-transform-runtime', { corejs: 3 }]],
        },
      },
    },
  ],
},
Run Code Online (Sandbox Code Playgroud)

  • 事实证明,现在有一个 [`target` 设置接受 `browserslist` 语法](https://webpack.js.org/configuration/target/),这显然可以与你的 Babel 配置保持一致。伟大的。 (3认同)

log*_*yth 7

Babel 本身是一个转换库,但它本身不会集成到任何特定工具中。要将 Babel 与 Webpack 一起使用,您需要安装该babel-loader软件包并使用以下内容在 Webpack 配置中对其进行配置

module: {
  rules: [
    {
      test: /\.m?js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
      }
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)


Sco*_*tin 7

除了解决问题的 loganfsmyth 的答案之外,我还想为任何其他阅读本文的初学者指出,通过将 Babel 配置移出package.json.babelrc.

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

modulewebpack.config.js现在的部分看起来像:

module: {
    rules: [
        {
            test: /\.m?js$/,
            exclude: /node_modules/,
            use: {
                loader: "babel-loader"
            }
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我的.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": {}
    }
}
Run Code Online (Sandbox Code Playgroud)

2021 年更新从 Webpack 版本 5 开始,它默认输出 ES6 代码。如果您不想发生这种情况,则需要添加配置设置。请参阅Giorgio Tempesta 的回答

  • IE11 `"SCRIPT1002 语法错误"` 我发现如果我删除箭头函数 => 那么它工作正常。 (2认同)