Comment installer la bibliothèque babel-polyfill?

140

Je viens de commencer à utiliser Babel pour compiler mon code javascript ES6 dans ES5. Lorsque je commence à utiliser Promises, il semble que cela ne fonctionne pas. Le site Web de Babel déclare soutenir les promesses via les polyfills.

Sans aucune chance, j'ai essayé d'ajouter:

require("babel/polyfill");

ou

import * as p from "babel/polyfill";

Avec cela, j'obtiendrai l'erreur suivante sur le démarrage de mon application:

Impossible de trouver le module 'babel / polyfill'

J'ai cherché le module mais il me semble qu'il me manque quelque chose de fondamental ici. J'ai également essayé d'ajouter l'ancien et bon NPM bluebird, mais il semble que cela ne fonctionne pas.

Comment utiliser les polyfills de Babel?

Shlomi
la source
1
npm install _name_
dandavis le
1
REMARQUE: Babel a maintenant un package NPM séparé pour cela: babel-polyfill
Stijn de Witt
1
@StijndeWitt juste pour vous faire gagner un clic, voici le fichier README.md complet en version complète:
gurghet
1
@gurghet Oui, ils auraient pu ajouter plus d'informations, je suis d'accord :) Mais tout ce que vous devez vraiment savoir, c'est npm install --save babel-polyfillet require('babel-polyfill).
Stijn de Witt
1
Puisque vous utilisez ES6, vous pouvez également utiliser l'importation "babel-polyfill".
Love Hasija

Réponses:

66

Cela a un peu changé dans babel v6.

À partir de la documentation:

Le polyfill émulera un environnement ES6 complet. Ce polyfill est automatiquement chargé lors de l'utilisation de babel-node.

Installation:
$ npm install babel-polyfill

Utilisation dans Node / Browserify / Webpack:
Pour inclure le polyfill, vous devez l'exiger en haut du point d'entrée de votre application.
require("babel-polyfill");

Utilisation dans le navigateur:
disponible à partir du dist/polyfill.jsfichier dans une babel-polyfillversion npm. Cela doit être inclus avant tout votre code Babel compilé. Vous pouvez soit l'ajouter à votre code compilé, soit l'inclure dans un <script>avant.

REMARQUE: ne faites pas requirecela via browserify etc, utilisez babel-polyfill.

vdclouis
la source
6
Je ne suis toujours pas tout à fait sûr du moment où le polyfill est nécessaire. Pourquoi les modules ES6 fonctionnent-ils simplement avec babel.js mais Array.protorype.findIndex()ne fonctionnent pas sans le polyfill et babel ne lèvera pas d'exception lors de la transpilation? Est-ce la nature d'un Polyfill ™?
RemEmber
5
Fondamentalement, Babel polyfill est simplement github.com/facebook/regenerator et github.com/zloirock/core-js combinés. Consultez ces 2 dépôts pour savoir si vous avez réellement besoin des polyfills.
vdclouis
7
Je pense que la raison pour laquelle l'une fonctionne et l'autre non, c'est que Babel, lors du transpilage, cible un hypothétique moteur JS avec un certain niveau de support. Les vrais navigateurs peuvent finir par supporter plus ou moins que ce moteur hypothétique. En pratique, je pense que le navigateur hypothétique qu'ils ciblent se situe quelque part au niveau d'IE10, de sorte que les navigateurs plus anciens peuvent avoir des problèmes. En plaçant les correctifs pour cela dans un polyfill séparé, ils vous laissent la décision de prendre en charge ces anciens navigateurs. Un peu comme jQuery avec sa branche 1.0 qui le fait et sa branche 2.0 qui ne prend pas en charge IE8. @RemEmber
Stijn de Witt
2
@dougmacklin si findIndex est le seul polyfill dont vous avez besoin, vous pouvez simplement l'inclure quelque part dans votre code. Vérifiez MDN pour les polyfills: developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
vdclouis
1
@vdclouis, comment feriez-vous pour inclure ce code polyfill via webpack pour qu'il soit disponible partout dans le projet?
dougmacklin
48

