Jak zainstalować bibliotekę babel-polyfill?

140

Właśnie zacząłem używać Babel do kompilowania kodu javascript z ES6 do ES5. Kiedy zaczynam używać Promises, wygląda na to, że nie działa. Witryna Babel zapewnia wsparcie dla obietnic za pośrednictwem polyfills.

Bez szczęścia postarałem się dodać:

require("babel/polyfill");

lub

import * as p from "babel/polyfill";

Dzięki temu otrzymam następujący błąd podczas ładowania mojej aplikacji:

Nie można znaleźć modułu „babel / polyfill”

Szukałem modułu, ale wydaje mi się, że brakuje mi tutaj jakiejś podstawowej rzeczy. Próbowałem też dodać stary i dobry NPM bluebird, ale wygląda na to, że nie działa.

Jak używać polyfills firmy Babel?

Shlomi
źródło
1
npm install _name_
dandavis
1
UWAGA: Babel ma teraz oddzielny pakiet NPM do tego: babel-polyfill
Stijn de Witt
1
@StijndeWitt tylko po to, aby zaoszczędzić Ci kliknięcie, oto pełny plik README.md w pełnej wersji:
gurghet
1
@gurghet Tak, mogli dodać tam więcej informacji Zgadzam się :) Ale wszystko, co naprawdę musisz wiedzieć, to npm install --save babel-polyfilli require('babel-polyfill).
Stijn de Witt,
1
Ponieważ używasz ES6, możesz także użyć importu „babel-polyfill”.
Love Hasija

Odpowiedzi:

66

Zmieniło się to nieco w babel v6.

Z dokumentów:

Wypełnienie będzie emulowało pełne środowisko ES6. To wypełnienie jest automatycznie wczytywane podczas korzystania z węzła babel.

Instalacja:
$ npm install babel-polyfill

Użycie w Node / Browserify / Webpack:
Aby dołączyć polyfill, musisz go umieścić na górze punktu wejścia do aplikacji.
require("babel-polyfill");

Użycie w przeglądarce:
dostępne z dist/polyfill.jspliku w babel-polyfillwydaniu npm. Należy to uwzględnić przed całym skompilowanym kodem Babel. Możesz dołączyć go do skompilowanego kodu lub dołączyć go <script>przed nim.

UWAGA: Nie rób requiretego przez browserify itp., Użyj babel-polyfill.

vdclouis
źródło
6
Nadal nie jestem do końca pewien, kiedy potrzebny jest polyfill. Dlaczego moduły ES6 działają tylko z babel.js, ale Array.protorype.findIndex()nie działają bez polyfill, a babel nie zgłosi wyjątku podczas transpilacji? Czy taka jest natura Polyfill ™?
RemEmber
5
Zasadniczo wypełniacz Babel to po prostu połączenie github.com/facebook/regenerator i github.com/zloirock/core-js . Sprawdź te 2 repozytoria, aby dowiedzieć się, czy naprawdę potrzebujesz polyfills.
vdclouis
7
Myślę, że powodem, dla którego jeden działa, a drugi nie, jest to, że Babel podczas transpilacji celuje w hipotetyczny silnik JS z pewnym poziomem wsparcia. Prawdziwe przeglądarki mogą w końcu obsługiwać mniej lub więcej niż ten hipotetyczny silnik. W praktyce myślę, że hipotetyczna przeglądarka, na którą są skierowane, znajduje się na poziomie IE10, więc starsze przeglądarki mogą mieć pewne problemy. Umieszczając poprawki w osobnym polyfillu, decyzję, czy chcesz obsługiwać takie starsze przeglądarki, pozostawiasz Tobie. Trochę jak jQuery z jego gałęzią 1.0, która tak robi i gałąź 2.0, która nie obsługuje IE8. @RemEmber
Stijn de Witt
2
@dougmacklin, jeśli findIndex jest jedynym polifillem, którego potrzebujesz, możesz go po prostu umieścić w swoim kodzie. Sprawdź MDN pod kątem polyfills: developer.mozilla.org/en/docs/Web/JavaScript/Reference/ ...
vdclouis
1
@vdclouis, jak zabrałbyś się do włączenia tego kodu polyfill za pośrednictwem pakietu internetowego, aby był dostępny w całym projekcie?
dougmacklin
48

Dokumentacja Babel opisuje to dość zwięźle:

Babel zawiera polyfill, który zawiera niestandardowe środowisko wykonawcze regeneratora i core.js.

Spowoduje to emulację pełnego środowiska ES6. Ten polyfill jest ładowany automatycznie, gdy używasz babel-node i babel / register.

Upewnij się, że potrzebujesz go w punkcie wejścia do aplikacji, zanim cokolwiek innego zostanie wywołane. Jeśli używasz narzędzia takiego jak webpack, staje się to całkiem proste (możesz powiedzieć webpakowi, aby dołączył go do pakietu).

Jeśli używasz narzędzia takiego jak gulp-babellub babel-loader, musisz również zainstalować babelsam pakiet, aby użyć wypełnienia.

Pamiętaj również, że w przypadku modułów, które mają wpływ na zasięg globalny (polyfills i tym podobne), możesz użyć krótkiego importu, aby uniknąć nieużywanych zmiennych w module:

import 'babel/polyfill';
ssube
źródło
4
Wystarczy dodać notatkę i nie jestem w 100% pewien, czy to jest całkowicie poprawne, ale próbowałem po prostu użyć import 'babel-core/polyfill'bez instalacji babeli działało dobrze.
Nathan Lutterman,
2
Zaemz , myślę, że masz już zainstalowany babel, więc import 'babel-core/polifyll'działa. Wypróbowałem to bez zainstalowanego babeli nie zadziałało. Przy okazji: ssube advice działa.
WebBrother
4
Kiedy używasz webpacka, gdzie go umieszczasz?
theptrk
2
@theptrk Używając webpacka, możesz po prostu zaimportować go jako moduł, ponieważ webpack umożliwia importowanie pakietów npm. W przypadku Karmy konfigurujesz go jako plik, który ma być dołączony przed testami.
ssube
3
Dzięki, może miałem inną wersję, ale zamiast tego musiałem użyć babel-core => "import 'babel-core / polyfill';
theptrk
22

W przypadku Babel w wersji 7, jeśli używasz @ babel / preset-env, aby uwzględnić polyfill, wystarczy dodać flagę „useBuiltIns” z wartością „usage” w konfiguracji babel. Nie ma potrzeby, aby wymagać ani importować polyfillu w punkcie wejścia aplikacji.

Po określeniu tej flagi babel @ 7 zoptymalizuje i uwzględni tylko te wypełnienia, których potrzebujesz.

Aby użyć tej flagi, po instalacji:

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

Po prostu dodaj flagę:

useBuiltIns: "usage" 

do pliku konfiguracyjnego Babel o nazwie „babel.config.js” (również nowy w Babel @ 7), w sekcji „@ babel / env”:

// file: babel.config.js

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

   return { presets };
};

