我如何使用 babel 7 对 Promise.any() 进行 polyfill?

问题描述

我使用 webpack 为我的客户打包我的代码。根据我的问题 Is it possible to break away from await Promise.all when any promise has fulfilled (Chrome 80) 我想使用 Promise.any()Promise.any 仅适用于 Chrome85+,我的客户需要我支持 Chrome 80+。自然地,我曾想过使用 babel 我可以 polyfill Promise.any(),例如corejs 提供了 Promise.any。但我不知道我做错了什么,现在有了 Babel 7 polyfill,我什至无法让 Promise.any 为 Chrome85+ 工作!

以下是我所做的,

首先,我的 webpack.config.js

module.exports = {
    entry: {
        index: './src/index.js'
        ui:'./src/ui/index.js'
    },output: {
        path: path.resolve(__dirname,'./dist'),filename: '[name].js',libraryTarget: 'umd',libraryExport: 'default',umdNamedDefine: true,library: '[name]'
    },module: {
        rules: [
            {
                test: /\.js$/,exclude: /node_modules/,use: {
                    loader: 'babel-loader'
                }
            },...
}

我最初使用 Babel 6。使用 Babel 6,我可以验证 webpack 捆绑的代码(使用 Promise.any)适用于 Chrome 85+(可能它根本没有 polyfill Promise.any)。

然后我使用 npx babel-upgrade --write 和一些曲折(例如 "useBuiltIns": 'usage')将 Babel 6 升级到 Babel 7。 webpack 可以捆绑我的代码,但令我惊讶的是,带有 Promise.any() 的捆绑代码甚至无法在 Chrome85+ 上运行。我收到错误消息“未捕获(承诺)被拒绝

以下是我的babelrc

{
    "env": {
        "production": {
            "presets": [
                [
                    "@babel/preset-env",{
                        "targets": {
                            "browsers": [
                                "last 4 Chrome versions","last 3 Firefox versions",]
                        },"modules": "commonjs","debug": true,"useBuiltIns": 'usage'
                    }
                ]
            ],"plugins": [
                [
                    "@babel/plugin-transform-runtime",{
                        "corejs": 2,"regenerator": true
                    }
                ]
            ]
        }
    }
}

我做错了什么?

解决方法

我针对 core-js 打开了 an issue,作者告诉我我不应该使用 core-js@2。有了这个指针,我终于让它与 core-js@3 一起工作了!

以下是我的.babelrc。重点是在 "presets" 或 "@babel/plugin-transform-runtime" 中设置 corejs3但不能同时设置。 让 babel 工作如此困难以至于我在这里列出了我的 .babelrc,但我不确定我是否设置正确。

"production": {
            "presets": [
                [
                    "@babel/preset-env",{
                        "targets": { ... },"modules": "commonjs","useBuiltIns": "usage","corejs": {
                            "version": 3,"proposals": true
                        }
                    }
                ]
            ],"plugins": [
                [
                    "@babel/plugin-transform-runtime",{
                        "regenerator": true
                        //or don't useBuiltIns but here
                        // "corejs": {
                        //     "version": 3,//     "proposals": true
                        // }
                    }
                ]
            ]
        }

通过这个设置,我可以看到 webpack 输出,polyfill 终于可以工作了!

Added following core-js polyfills:
  esnext.aggregate-error { "chrome":"78","ie":"10","safari":"13.1" }
  esnext.promise.any { "chrome":"78","safari":"13.1" }
  ...