¿Cómo instalo la biblioteca babel-polyfill?

140

Acabo de comenzar a usar Babel para compilar mi código JavaScript ES6 en ES5. Cuando empiezo a usar Promesas parece que no está funcionando. El sitio web de Babel indica el apoyo a las promesas a través de polyfills.

Sin suerte, intenté agregar:

require("babel/polyfill");

o

import * as p from "babel/polyfill";

Con eso obtendré el siguiente error en el arranque de mi aplicación:

No se puede encontrar el módulo 'babel / polyfill'

Busqué el módulo pero parece que me falta algo fundamental aquí. También traté de agregar el antiguo y bueno bluebird NPM, pero parece que no funciona.

¿Cómo usar los polyfills de Babel?

Shlomi
fuente
1
npm install _name_
dandavis
1
NOTA: Babel ahora tiene un paquete NPM separado para esto: babel-polyfill
Stijn de Witt
1
@StijndeWitt solo para ahorrarle un clic, aquí está el archivo README.md completo en versión completa:
gurghet
1
@gurghet Sí, podrían haber agregado más información allí Estoy de acuerdo :) Pero todo lo que realmente necesita saber es npm install --save babel-polyfilly require('babel-polyfill).
Stijn de Witt
1
Como está utilizando ES6, también puede usar la importación "babel-polyfill".
Love Hasija

Respuestas:

66

Esto cambió un poco en babel v6.

De los documentos:

El polyfill emulará un entorno ES6 completo. Este polyfill se carga automáticamente cuando se usa babel-node.

Instalación:
$ npm install babel-polyfill

Uso en Node / Browserify / Webpack:
para incluir el polyfill, debe solicitarlo en la parte superior del punto de entrada a su aplicación.
require("babel-polyfill");

Uso en el navegador:
disponible desde el dist/polyfill.jsarchivo dentro de una babel-polyfillversión npm. Esto debe incluirse antes de todo el código compilado de Babel. Puede anteponerlo a su código compilado o incluirlo en un <script>antes.

NOTA: No haga requireesto a través de browserify, etc., use babel-polyfill.

vdclouis
fuente
66
Todavía no estoy completamente seguro de cuándo se necesita el polyfill. ¿Por qué los módulos ES6 solo funcionan con babel.js pero Array.protorype.findIndex()no funcionan sin el polyfill y babel no generará una excepción cuando se transpile? ¿Es esa la naturaleza de un Polyfill ™?
RemEmber
55
Básicamente, el polyfill de Babel es solo github.com/facebook/regenerator y github.com/zloirock/core-js combinados. Echa un vistazo a esos 2 repos para saber si realmente necesitas los polyfills.
vdclouis
77
Creo que la razón por la que uno funciona y el otro no es que Babel, al transpirar, apunta a un motor JS hipotético con un cierto nivel de soporte. Los navegadores reales pueden terminar soportando más o menos que este motor hipotético. En la práctica, creo que el navegador hipotético al que apuntan está en algún lugar del nivel IE10, por lo que los navegadores más antiguos pueden tener algunos problemas. Al poner las soluciones para esto en un polyfill por separado, dejan la decisión de si desea admitir navegadores más antiguos para usted. Un poco como jQuery con su rama 1.0 que lo hace y la rama 2.0 que no es compatible con IE8. @RemEmber
Stijn de Witt
2
@dougmacklin si findIndex es el único polyfill que necesita, puede incluirlo en algún lugar de su código. Verifique MDN para polyfills: developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
vdclouis
1
@vdclouis, ¿cómo haría para incluir ese código de polyfill a través de webpack para que esté disponible en todas partes del proyecto?
dougmacklin
48

Los documentos de Babel describen esto de manera muy concisa:

Babel incluye un polyfill que incluye un tiempo de ejecución de regenerador personalizado y core.js.

Esto emulará un entorno ES6 completo. Este polyfill se carga automáticamente cuando se usa babel-node y babel / register.

Asegúrese de requerirlo en el punto de entrada de su aplicación, antes de llamar a cualquier otra cosa. Si está utilizando una herramienta como webpack, eso se vuelve bastante simple (puede decirle a webpack que lo incluya en el paquete).

Si está utilizando una herramienta como gulp-babelo babel-loader, también necesita instalar el babelpaquete para usar el polyfill.

También tenga en cuenta que para los módulos que afectan el alcance global (polyfills y similares), puede usar una importación concisa para evitar tener variables no utilizadas en su módulo:

import 'babel/polyfill';
ssube
fuente
44
Solo para agregar una nota, y no estoy 100% seguro de si esto es completamente correcto, pero intenté usarlo import 'babel-core/polyfill'sin instalarlo babely funcionó bien.
Nathan Lutterman
2
Zaemz , supongo que ya has instalado Babel, así que import 'babel-core/polifyll'funciona. Lo probé sin instalar babely no funcionó para mí. Por cierto: ssube advice funciona.
WebBrother
44
Al usar el paquete web, ¿dónde lo incluye?
theptrk
2
@theptrk Usando webpack, simplemente puede importarlo como un módulo, ya que webpack permite importar paquetes npm. Para Karma, lo configura como un archivo que se incluirá antes de las pruebas.
ssube
3
Gracias, tal vez tenía una versión diferente pero tenía que usar babel-core en su lugar => "import 'babel-core / polyfill';
theptrk
22

Para la versión 7 de Babel, si está utilizando @ babel / preset-env, para incluir polyfill todo lo que tiene que hacer es agregar un indicador 'useBuiltIns' con el valor de 'uso' en su configuración de babel. No es necesario exigir ni importar polyfill en el punto de entrada de su aplicación.

Con esta bandera especificada, babel @ 7 optimizará y solo incluirá los polyfills que necesita.

Para usar esta bandera, después de la instalación:

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

Simplemente agregue la bandera:

useBuiltIns: "usage" 

a su archivo de configuración de babel llamado "babel.config.js" (también nuevo en Babel @ 7), en la sección "@ babel / env":

// file: babel.config.js

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

   return { presets };
};

