【问题标题】:Promise polyfill does not work in FireFox and IE11 when added via Webpack babel-loader通过 Webpack babel-loader 添加时,Promise polyfill 在 FireFox 和 IE11 中不起作用
【发布时间】:2020-09-01 07:19:16
【问题描述】:

我遇到了以下关于 Promise polyfill 的特殊问题,该问题应由 Babel 的预设环境添加以实现浏览器兼容性。

我有一个Foo.ts 文件,它使用async/await 语法来处理承诺。被babel-loader处理后,由Webpack开发服务器捆绑启动,包含的React web应用在Chrome、Safari、Edge(Mac)上运行成功,在FireFox、IE11和Edge(Windows)下运行失败。

错误如下所示,它被识别为来自Foo.ts 所依赖的npm 包@apollo/client。是不是表示缺少promise polyfill?

TypeError: "this.fetchQuery(...).finally is not a function"

babel-loader 的 Webpack 配置如下所示。

module: {
  rules: [
    {
      test: /\.(jsx?|tsx?)$/,
      exclude: /node_modules\/.*/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: [
            '@babel/preset-react',
            '@babel/preset-typescript',
            [
              '@babel/preset-env',
              {
                useBuiltIns: 'usage',
                corejs: '3.6',
                debug: true,
              },
            ],
          ],
          plugins: ['react-hot-loader/babel'],
        },
      },
    },
  ]
}

当开发服务器启动时,在控制台输出中我可以看到下面的行,说 promise polyfill 已添加到 Foo.js。

Added following core-js polyfills:
  es.promise { "chrome":"45", "edge":"12", "firefox":"45", "ie":"11", "safari":"10.1" }

因此我很困惑问题是如何发生的。

如果我手动将import 'core-js/es/promise/finally'; 添加到Foo.ts,一切正常。

我想知道这里可能缺少什么以及为什么 babel-loader 没有成功添加该 polyfill。

Foo.ts 中涉及@apollo/client 的代码部分如下所示。在经过 babel 转换之前,由tsc 编译为ES2015 目标。

try {
  const response: ApolloQueryResult<QueryType> = await this.apolloClient.query(
    {
      query,
      fetchPolicy: 'no-cache',
      errorPolicy: 'all',
      variables,
    },
  );
  return response.data;
} catch (e) {
  console.error(e);
  throw e;
}

环境信息

  • 火狐:68.8.0esr
  • @babel/preset-env: 7.9.5
  • 核心-js:3.6.5
  • Webpack:4.29.6
  • babel-loader: 8.0.5

【问题讨论】:

    标签: webpack babeljs apollo-client polyfills babel-loader


    【解决方案1】:

    经过进一步挖掘,我认为问题是由@babel/preset-env 无法为Firefox 注入正确的es.promise polyfill 引起的。我使用以下配置进行了测试,该配置仅将目标运行环境隔离到 Firefox。该问题仅在 Firefox 版本设置为 68 或更低时出现。

          targets: {
            firefox: '68',
          },
    

    目前我的解决方法是:

    1. 配置 @babel/preset-env 以故意排除 es.promise polyfill。
    exclude: ['es.promise'],
    
    1. 通过 Webpack 的入口点配置添加它,因为它仍然需要。
    entry: ['core-js/es/promise', 'index.ts'],
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 2019-03-10
    • 2020-05-07
    • 1970-01-01
    • 2019-08-20
    • 1970-01-01
    相关资源
    最近更新 更多