Odniesienie:


Aktualizacja, sierpień 2019 r .:

Wraz z wydaniem Babel 7.4.0 (19 marca 2019 r.) @ Babel / polyfill jest przestarzałe. Zamiast instalować @ babe / polyfill, zainstalujesz core-js:

npm install --save core-js@3

Nowy wpis corejszostanie dodany do twojego 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 };
};

patrz przykład: https://github.com/ApolloTang/stackoverflow-eg--babel-v7.4.0-polyfill-w-core-v3

Odniesienie:

Apollo
źródło
1
Czy używasz tego w środowisku produkcyjnym? jakieś ryzyko?
Roy
useBuiltIns: "usage"nie działa po mojej stronie. Po prostu nie zawiera żadnych polyfilów w pakiecie (przykład: używam generatorów i otrzymuję błąd „regeneratorRuntime nie jest zdefiniowany”). Jakieś pomysły?
WebBrother
@WebBrother, działa dla mnie ... patrz np .: github.com/ApolloTang/stackoverflow-eg--babel-polyfill
apollo
@Roy, jestem w trakcie migracji projektu przedsiębiorstwa z babel @ 6 do babel @ 7, abym mógł używać @ babel / preset-typescript. Jest to nadal w toku, ale postępuję zgodnie z instrukcjami zawartymi w oficjalnym dokumencie babel (patrz odnośniki w mojej odpowiedzi). Jak dotąd wydaje się, że wszystko działa, ale nie wysłałem jeszcze mojej pracy migracji / aktualizacji do kontroli jakości, napiszę tutaj, jeśli pojawi się jakiś problem.
apollo
19