La documentation Babel décrit cela de manière assez concise:

Babel inclut un polyfill qui inclut un runtime de régénérateur personnalisé et core.js.

Cela émulera un environnement ES6 complet. Ce polyfill est automatiquement chargé lors de l'utilisation de babel-node et babel / register.

Assurez-vous que vous en avez besoin au point d'entrée de votre application, avant tout autre appel. Si vous utilisez un outil comme webpack, cela devient assez simple (vous pouvez dire à webpack de l'inclure dans le bundle).

Si vous utilisez un outil comme gulp-babelou babel-loader, vous devez également installer le babelpackage lui-même pour utiliser le polyfill.

Notez également que pour les modules qui affectent la portée globale (polyfills et autres), vous pouvez utiliser une importation laconique pour éviter d'avoir des variables inutilisées dans votre module:

import 'babel/polyfill';
ssube
la source
4
Juste pour ajouter une note, et je ne suis pas sûr à 100% si cela est tout à fait correct, mais j'ai essayé de simplement utiliser import 'babel-core/polyfill'sans installer babelet cela a très bien fonctionné.
Nathan Lutterman
2
Zaemz , je suppose que vous avez déjà installé babel, donc ça import 'babel-core/polifyll'marche. Je l'ai essayé sans l'installation babelet cela n'a pas fonctionné pour moi. Au fait: ssube conseille fonctionne.
WebBrother
4
Lorsque vous utilisez Webpack, où l'incluez-vous?
theptrk
2
@theptrk En utilisant webpack, vous pouvez simplement l'importer en tant que module, car webpack permet d'importer des packages npm. Pour Karma, vous le configurez comme un fichier à inclure avant les tests.
ssube du
3
Merci, j'avais peut-être une version différente mais j'ai dû utiliser babel-core à la place => "import 'babel-core / polyfill';
theptrk
22

Pour Babel version 7, si vous utilisez @ babel / preset-env, pour inclure polyfill, tout ce que vous avez à faire est d'ajouter un indicateur 'useBuiltIns' avec la valeur 'usage' dans votre configuration babel. Il n'est pas nécessaire d'exiger ou d'importer polyfill au point d'entrée de votre application.

Avec cet indicateur spécifié, babel @ 7 optimisera et n'inclura que les polyfills dont vous avez besoin.

Pour utiliser cet indicateur, après l'installation:

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

Ajoutez simplement le drapeau:

useBuiltIns: "usage" 

dans votre fichier de configuration babel appelé "babel.config.js" (également nouveau dans Babel @ 7), dans la section "@ babel / env":

// file: babel.config.js

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

   return { presets };
};

Référence:


Mise à jour août 2019:

Avec la sortie de Babel 7.4.0 (19 mars 2019), @ babel / polyfill est obsolète. Au lieu d'installer @ babe / polyfill, vous installerez core-js:

npm install --save core-js@3

Une nouvelle entrée corejsest ajoutée à votre 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 };
};

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

Référence:

Apollon
la source
1
Utilisez-vous cela dans l'environnement de production? un risque?
Roy
useBuiltIns: "usage"ne fonctionne pas de mon côté. Il n'inclut tout simplement aucun polyfils dans le bundle (exemple: j'utilise des générateurs et j'obtiens une erreur "regeneratorRuntime is not defined"). Des idées?
WebBrother
@WebBrother, fonctionne pour moi ... voir par exemple: github.com/ApolloTang/stackoverflow-eg--babel-polyfill
apollo
@Roy, je suis actuellement en train de migrer un projet d'entreprise de babel @ 6 vers babel @ 7 afin de pouvoir utiliser @ babel / preset-typescript. C'est toujours un travail en cours, mais je suis les instructions du document officiel de babel (voir les liens de référence dans ma réponse). Jusqu'à présent, tout semble fonctionner, mais je n'ai pas encore envoyé mon travail de migration / mise à niveau au QA, je posterai ici si un problème survient.
apollo
19