Referencia:


Actualización de agosto de 2019:

Con el lanzamiento de Babel 7.4.0 (19 de marzo de 2019) @ babel / polyfill está en desuso. En lugar de instalar @ babe / polyfill, instalará core-js:

npm install --save core-js@3

Se corejsagrega una nueva entrada a su 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 };
};

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

Referencia:

Apolo
fuente
1
¿Usas esto en producción env? cualquier riesgo?
Roy
useBuiltIns: "usage"No funciona de mi lado. Simplemente no incluye ningún polyfils en el paquete (ejemplo: uso generadores y aparece el error "regeneratorRuntime no está definido"). ¿Algunas ideas?
WebBrother
@WebBrother, funciona para mí ... ver por ejemplo: github.com/ApolloTang/stackoverflow-eg--babel-polyfill
apollo
@Roy, en realidad estoy en el proceso de migrar un proyecto empresarial de babel @ 6 a babel @ 7 para poder usar @ babel / preset-typescript. Esto todavía es un trabajo en progreso, pero estoy siguiendo las instrucciones del documento oficial de Babel (ver enlaces de referencia en mi respuesta). Hasta ahora todo parece estar funcionando, pero todavía no he enviado mi trabajo de migración / actualización a QA, lo publicaré aquí si surge algún problema.
Apolo
19

Si su package.json se parece a lo siguiente:

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

Y recibe el Cannot find module 'babel/polyfill'mensaje de error, entonces probablemente solo necesite cambiar su declaración de importación DE:

import "babel/polyfill";

A:

import "babel-polyfill";

Y asegúrese de que aparezca antes de cualquier otra importdeclaración (no necesariamente en el punto de entrada de su solicitud).

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

l3x
fuente
3
En esta respuesta, el paquete babel-polyfill aparece en la lista 'devDependencies'. Hacer esto resultará en babel-polyfill no incluido en la implementación. No debe instalar babel-polyfill con el distintivo -D sino con el distintivo -S para que aparezca en la lista de 'dependencias' y, por lo tanto, se incluya en su implementación.
Apolo
9

En primer lugar, la respuesta obvia que nadie ha proporcionado, debe instalar Babel en su aplicación:

npm install babel --save

(o babel-coresi en cambio quieresrequire('babel-core/polyfill') ).

Aparte de eso, tengo una tarea difícil para recopilar mi es6 y jsx como un paso de compilación (es decir, no quiero usar babel/register, por eso estoy tratando de usar babel/polyfilldirectamente en primer lugar), así que me gustaría Pon más énfasis en esta parte de la respuesta de @ssube:

Asegúrese de requerirlo en el punto de entrada de su aplicación, antes de llamar a cualquier otra cosa

Me encontré con un problema extraño en el que estaba tratando de babel/polyfillsolicitar un archivo de inicio de entorno compartido y recibí el error al que hizo referencia el usuario: creo que podría haber tenido algo que ver con la forma en que Babel ordena la importación versus la que requiere, pero no puedo reproducir ahora. De todos modos, moverme import 'babel/polyfill'como la primera línea en los scripts de inicio de mi cliente y servidor solucionó el problema.

Tenga en cuenta que si en su lugar desea usar, require('babel/polyfill')me aseguraría de que todas las demás declaraciones del cargador de módulos también sean necesarias y no utilicen importaciones; evite mezclar las dos. En otras palabras, si tiene alguna declaración de importación en su script de inicio, haga import babel/polyfillla primera línea en su script en lugar de require('babel/polyfill').

ChetPrickles
fuente
9
no necesita ejecutar sudocon npm docs.npmjs.com/getting-started/fixing-npm-permissions
Vladimir Starkov
8

babel-polyfill le permite usar el conjunto completo de funciones de ES6 más allá de los cambios de sintaxis. Esto incluye características como nuevos objetos integrados como Promises y WeakMap, así como nuevos métodos estáticos como Array.from u Object.assign.

Sin babel-polyfill, babel solo le permite usar características como funciones de flecha, desestructuración, argumentos predeterminados y otras características específicas de sintaxis introducidas en 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
fuente
0

Como dice Babel en el documentos , para Babel> 7.4.0 el módulo @ babel / polyfill está en desuso , por lo que se recomienda utilizar directamente las bibliotecas core-js y regenerator-runtime que antes se incluían en @ babel / polyfill.

Entonces esto funcionó para mí:

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

luego agregue a la parte superior de su archivo js inicial:

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