Jeśli plik package.json wygląda mniej więcej tak:

  ...
  "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",
  ...

Otrzymujesz Cannot find module 'babel/polyfill'komunikat o błędzie, prawdopodobnie musisz zmienić instrukcję importu OD:

import "babel/polyfill";

DO:

import "babel-polyfill";

I upewnij się, że pojawia się przed jakimkolwiek innym importstwierdzeniem (niekoniecznie w punkcie wejścia do aplikacji).

Źródła: https://babeljs.io/docs/usage/polyfill/

l3x
źródło
3
W tej odpowiedzi pakiet babel-polyfill jest wymieniony w sekcji „devDependencies”. W ten sposób babel-polyfill nie zostanie uwzględniony podczas wdrażania. Nie powinieneś instalować babel-polyfill z flagą -D, ale z flagą -S, więc jest on wymieniony pod 'zależnościami', a zatem dołączony do Twojego wdrożenia.
apollo
9

Po pierwsze, oczywista odpowiedź, której nikt nie udzielił, musisz zainstalować Babel w swojej aplikacji:

npm install babel --save

(lub babel-corejeśli zamiast tego chcesz require('babel-core/polyfill')).

Poza tym mam podstawowe zadanie transpozycji moich es6 i jsx jako kroku kompilacji (tj. Nie chcę używać babel/register, dlatego staram się używać babel/polyfillbezpośrednio w pierwszej kolejności), więc chciałbym położyć większy nacisk na tę część odpowiedzi @ ssube:

Upewnij się, że potrzebujesz go w punkcie wejścia do aplikacji, zanim cokolwiek innego zostanie wywołane

Napotkałem jakiś dziwny problem, w którym próbowałem wymagać babel/polyfillod jakiegoś pliku startowego środowiska współdzielonego i otrzymałem błąd, do którego odwołał się użytkownik - myślę, że mógł to mieć coś wspólnego z tym, jak zamówienia importu babel w porównaniu z wymaganiami, ale nie mogę odtworzyć teraz. W każdym razie, przeniesienie import 'babel/polyfill'pierwszej linii w skryptach startowych klienta i serwera rozwiązało problem.

Zauważ, że jeśli zamiast tego chcesz użyć require('babel/polyfill'), upewnię się, że wszystkie inne instrukcje modułu ładującego również są wymagane i nie używają importu - unikaj mieszania tych dwóch. Innymi słowy, jeśli masz jakiekolwiek instrukcje importu w swoim skrypcie startowym, wprowadź import babel/polyfillpierwszy wiersz skryptu zamiast require('babel/polyfill').

ChetPrickles
źródło
9
nie musisz uruchamiać sudoz npm docs.npmjs.com/getting-started/fixing-npm-permissions
Vladimir Starkov
8

babel-polyfill umożliwia korzystanie z pełnego zestawu funkcji ES6 poza zmianami składni. Obejmuje to funkcje, takie jak nowe wbudowane obiekty, takie jak Promises i WeakMap, a także nowe metody statyczne, takie jak Array.from lub Object. assign.

Bez babel-polyfill, babel pozwala tylko na używanie funkcji takich jak funkcje strzałkowe, destrukturyzacja, domyślne argumenty i inne specyficzne dla składni funkcje wprowadzone w 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
źródło
0

Jak Babel mówi w dokumentacji , dla Babel> 7.4.0 moduł @ babel / polyfill jest przestarzały , więc zaleca się bezpośrednie użycie bibliotek core-js i regenerator-runtime, które wcześniej były zawarte w @ babel / polyfill.

Więc to zadziałało dla mnie:

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

następnie dodaj na samej górze początkowego pliku js:

import 'core-js/stable';
import 'regenerator-runtime/runtime';
Fred K.
źródło