Обещание polyfill не работает в FireFox и IE11 при добавлении через Webpack babel-loader

#webpack #babeljs #apollo-client #polyfills #babel-loader

#webpack #babeljs #аполлон-клиент #полифиллы #вавилон-погрузчик

Вопрос:

Я столкнулся с указанной ниже специфической проблемой в promise polyfill, которая должна быть добавлена с помощью предустановленной среды Babel для совместимости с браузером.

У меня есть Foo.ts файл, который использует async/await синтаксис для обработки обещаний. После обработки babel-loader , объединения и запуска сервером разработки Webpack содержащее веб-приложение React успешно запускается в Chrome, Safari, Edge (Mac), но завершается сбоем в FireFox, IE11 и Edge (Windows).

Ошибка выглядит следующим образом, которая идентифицируется как из пакета npm, от @apollo/client которого Foo.ts зависит. Указывает ли это на то, что многообещающее заполнение отсутствует?

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

Конфигурация Webpack для babel-loader выглядит следующим образом.

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

  

При запуске сервера разработки в выводе консоли я могу видеть ниже строку, в которой говорится, что многообещающее заполнение добавлено в 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 .

Часть кода, Foo.ts которая включает @apollo/client , выглядит следующим образом. Он компилируется в ES2015 target by tsc перед выполнением преобразования babel.

 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;
}
  

Дополнительная информация

  • Firefox: 68.8.0esr
  • @babel/предустановленный-env: 7.9.5
  • ядро-js: 3.6.5
  • Веб-пакет: 4.29.6
  • вавилон-загрузчик: 8.0.5

Ответ №1:

После дальнейшего изучения я думаю, что проблема вызвана тем, что @babel/preset-env не удается ввести правильное es.promise заполнение для Firefox. Я тестировал с приведенной ниже конфигурацией, которая изолирует целевую среду запуска только для Firefox. Проблема наблюдается только для версии Firefox, установленной на 68 и ниже.

       targets: {
        firefox: '68',
      },
  

На данный момент мой обходной путь:

  1. Настройте, @babel/preset-env чтобы намеренно исключить es.promise полизаполнение.
 exclude: ['es.promise'],
  
  1. Добавьте его через конфигурацию точки входа Webpack, поскольку она все еще необходима.
 entry: ['core-js/es/promise', 'index.ts'],
  

Комментарии:

1. Я опубликовал отчет о проблеме, чтобы получить дополнительную консультацию. github.com/babel/babel/issues/12029