Meilleur moyen de polyfill ES6 fonctionnalités dans l'application React qui utilise create-react-app


87

J'ai testé mon application React.js sur Internet Explorer et j'ai découvert que du code ES6 / 7 comme le Array.prototype.includes()casse.

J'utilise create-react-app , et apparemment, ils ont choisi de ne pas inclure beaucoup de polyfills car tout le monde n'en a pas besoin, et ils ralentissent les temps de construction (voir par exemple ici et ici ). La documentation (au moment de la rédaction) suggère:

Si vous utilisez d'autres fonctionnalités ES6 + qui nécessitent une prise en charge à l'exécution (telles que Array.from () ou Symbol), assurez-vous d'inclure manuellement les polyfills appropriés ou que les navigateurs que vous ciblez les prennent déjà en charge.

Alors ... quelle est la meilleure façon de les inclure «manuellement»?


1
Babel fournit babel-polyfillun polyfill ES6 + facile.
loganfsmyth

1
Notez que Array.prototype.includes()c'est en fait dans ES7, pas ES6
huyz

Réponses:


122

Mise à jour : L'approche et la documentation du polyfill create-react-app ont changé depuis cette question / réponse. Vous devriez maintenant inclure react-app-polyfill( ici ) si vous souhaitez prendre en charge des navigateurs plus anciens comme ie11. Cependant, cela n'inclut que les " ... exigences minimales et les fonctionnalités de langage couramment utilisées ", vous voudrez donc toujours utiliser l'une des approches ci-dessous pour les fonctionnalités ES6 / 7 moins courantes (comme Array.includes)


Ces deux approches fonctionnent toutes les deux:


1. Importations manuelles depuis react-app-polyfill et core-js

Installez react-app-polyfill et core-js (3.0+):

npm install react-app-polyfill core-js ou yarn add react-app-polyfill core-js

Créez un fichier appelé (quelque chose comme) polyfills.js et importez-le dans votre fichier racine index.js. Puis importez les polyfills de base react-app, ainsi que toutes les fonctionnalités requises spécifiques, comme ceci:

/* polyfills.js */

import 'react-app-polyfill/ie11';
import 'core-js/features/array/find';
import 'core-js/features/array/includes';
import 'core-js/features/number/is-nan';

/* index.js */

import './polyfills'
...

2. Service Polyfill

Utilisez le CDN polyfill.io pour récupérer des polyfills personnalisés et spécifiques au navigateur en ajoutant cette ligne à index.html:

<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=default,Array.prototype.includes"></script>

Remarque, j'ai dû demander explicitement la Array.prototype.includesfonctionnalité car elle n'est pas incluse dans l'ensemble de fonctionnalités par défaut.


18
Je deviendrais probablement plus granulaire. Au lieu de copier-coller, vous pouvez installer core-jset importer des polyfills globaux individuels à partir de votre polyfills.js. A part cela, les deux approches sonnent bien.
Dan Abramov

1
Cela semble plus intelligent, merci Dan. Vous voulez dire github.com/zloirock/core-js , je suppose (par exemple. Npm install core-js)?
Daniel Loiterton

7
Je rencontrais un problème avec une application générée avec la dernière application create-react-app n'apparaissant pas sur IE 11 et les versions antérieures. Grâce à cette solution, j'ai fini par inclure <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=default,es6"></script>(remarquez le es6) et maintenant ça marche comme un charme. Je crois que le problème principal était d'avoir besoin d'un polyfill pour Symbol.
dougmacklin

1
@dougmacklin Just FYI: C'est hasardeux, car dans mon cas, l'utilisation de votre include n'a pas résolu mes problèmes d'IE 11. Malheureusement, la console de développement dans IE 11 n'a pas non plus été utile pour déterminer quelle fonctionnalité de langue la déclenchait. Nous avons fini par utiliser babel-polyfill. Des mains lourdes, je sais, mais nous devions lancer le site de production.
Clinton Chau

1
@ClintonChau, totalement compréhensible. Depuis que j'ai publié ce commentaire, j'ai fini par devoir utiliser babel-polyfill sur un autre projet pour résoudre un problème différent d'IE 11
dougmacklin

12

Utilisez le react-app-polyfill qui a des polyfills pour les fonctionnalités ES6 courantes utilisées dans React. Et cela fait partie de create-react-app . Assurez-vous de l'inclure au début de index.js comme défini dans le README.


1
Je pense que ma réponse est la meilleure, mais c'est uniquement parce qu'elle est plus récente - le react-app-polyfill n'a été créé que il y a quelques mois et jusque-là, les autres réponses étaient évidemment meilleures :-)
icewhite

4
Salut @icewhite, je pense que vous avez mal compris à propos de react-app-polyfill. Le paquet inclut juste polifill de: Promise, window.fetch, Object.assign, Symbol, Array.from. Il ne comprend Array.prototype.includes()ou autres.
Huong Nguyen

6

J'ai utilisé du fil pour télécharger le polyfill et je l'ai importé directement dans mon index.js.

Dans l'invite de commande:

yarn add array.prototype.fill

Et puis, en haut de index.js:

import 'array.prototype.fill' // <-- newly added import
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
...

J'aime cette approche car j'importe spécifiquement ce dont j'ai besoin dans le projet.


1
Quelque chose de ce genre semble maintenant être la meilleure pratique suggérée pour les projets Create React App. Voir: github.com/facebook/create-react-app/blob/master/packages
Peter W

3

Pour ce que ça vaut, j'avais des problèmes avec la nouvelle console de recherche Google et mon application React (create-react-app). Après avoir ajouté l'es6shim, tout a été résolu.

J'ai ajouté ce qui suit à ma page publique index.html.

<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>

0

Éjecter de votre projet d'application Create React

Ensuite, vous pouvez mettre tous vos polyfills dans votre /config/polyfills.jsfichier

Mettez ce qui suit à la fin du fichier

Object.values = Object.values ? Object.values : o=>Object.keys(o).map(k=>o[k]);

Webpack corrigera automatiquement cela pour vous;)


en fait trouvé un meilleur moyen, npm install --save core-js; import 'core-js / fn / object / values';
webmaster

Pouvez-vous s'il vous plaît modifier votre réponse avec cette meilleure façon?
MattSidor

0

J'ai eu le même problème. Une solution de Daniel Loiterton n'a pas fonctionné pour moi. Mais! J'ai ajouté une autre importation de core-js import 'core-js/modules/es6.symbol';et cela fonctionne pour moi sur IE11.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.