Como instalo a biblioteca babel-polyfill?

140

Comecei a usar o Babel para compilar meu código javascript ES6 no ES5. Quando começo a usar o Promises, parece que não está funcionando. O site da Babel declara suporte a promessas via polyfills.

Sem sorte, tentei acrescentar:

require("babel/polyfill");

ou

import * as p from "babel/polyfill";

Com isso, receberei o seguinte erro no bootstrap do aplicativo:

Não foi possível encontrar o módulo 'babel / polyfill'

Eu procurei pelo módulo, mas parece que estou perdendo alguma coisa fundamental aqui. Também tentei adicionar o NPM bluebird antigo e bom, mas parece que ele não está funcionando.

Como usar os polyfills da Babel?

Shlomi
fonte
1
npm install _name_
dandavis
1
OBSERVAÇÃO: O Babel agora tem um pacote NPM separado para isso: babel-polyfill
Stijn de Witt
1
@StijndeWitt apenas para poupar um clique, aqui está o arquivo README.md completa na versão completa:
gurghet
1
@ gurghet Sim, eles poderiam ter acrescentado mais algumas informações, eu concordo :) Mas tudo o que você realmente precisa saber é npm install --save babel-polyfille require('babel-polyfill).
Stijn de Witt
1
Como você está usando o ES6, também é possível usar a importação "babel-polyfill".
Love Hasija

Respostas:

66

Isso mudou um pouco no babel v6.

Dos documentos:

O polyfill emulará um ambiente completo do ES6. Esse polyfill é carregado automaticamente ao usar o nó babel.

Instalação:
$ npm install babel-polyfill

Uso no Node / Browserify / Webpack:
Para incluir o polyfill, você precisa solicitá-lo na parte superior do ponto de entrada do seu aplicativo.
require("babel-polyfill");

Uso no navegador:
disponível no dist/polyfill.jsarquivo em um babel-polyfillrelease npm. Isso precisa ser incluído antes de todo o seu código Babel compilado. Você pode anexá-lo ao seu código compilado ou incluí-lo em um <script>antes dele.

NOTA: Não faça requireisso via browserify etc, use babel-polyfill.

vdclouis
fonte
6
Ainda não tenho certeza de quando é necessário o polyfill. Por que os módulos ES6 funcionam apenas com o babel.js, mas Array.protorype.findIndex()não funcionam sem o polyfill e o babel não gera uma exceção quando está transpilando? Essa é a natureza de um Polyfill ™?
Remember
5
Basicamente, o polyfill Babel é apenas github.com/facebook/regenerator e github.com/zloirock/core-js combinados. Confira esses 2 repositórios para saber se você realmente precisa dos polyfills.
vdclouis
7
Acho que o motivo pelo qual um funciona e o outro não é que Babel, ao transpilar, tem como alvo um mecanismo JS hipotético com um certo nível de suporte. Navegadores reais podem acabar suportando mais ou menos que esse mecanismo hipotético. Na prática, acho que o navegador hipotético que eles segmentam está em algum lugar no nível IE10, portanto, navegadores mais antigos podem ter alguns problemas. Ao colocar as correções para isso em um polyfill separado, eles decidem se você deseja oferecer suporte a navegadores mais antigos. Um pouco como o jQuery, com o ramo 1.0, e o ramo 2.0, que não suporta o IE8. @RemEmber
Stijn de Witt
2
@dougmacklin se findIndex é o único polyfill que você precisa, você pode apenas incluir esse em algum lugar do seu código. Verifique MDN para polyfills: developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
vdclouis
1
@vdclouis, como você incluiria esse código polyfill via webpack para que ele esteja disponível em qualquer lugar do projeto?
Dougmacklin
48

Os documentos de Babel descrevem isso de forma bastante concisa:

O Babel inclui um polyfill que inclui um tempo de execução do regenerador personalizado e core.js.

Isso emulará um ambiente completo do ES6. Esse polyfill é carregado automaticamente ao usar o babel-node e o babel / register.

Certifique-se de solicitá-lo no ponto de entrada do seu aplicativo antes que qualquer outra coisa seja chamada. Se você estiver usando uma ferramenta como o webpack, isso se torna bastante simples (você pode dizer ao webpack para incluí-lo no pacote).

Se você estiver usando uma ferramenta como gulp-babelou babel-loader, também precisará instalar o babelpróprio pacote para usar o polyfill.

Observe também que, para os módulos que afetam o escopo global (polyfills e similares), você pode usar uma importação concisa para evitar ter variáveis ​​não utilizadas em seu módulo:

import 'babel/polyfill';
ssube
fonte
4
Só para adicionar uma observação, e não tenho 100% de certeza se isso está totalmente correto, mas tentei usar import 'babel-core/polyfill'sem instalar babele funcionou muito bem.
Nathan Lutterman
2
Zaemz , acho que você já instalou o babel, então import 'babel-core/polifyll'funciona. Eu tentei sem instalar babele não funcionou para mim. By the way: ssube aconselhar funciona.
WebBrother 12/08/2015
4
Ao usar o webpack, onde você o inclui?
theptrk
2
@theptrk Usando o webpack, você pode simplesmente importá-lo como um módulo, já que o webpack permite importar pacotes npm. Para o Karma, você o configura como um arquivo a ser incluído antes dos testes.
ssube
3
Obrigado, talvez eu tenha uma versão diferente, mas precisei usar o babel-core => "import 'babel-core / polyfill';
theptrk
22

Para o Babel versão 7, se você estiver usando @ babel / preset-env, para incluir o polyfill, basta adicionar um sinalizador 'useBuiltIns' com o valor de 'use' na sua configuração do babel. Não há necessidade de solicitar ou importar o polyfill no ponto de entrada do seu aplicativo.

Com esse sinalizador especificado, o babel @ 7 otimizará e incluirá apenas os polyfills necessários.

Para usar esse sinalizador, após a instalação:

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

Basta adicionar a bandeira:

useBuiltIns: "usage" 

ao seu arquivo de configuração babel chamado "babel.config.js" (também novo no Babel @ 7), na seção "@ babel / env":

// file: babel.config.js

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

   return { presets };
};

