Wie installiere ich die babel-polyfill-Bibliothek?

139

Ich habe gerade angefangen, Babel zu verwenden, um meinen ES6-Javascript-Code in ES5 zu kompilieren. Wenn ich Promises benutze, sieht es so aus, als würde es nicht funktionieren. Auf der Babel-Website wird die Unterstützung von Versprechungen über Polyfills angegeben.

Ohne Glück versuchte ich hinzuzufügen:

require("babel/polyfill");

oder

import * as p from "babel/polyfill";

Damit erhalte ich beim Bootstrapping meiner App den folgenden Fehler:

Modul 'babel / polyfill' kann nicht gefunden werden

Ich habe nach dem Modul gesucht, aber es scheint, dass mir hier etwas Grundlegendes fehlt. Ich habe auch versucht, das alte und gute Bluebird NPM hinzuzufügen, aber es sieht so aus, als würde es nicht funktionieren.

Wie verwende ich die Polyfills von Babel?

Shlomi
quelle
1
npm install _name_
Dandavis
1
HINWEIS: Babel hat jetzt ein separates NPM-Paket dafür: babel-polyfill
Stijn de Witt
1
@StijndeWitt nur um Ihnen einen Klick zu ersparen, hier ist die vollständige README.md-Datei in Vollversion:
Gurghet
1
@gurghet Ja, sie hätten dort weitere Informationen hinzufügen können, da stimme ich zu :) Aber alles, was Sie wirklich wissen müssen, ist npm install --save babel-polyfillund require('babel-polyfill).
Stijn de Witt
1
Da Sie ES6 verwenden, können Sie auch den Import "babel-polyfill" verwenden.
Liebe Hasija

Antworten:

66

Dies hat sich in babel v6 etwas geändert.

Aus den Dokumenten:

Die Polyfüllung emuliert eine vollständige ES6-Umgebung. Diese Polyfüllung wird bei Verwendung von babel-node automatisch geladen.

Installation:
$ npm install babel-polyfill

Verwendung in Node / Browserify / Webpack:
Um die Polyfüllung einzuschließen , müssen Sie sie oben am Einstiegspunkt Ihrer Anwendung benötigen.
require("babel-polyfill");

Verwendung im Browser:
Verfügbar aus der dist/polyfill.jsDatei innerhalb einer babel-polyfillnpm-Version. Dies muss vor dem gesamten kompilierten Babel-Code enthalten sein. Sie können es entweder Ihrem kompilierten Code voranstellen oder in a einfügen<script> davor stehenden .

HINWEIS: requireVerwenden Sie dies nicht über browserify usw., verwenden Sie babel-polyfill.

vdclouis
quelle
6
Ich bin mir immer noch nicht ganz sicher, wann die Polyfüllung benötigt wird. Warum funktionieren ES6-Module nur mit babel.js, Array.protorype.findIndex()aber nicht ohne Polyfill, und babel löst beim Transpilieren keine Ausnahme aus? Ist das die Natur eines Polyfill ™?
RemEmber
5
Grundsätzlich besteht Babel Polyfill nur aus github.com/facebook/regenerator und github.com/zloirock/core-js . Schauen Sie sich diese 2 Repos an, um zu wissen, ob Sie die Polyfills tatsächlich benötigen.
Vdclouis
7
Ich denke, der Grund, warum einer funktioniert und der andere nicht, ist, dass Babel beim Transpilieren auf eine hypothetische JS-Engine mit einem gewissen Grad an Unterstützung abzielt. Echte Browser unterstützen möglicherweise mehr oder weniger als diese hypothetische Engine. In der Praxis denke ich, dass der hypothetische Browser, auf den sie abzielen, irgendwo auf der IE10-Ebene liegt, sodass ältere Browser möglicherweise einige Probleme haben. Indem sie die Korrekturen dafür in eine separate Polyfüllung einfügen, überlassen sie Ihnen die Entscheidung, ob Sie solche älteren Browser unterstützen möchten. Ein bisschen wie jQuery mit dem 1.0-Zweig, der dies tut, und dem 2.0-Zweig, der IE8 nicht unterstützt. @ RemEmber
Stijn de Witt
2
@dougmacklin Wenn findIndex die einzige Polyfüllung ist, die Sie benötigen, können Sie diese einfach irgendwo in Ihren Code aufnehmen. Überprüfen Sie MDN auf Polyfills: developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
vdclouis
1
@vdclouis, wie würden Sie vorgehen, um diesen Polyfill-Code per Webpack einzuschließen, damit er überall im Projekt verfügbar ist?
Dougmacklin
48

Die Babel-Dokumente beschreiben dies ziemlich kurz:

Babel enthält eine Polyfüllung, die eine benutzerdefinierte Regenerator-Laufzeit und core.js enthält.

Dadurch wird eine vollständige ES6-Umgebung emuliert. Diese Polyfüllung wird bei Verwendung von babel-node und babel / register automatisch geladen.

Stellen Sie sicher, dass Sie es am Einstiegspunkt Ihrer Anwendung benötigen, bevor etwas anderes aufgerufen wird. Wenn Sie ein Tool wie Webpack verwenden, wird dies ziemlich einfach (Sie können Webpack anweisen, es in das Bundle aufzunehmen).

Wenn Sie ein Tool wie gulp-babeloder verwenden babel-loader, müssen Sie auch das babelPaket selbst installieren , um die Polyfüllung zu verwenden.

Beachten Sie auch, dass Sie für Module, die sich auf den globalen Bereich auswirken (Polyfills und dergleichen), einen knappen Import verwenden können, um zu vermeiden, dass nicht verwendete Variablen in Ihrem Modul enthalten sind:

import 'babel/polyfill';
ssube
quelle
4
Nur um eine Notiz hinzuzufügen, und ich bin nicht 100% sicher, ob dies völlig korrekt ist, aber ich habe versucht, nur import 'babel-core/polyfill'ohne Installation zu verwenden, babelund es hat gut funktioniert.
Nathan Lutterman
2
Zaemz , ich denke du hast Babel bereits installiert, also import 'babel-core/polifyll'funktioniert es. Ich habe es ohne Installation versucht babelund es hat bei mir nicht funktioniert. Übrigens: Ssube Advice funktioniert.
WebBrother
4
Wo fügen Sie Webpack ein, wenn Sie es verwenden?
Theptrk
2
@theptrk Mit webpack können Sie es einfach als Modul importieren, da webpack das Importieren von npm-Paketen ermöglicht. Für Karma richten Sie es als Datei ein , die vor dem Testen aufgenommen werden soll.
ssube
3
Danke, vielleicht hatte ich eine andere Version, aber ich musste stattdessen babel-core verwenden => "import 'babel-core / polyfill';
theptrk
22

Wenn Sie in Babel Version 7 @ babel / preset-env verwenden, müssen Sie zum Einschließen von Polyfill lediglich ein Flag 'useBuiltIns' mit dem Wert 'usage' in Ihre Babel-Konfiguration einfügen. Es ist nicht erforderlich, Polyfill am Einstiegspunkt Ihrer App zu benötigen oder zu importieren.

Mit diesem Flag wird babel @ 7 optimiert und enthält nur die Polyfills, die Sie benötigen.

So verwenden Sie dieses Flag nach der Installation:

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

Fügen Sie einfach die Flagge hinzu:

useBuiltIns: "usage" 

in Ihre Babel-Konfigurationsdatei mit dem Namen "babel.config.js" (ebenfalls neu in Babel @ 7) im Abschnitt "@ babel / env":

// file: babel.config.js

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

   return { presets };
};

