Как установить библиотеку babel-polyfill?

140

Я только начал использовать Babel для компиляции своего кода JavaScript ES6 в ES5. Когда я начинаю использовать Promises, похоже, он не работает. Сайт Babel заявляет о поддержке обещаний через полифиллы.

Без всякой удачи я попытался добавить:

require("babel/polyfill");

или

import * as p from "babel/polyfill";

При этом я получаю следующую ошибку при загрузке моего приложения:

Не удается найти модуль 'babel / polyfill'

Я искал модуль, но, похоже, мне здесь не хватает какой-то фундаментальной вещи. Я также попытался добавить старый и хороший NPM для Bluebird, но похоже, что он не работает.

Как использовать полифилы от Babel?

Шломи
источник
1
npm install _name_
Дандавис
1
ПРИМЕЧАНИЕ: у Babel теперь есть отдельный пакет NPM для этого: babel-polyfill
Stijn de Witt
1
@StijndeWitt, просто чтобы сохранить ваш клик, вот полный файл README.md в полной версии:
gurghet
1
@gurghet Да, они могли бы добавить еще немного информации, я согласен :) Но все, что вам действительно нужно знать, это npm install --save babel-polyfillи require('babel-polyfill).
Стейн де Витт
1
Поскольку вы используете ES6, вы также можете использовать импорт "babel-polyfill".
Любовь Хасия

Ответы:

66

Это немного изменилось в Babel v6.

Из документов:

Polyfill будет эмулировать полную среду ES6. Этот полифилл автоматически загружается при использовании babel-node.

Монтаж:
$ npm install babel-polyfill

Использование в Node / Browserify / Webpack:
чтобы включить полифил, вам нужно указать его в верхней части точки входа в ваше приложение.
require("babel-polyfill");

Использование в браузере:
доступно из dist/polyfill.jsфайла в babel-polyfillвыпуске npm. Это должно быть включено до всего вашего скомпилированного кода Babel. Вы можете либо добавить его к вашему скомпилированному коду, либо включить его в <script>перед ним.

ПРИМЕЧАНИЕ: не делайте requireэтого через browserify и т. Д., Используйте babel-polyfill.

vdclouis
источник
6
Я до сих пор не совсем уверен, когда понадобится полифилл. Почему модули ES6 просто работают с babel.js, но Array.protorype.findIndex()не работают без полизаполнения, и babel не вызовет исключения при переносе? Это природа Polyfill ™?
RemEmber
5
В основном, Babel Polyfill - это просто github.com/facebook/regenerator и github.com/zloirock/core-js вместе взятые. Проверьте эти 2 репозитория, чтобы узнать, действительно ли вам нужны полифилы.
vdclouis
7
Я думаю, что причина, по которой один работает, а другой нет, заключается в том, что Бабел, перемещаясь, нацеливается на гипотетический движок JS с определенным уровнем поддержки. Реальные браузеры могут поддерживать больше или меньше, чем этот гипотетический движок. На практике я думаю, что предполагаемый браузер, на который они нацелены, находится где-то на уровне IE10, поэтому у старых браузеров могут возникнуть некоторые проблемы. Поместив исправления для этого в отдельный полифилл, они оставляют решение, хотите ли вы поддерживать такие старые браузеры. Немного похоже на jQuery с веткой 1.0, которая поддерживает, и веткой 2.0, которая не поддерживает IE8. @RemEmber
Стейн де Витт
2
@dougmacklin, если findIndex является единственным полифилом, который вам нужен, вы можете просто включить его в свой код. Проверьте MDN на наличие полифилов: developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
vdclouis
1
@vdclouis, как бы вы включили этот полифилл-код через веб-пакет, чтобы он был доступен везде в проекте?
Дугмаклин
48

В документах Бабеля описывают это довольно лаконично:

Babel включает в себя polyfill, который включает пользовательскую среду выполнения регенератора и core.js.

Это будет эмулировать полную среду ES6. Этот polyfill автоматически загружается при использовании babel-node и babel / register.

Убедитесь, что вы требуете его в точке входа в ваше приложение, прежде чем что-либо еще вызывается. Если вы используете такой инструмент, как веб-пакет, это становится довольно простым (вы можете указать веб-пакету включить его в пакет).

Если вы используете такой инструмент, как gulp-babelили babel-loader, вам также нужно установить сам babelпакет, чтобы использовать полифилл.

Также обратите внимание, что для модулей, которые влияют на глобальную область действия (полифилы и тому подобное), вы можете использовать краткий импорт, чтобы избежать использования неиспользуемых переменных в вашем модуле:

import 'babel/polyfill';
ssube
источник
4
Просто, чтобы добавить примечание, и я не уверен на 100%, если это полностью правильно, но я попытался просто использовать import 'babel-core/polyfill'без установки, babelи это работало просто отлично.
Натан Луттерман
2
Zaemz , я думаю, вы уже установили babel, так что import 'babel-core/polifyll'работает. Я попробовал это без установленного, babelи это не работало для меня. Кстати: ссубе советую работает.
WebBrother
4
Когда вы используете веб-пакет, куда вы его включаете?
Theptrk
2
@theptrk Используя webpack, вы можете просто импортировать его как модуль, поскольку webpack позволяет импортировать пакеты npm. Для Karma вы настраиваете его как файл, который будет включен перед тестированием.
ssube
3
Спасибо, может быть, у меня была другая версия, но вместо этого мне пришлось использовать babel-core => "import 'babel-core / polyfill';
theptrk
22

Для Babel версии 7, если вы используете @ babel / preset-env, для включения polyfill все, что вам нужно сделать, это добавить флаг «useBuiltIns» со значением «using» в вашей конфигурации babel. Нет необходимости запрашивать или импортировать полизаполнение в точке входа вашего приложения.

Если указан этот флаг, babel @ 7 будет оптимизировать и включать только те необходимые вам заполнения.

Чтобы использовать этот флаг, после установки:

npm install --save-dev  @babel/core @babel/cli @babel/preset-env
npm install --save @babel/polyfill

Просто добавьте флаг:

useBuiltIns: "usage" 

в ваш конфигурационный файл babel с именем "babel.config.js" (также новый для Babel @ 7) в разделе "@ babel / env":

// file: babel.config.js

module.exports = () => {
   const presets = [
      [
         "@babel/env", 
         { 
             targets: { /* your targeted browser */ },
             useBuiltIns: "usage"  // <-----------------*** add this
         }
      ]
   ];

   return { presets };
};

Ссылка:


Обновление Авг 2019:

С выпуском Babel 7.4.0 (19 марта 2019 г.) @ babel / polyfill устарела. Вместо установки @ babe / polyfill вы установите core-js:

npm install --save core-js@3

Новая запись corejsдобавлена ​​в ваш babel.config.js

// file: babel.config.js

module.exports = () => {
   const presets = [
      [
         "@babel/env", 
         { 
             targets: { /* your targeted browser */ },
             useBuiltIns: "usage",
             corejs: 3  // <----- specify version of corejs used
         }
      ]
   ];

   return { presets };
};

см. пример: https://github.com/ApolloTang/stackoverflow-eg--babel-v7.4.0-polyfill-w-core-v3

Ссылка:

Аполлон
источник
1
Вы используете это в производственной среде? любой риск?
Рой
useBuiltIns: "usage"не работает на моей стороне. Он просто не включает в себя никаких полифайлов в комплекте (пример: я использую генераторы и получаю сообщение об ошибке «регенератор не определен»). Любые идеи?
WebBrother
@WebBrother, работает для меня ... см. Например: github.com/ApolloTang/stackoverflow-eg--babel-polyfill
apollo
@ Рой, я на самом деле в процессе переноса корпоративного проекта с babel @ 6 на babel @ 7, чтобы я мог использовать @ babel / preset-typcript. Эта работа еще не завершена, но я следую инструкциям из официального документа babel (см. Ссылки в моем ответе). Пока все работает, но я еще не отправил свои работы по миграции / обновлению в QA, я опубликую здесь, если возникнут какие-либо проблемы.
аполлон
19

Если ваш package.json выглядит примерно так:

  ...
  "devDependencies": {
    "babel": "^6.5.2",
    "babel-eslint": "^6.0.4",
    "babel-polyfill": "^6.8.0",
    "babel-preset-es2015": "^6.6.0",
    "babelify": "^7.3.0",
  ...

И вы получите Cannot find module 'babel/polyfill'сообщение об ошибке, тогда вам, вероятно, просто нужно изменить оператор импорта FROM:

import "babel/polyfill";

TO:

import "babel-polyfill";

И убедитесь, что он предшествует любому другому importутверждению (не обязательно в точке входа вашего приложения).

Ссылка: https://babeljs.io/docs/usage/polyfill/

L3x
источник
3
В этом ответе пакет babel-polyfill указан в разделе «devDependencies». Это приведет к тому, что babel-polyfill не будет включен в развертывание. Не следует устанавливать babel-polyfill с флагом -D, но с флагом -S, поэтому он указан в разделе «зависимости» и, следовательно, включен в ваше развертывание.
Аполлон
9

Во-первых, очевидный ответ, который никто не дал, вам нужно установить Babel в ваше приложение:

npm install babel --save

(или babel-coreесли вы хотите вместо этого require('babel-core/polyfill')).

Помимо этого, у меня есть грандиозная задача по переносу моих es6 и jsx в качестве шага сборки (то есть я не хочу использовать babel/register, именно поэтому я пытаюсь использовать babel/polyfillнепосредственно с самого начала), поэтому я бы хотел уделите больше внимания этой части ответа @ ssube:

Убедитесь, что вы требуете его в точке входа в ваше приложение, прежде чем что-либо еще называется

Я столкнулся с какой-то странной проблемой, из-за которой я пытался запросить babel/polyfillкакой-то файл запуска общей среды, и я получил ошибку, на которую ссылался пользователь. Я думаю, что это может быть связано с тем, как импорт заказов Babel по сравнению с требованиями требует, но я не могу воспроизвести сейчас. В любом случае, перемещение import 'babel/polyfill'в качестве первой строки в моих клиентских и серверных сценариях запуска решило проблему.

Обратите внимание, что если вы вместо этого хотите использовать, require('babel/polyfill')я бы удостоверился, что все ваши другие операторы загрузчика модулей также требуются, а не используйте импорт - избегайте их смешивания. Другими словами, если у вас есть какие-либо операторы импорта в вашем скрипте запуска, сделайте import babel/polyfillпервую строку в вашем скрипте, а не require('babel/polyfill').

ChetPrickles
источник
9
вам не нужно работать sudoс npm docs.npmjs.com/getting-started/fixing-npm-permissions
Владимир Старков
8

babel-polyfill позволяет вам использовать полный набор функций ES6 за пределами синтаксических изменений. Это включает в себя такие функции, как новые встроенные объекты, такие как Promises и WeakMap, а также новые статические методы, такие как Array.from или Object.assign.

Без babel-polyfill babel позволяет использовать только такие функции, как функции стрелок, деструктурирование, аргументы по умолчанию и другие специфичные для синтаксиса функции, представленные в ES6.

https://www.quora.com/What-does-babel-polyfill-do

https://hackernoon.com/polyfills-everything-you-ever-wanted-to-know-or-maybe-a-bit-less-7c8de164e423

zloctb
источник
0

Как говорит Бабель в документации , для Babel> 7.4.0 модуль @ babel / polyfill устарел , поэтому рекомендуется использовать напрямую библиотеки core-js и регенератор-время выполнения, которые ранее были включены в @ babel / polyfill.

Так что это сработало для меня:

npm install --save core-js@3.6.5
npm install regenerator-runtime

затем добавьте в самый верх вашего исходного js-файла:

import 'core-js/stable';
import 'regenerator-runtime/runtime';
Фред К
источник