Si votre package.json ressemble à ceci:

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

Et vous obtenez le Cannot find module 'babel/polyfill'message d'erreur, il vous suffit probablement de modifier votre instruction d'importation FROM:

import "babel/polyfill";

À:

import "babel-polyfill";

Et assurez-vous qu'il vient avant toute autre importdéclaration (pas nécessairement au point d'entrée de votre application).

Référence: https://babeljs.io/docs/usage/polyfill/

l3x
la source
3
Dans cette réponse, le paquet babel-polyfill est répertorié sous 'devDependencies'. Faire cela entraînera babel-polyfill non inclus dans le déploiement. Vous ne devez pas installer babel-polyfill avec l'option -D mais avec l'option -S pour qu'elle soit répertoriée sous «dépendances», et donc incluse dans votre déploiement.
apollo
9

Tout d'abord, la réponse évidente que personne n'a fournie, vous devez installer Babel dans votre application:

npm install babel --save

(ou babel-coresi vous le souhaitez require('babel-core/polyfill')).

En dehors de cela, j'ai une tâche difficile de transpiler mon es6 et jsx en tant qu'étape de construction (c'est-à-dire que je ne veux pas utiliser babel/register, c'est pourquoi j'essaie d'utiliser babel/polyfilldirectement en premier lieu), alors j'aimerais mettre davantage l'accent sur cette partie de la réponse de @ ssube:

Assurez-vous d'en avoir besoin au point d'entrée de votre application, avant que quoi que ce soit d'autre ne soit appelé

J'ai rencontré un problème étrange où j'essayais d'exiger babel/polyfilld'un fichier de démarrage d'environnement partagé et j'ai eu l'erreur référencée par l'utilisateur - je pense que cela pourrait avoir quelque chose à voir avec la façon dont babel commande les importations par rapport aux demandes, mais je suis incapable de reproduire maintenant. Quoi qu'il en soit, le déplacement en import 'babel/polyfill'tant que première ligne dans mes scripts de démarrage client et serveur a résolu le problème.

Notez que si vous souhaitez utiliser à la place, require('babel/polyfill')je m'assurerai que toutes vos autres instructions de chargeur de module sont également obligatoires et n'utilisent pas d'importations - évitez de mélanger les deux. En d'autres termes, si vous avez des instructions d'importation dans votre script de démarrage, créez import babel/polyfillla première ligne de votre script plutôt que require('babel/polyfill').

ChetPrickles
la source
9
vous n'avez pas besoin de courir sudoavec npm docs.npmjs.com/getting-started/fixing-npm-permissions
Vladimir Starkov
8

babel-polyfill vous permet d'utiliser l'ensemble complet des fonctionnalités ES6 au-delà des changements de syntaxe. Cela inclut des fonctionnalités telles que de nouveaux objets intégrés tels que Promises et WeakMap, ainsi que de nouvelles méthodes statiques telles que Array.from ou Object.assign.

Sans babel-polyfill, babel vous permet uniquement d'utiliser des fonctionnalités telles que les fonctions fléchées, la déstructuration, les arguments par défaut et d'autres fonctionnalités spécifiques à la syntaxe introduites dans 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
la source
0

Comme Babel le dit dans la documentation , pour Babel> 7.4.0 le module @ babel / polyfill est obsolète , il est donc recommandé d'utiliser directement les bibliothèques core-js et regenerator-runtime qui auparavant étaient incluses dans @ babel / polyfill.

Donc, cela a fonctionné pour moi:

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

puis ajoutez tout en haut de votre fichier js initial:

import 'core-js/stable';
import 'regenerator-runtime/runtime';
Fred K
la source