Referenz:


Update August 2019:

Mit der Veröffentlichung von Babel 7.4.0 (19. März 2019) ist @ babel / polyfill veraltet. Anstatt @ babe / polyfill zu installieren, installieren Sie core-js:

npm install --save core-js@3

Ein neuer Eintrag corejswird zu Ihrer babel.config.js hinzugefügt

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

siehe Beispiel: https://github.com/ApolloTang/stackoverflow-eg--babel-v7.4.0-polyfill-w-core-v3

Referenz:

Apollo
quelle
1
Verwenden Sie dies in der Produktion env? irgendein Risiko?
Roy
useBuiltIns: "usage"funktioniert nicht auf meiner Seite. Es enthält einfach keine Polydateien im Bundle (Beispiel: Ich verwende Generatoren und erhalte die Fehlermeldung "regeneratorRuntime is not defined"). Irgendwelche Ideen?
WebBrother
@ WebBrother, funktioniert für mich ... siehe zB: github.com/ApolloTang/stackoverflow-eg--babel-polyfill
Apollo
@ Roy, ich bin gerade dabei, ein Unternehmensprojekt von babel @ 6 auf babel @ 7 zu migrieren, damit ich @ babel / preset-typescript verwenden kann. Dies ist noch in Arbeit, aber ich folge den Anweisungen aus dem offiziellen Dokument von babel (siehe Referenzlinks in meiner Antwort). Bisher scheint alles zu funktionieren, aber ich habe meine Migrations- / Upgrade-Arbeit noch nicht an QA gesendet. Ich werde hier posten, wenn ein Problem auftritt.
Apollo
19

