JavaScript - babel-preset-env无法为IE11转换箭头函数

aemubtdh  于 2022-12-08  发布在  Babel
关注(0)|答案(5)|浏览(350)

我很难配置Babel来转换IE11可以理解的代码,特别是箭头函数。用我的配置运行npx webpack --mode=development并不能转换代码中的箭头函数:在生成的代码的eval()语句中,我可以看到所有示例都没有转换。
this question中引用的控制台输出不同,我的输出中没有提到“使用目标”或“使用预设”。我不知道这是否与使用npx webpack而不是npm run build有关。
下面是我的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"
        ]
      }
    }
  }
}

我的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文档和非常简单的babel-plugin-transform-es2015-arrow-functions docs来达到这一点的。关于this very similar question的答案(没有被接受的答案)根本没有提到这个插件,还有一个建议使用polyfill,这似乎涉及到在实际代码中加载一个库,而不是在这个阶段?
一般来说,我对Webpack的工作还是个新手,不明白"env"(在很多问题中都会提到)和"@babel/preset-env"之间的区别是什么,或者前者一般意味着什么;如果您单击docs导航中的“env”,它会将您带到@babel/preset-env的页面。
我做错了什么?

y53ybaqx

y53ybaqx1#

如果使用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,
  },
}
编辑日期:2022年8月10日

在对我的webpack配置进行一些重构时,我发现箭头已经停止了跳动(或者在给出最初的答案时我没有进行广泛的测试)。
有两件事设置不正确:target键丢失,babel配置的值错误。
为了支持旧版浏览器,需要如下设置目标键:

target: ['web', 'es5']

在Babel配置中,我在Babel加载器的targets下的browserslist配置中添加了'not dead',所以由于IE11现在在技术上已经死了,这个配置删除了箭头函数的传输。
因此,如果你仍然需要transpile箭头功能,这将是巴别塔配置中的相关部分。

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 }]],
        },
      },
    },
  ],
},
gpfsuwkq

gpfsuwkq2#

除了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年更新:从Webpack第5版开始,默认输出ES6代码。如果你不想这样,你需要添加一个配置设置。参见Giorgio Tempesta's answer

shstlldc

shstlldc3#

Babel本身是一个转换库,但是它本身不会集成到任何特定的工具中。

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

oipij1gg4#

我也遇到了同样的问题。原来并不是我所有的代码都有箭头函数,而是只有一个库。我进入我构建的包,并搜索带有箭头函数的代码(=>)。然后我搜索并复制了一些看起来很独特的名字,并设法找到了它的来源,在node_modules内的所有文件中搜索它。在我的例子中,箭头函数的代码来自fetch polyfill,名为unfetch,我不知道为什么它没有被插件翻译,但我将其切换为“whatwg-fetch”,它运行得很好--包中不再有箭头函数。你可以尝试同样的技术来找出是什么原因在你的情况下。

yacmzcpb

yacmzcpb5#

2022年更新

如果您现在遇到这个问题,可能是因为browerslist自4.21.0版本以来将IE 11视为死亡。无论如何,访问IE 11的解决方案是将ie 11添加为browerslist中的最后一个条目,或者至少添加在not dead之后。
通常在package.json中看不到browserslist,但如果使用npm ls browserslist,则可以看到哪个依赖项使用browserslist以及它的哪个版本。
另请参阅:https://github.com/browserslist/browserslist/issues/699

相关问题