Referência:


Atualizar agosto de 2019:

Com o lançamento do Babel 7.4.0 (19 de março de 2019), o babel / polyfill foi descontinuado. Em vez de instalar o @ babe / polyfill, você instalará o core-js:

npm install --save core-js@3

Uma nova entrada corejsé adicionada ao seu 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 };
};

veja o exemplo: https://github.com/ApolloTang/stackoverflow-eg--babel-v7.4.0-polyfill-w-core-v3

Referência:

Apollo
fonte
1
Você usa isso na produção env? algum risco?
Roy
useBuiltIns: "usage"não funciona do meu lado. Ele simplesmente não inclui nenhum polyfils no pacote (exemplo: eu uso geradores e recebo um erro "regeneratorRuntime não está definido"). Alguma ideia?
WebBrother
@WebBrother, funciona para mim ... veja por exemplo: github.com/ApolloTang/stackoverflow-eg--babel-polyfill
apollo
@ Roy, na verdade, estou no processo de migrar um projeto corporativo de babel @ 6 para babel @ 7, para que eu possa usar @ babel / preset-typescript. Ainda está em andamento, mas estou seguindo as instruções do documento oficial da babel (consulte os links de referência na minha resposta). Até o momento, tudo parece estar funcionando, mas ainda não enviei meu trabalho de migração / atualização para o controle de qualidade; postarei aqui se houver algum problema.
apollo
19

Se o seu package.json se parecer com o seguinte:

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

E você recebe a Cannot find module 'babel/polyfill'mensagem de erro, provavelmente precisará alterar sua instrução de importação DE:

import "babel/polyfill";

PARA:

import "babel-polyfill";

E verifique se ele vem antes de qualquer outra importdeclaração (não necessariamente no ponto de entrada do seu aplicativo).

Referência: https://babeljs.io/docs/usage/polyfill/

l3x
fonte
3
Nesta resposta, o pacote babel-polyfill está listado em 'devDependencies'. Fazer isso resultará no babel-polyfill não incluído na implantação. Você não deve instalar o babel-polyfill com o sinalizador -D, mas com o sinalizador -S, para que seja listado em 'dependências' e, portanto, incluído na sua implantação.
Apollo
9

Primeiro, a resposta óbvia que ninguém forneceu, você precisa instalar o Babel no seu aplicativo:

npm install babel --save

(ou babel-corese você preferir require('babel-core/polyfill')).

Além disso, tenho uma tarefa difícil de transpilar meu es6 e jsx como uma etapa de compilação (ou seja, eu não quero usar babel/register, e é por isso que estou tentando usar babel/polyfilldiretamente em primeiro lugar), então gostaria de coloque mais ênfase nesta parte da resposta da @ ssube:

Certifique-se de solicitá-lo no ponto de entrada do seu aplicativo, antes que qualquer outra coisa seja chamada

Encontrei um problema estranho em que estava tentando solicitar babel/polyfillalgum arquivo de inicialização do ambiente compartilhado e recebi o erro que o usuário referenciou - acho que pode ter algo a ver com a forma como o babel ordena a importação versus requer, mas não consigo reproduzir agora. De qualquer forma, mover import 'babel/polyfill'como a primeira linha nos scripts de inicialização do meu cliente e servidor corrigiu o problema.

Observe que, se você preferir usar require('babel/polyfill'), garantiria que todas as outras instruções do carregador de módulos também sejam necessárias e não usem importações - evite misturar as duas. Em outras palavras, se você tiver alguma declaração de importação no script de inicialização, faça import babel/polyfilla primeira linha do script em vez de require('babel/polyfill').

ChetPrickles
fonte
9
Você não precisa correr sudocom o NPM docs.npmjs.com/getting-started/fixing-npm-permissions
Vladimir Starkov
8

O babel-polyfill permite que você use o conjunto completo de recursos do ES6 além das alterações de sintaxe. Isso inclui recursos como novos objetos internos, como Promises e WeakMap, além de novos métodos estáticos, como Array.from ou Object.assign.

Sem o babel-polyfill, o babel apenas permite o uso de recursos como funções de seta, destruição, argumentos padrão e outros recursos específicos de sintaxe introduzidos no ES6.

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

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

zloctb
fonte
0

Como Babel diz nos documentos , para Babel> 7.4.0 o módulo @ babel / polyfill está obsoleto , por isso é recomendável usar diretamente as bibliotecas core-js e regenerator-runtime que antes eram incluídas no @ babel / polyfill.

Então, isso funcionou para mim:

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

adicione no topo do seu arquivo js inicial:

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