Wenn Ihre package.json ungefähr so ​​aussieht:

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

Und Sie erhalten die Cannot find module 'babel/polyfill'Fehlermeldung, dann müssen Sie wahrscheinlich nur Ihre Importanweisung ändern FROM:

import "babel/polyfill";

ZU:

import "babel-polyfill";

Und stellen Sie sicher, dass es vor jeder anderen importAussage steht (nicht unbedingt am Einstiegspunkt Ihrer Bewerbung).

Referenz: https://babeljs.io/docs/usage/polyfill/

l3x
quelle
3
In dieser Antwort ist das babel-polyfill-Paket unter 'devDependencies' aufgeführt. Dies führt dazu, dass Babel-Polyfill nicht in der Bereitstellung enthalten ist. Sie sollten babel-polyfill nicht mit dem Flag -D, sondern mit dem Flag -S installieren, damit es unter "Abhängigkeiten" aufgeführt und daher in Ihrer Bereitstellung enthalten ist.
Apollo
9

Zunächst einmal, die offensichtliche Antwort, die niemand gegeben hat, müssen Sie Babel in Ihre Anwendung installieren:

npm install babel --save

(oder babel-corewenn Sie stattdessen möchten require('babel-core/polyfill')).

Abgesehen davon habe ich eine grunzende Aufgabe, meine es6 und jsx als Build-Schritt zu transpilieren (dh ich möchte sie nicht verwenden babel/register, weshalb ich versuche, sie babel/polyfilldirekt zu verwenden ), also würde ich es gerne tun Legen Sie mehr Wert auf diesen Teil der Antwort von @ ssube:

Stellen Sie sicher, dass Sie es am Einstiegspunkt Ihrer Anwendung benötigen, bevor etwas anderes aufgerufen wird

Ich bin auf ein seltsames Problem gestoßen, bei dem ich versucht habe, eine babel/polyfillStartdatei für eine gemeinsam genutzte Umgebung zu benötigen, und ich habe den Fehler erhalten, auf den der Benutzer verwiesen hat. Ich denke, es hat möglicherweise etwas damit zu tun, wie Babel Importe im Vergleich zu Anforderungen bestellt, aber ich kann sie nicht reproduzieren jetzt. Das Verschieben import 'babel/polyfill'als erste Zeile in meinen Client- und Server-Startskripten hat das Problem behoben.

Beachten Sie, dass require('babel/polyfill')ich , wenn Sie stattdessen verwenden möchten, sicherstellen würde, dass alle Ihre anderen Modulladeranweisungen ebenfalls erforderlich sind, und keine Importe verwenden - vermeiden Sie das Mischen der beiden. Mit anderen Worten, wenn Sie Importanweisungen in Ihrem Startskript haben, machen Sie import babel/polyfilldie erste Zeile in Ihrem Skript anstatt require('babel/polyfill').

ChetPrickles
quelle
9
Sie müssen nicht sudomit npm docs.npmjs.com/getting-started/fixing-npm-permissions
Vladimir
8

Mit babel-polyfill können Sie alle ES6-Funktionen über Syntaxänderungen hinaus nutzen. Dies umfasst Funktionen wie neue integrierte Objekte wie Promises und WeakMap sowie neue statische Methoden wie Array.from oder Object.assign.

Ohne babel-polyfill können Sie mit babel nur Funktionen wie Pfeilfunktionen, Destrukturierung, Standardargumente und andere in ES6 eingeführte syntaxspezifische Funktionen verwenden.

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
quelle
0

Wie Babel in den Dokumenten sagt , ist für Babel> 7.4.0 das Modul @ babel / polyfill veraltet , daher wird empfohlen, direkt core-js und regenerator-runtime zu verwenden , die zuvor in @ babel / polyfill enthalten waren.

Das hat also bei mir funktioniert:

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

Fügen Sie dann ganz oben in Ihrer anfänglichen js-Datei Folgendes hinzu:

import 'core-js/stable';
import 'regenerator-runtime/runtime';
Fred K.
quelle