Лучший способ полифиллировать функции ES6 в приложении React, которое использует приложение create-react-app

Я тестировал свое приложение React.js в Internet Explorer и обнаружил, что какой-то код ES6 / 7, например Array.prototype.includes(), его ломает.

Я использую create-response-app, и, очевидно, они решили не включать много полифилов, поскольку они нужны не всем, и они замедляют время сборки (см., например, здесь и здесь). Документация (на момент написания) предлагает:

Если вы используете какие-либо другие функции ES6 +, которые нуждаются в поддержке во время выполнения (например, Array.from () или Symbol), убедитесь, что вы включаете соответствующие полифиллы вручную или что браузеры, на которые вы нацеливаете, уже поддерживают их.

Итак ... как лучше всего включить их "вручную"?


person Daniel Loiterton    schedule 03.05.2017    source источник
comment
Babel предоставляет babel-polyfill как простой полифил ES6 +.   -  person loganfsmyth    schedule 03.05.2017
comment
Обратите внимание, что Array.prototype.includes() на самом деле находится в ES7, а не в ES6   -  person huyz    schedule 20.11.2018


Ответы (6)


Обновление: подход и документация create-react-app polyfill изменились после этого вопроса / ответа. Теперь вы должны включить react-app-polyfill (сюда ), если вы хотите поддерживать старые браузеры, такие как ie11. Однако это включает только «... минимальные требования и часто используемые языковые функции», поэтому вы все равно захотите использовать один из подходов ниже для менее распространенных функций ES6 / 7 (например, Array.includes)


Оба этих подхода работают:


1. Ручной импорт из react-app-polyfill и core-js

Установите react-app-polyfill и core-js (3.0+):

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

Создайте файл с именем (что-то вроде) polyfills.js и импортируйте его в свой корневой файл index.js. Затем импортируйте базовые полифилы приложения react-app, а также все необходимые специфические функции, например:

/* 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. Сервис Polyfill

Используйте CDN polyfill.io для получения настраиваемых полифиллов для конкретного браузера, добавив эту строку в index.html :

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

обратите внимание, мне пришлось явно запросить функцию Array.prototype.includes, поскольку она не включена в набор функций по умолчанию.

person Daniel Loiterton    schedule 03.05.2017
comment
Я бы, наверное, стал более детальным. Вместо копирования и вставки вы можете установить core-js и импортировать отдельные глобальные полифиллы из вашего polyfills.js. В остальном оба подхода звучат нормально. - person Dan Abramov; 03.05.2017
comment
Звучит умнее, спасибо Дэн. Вы имеете в виду github.com/zloirock/core-js, я полагаю (например, npm install core -js)? - person Daniel Loiterton; 04.05.2017
comment
У меня возникла проблема с приложением, созданным с помощью последнего приложения create-response-app, которое не отображается в IE 11 и ниже. Благодаря этому решению я включил <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=default,es6"></script> (обратите внимание на es6), и теперь он работает как шарм. Я считаю, что основная проблема заключалась в необходимости создания полифилла для Symbol. - person dougmacklin; 06.06.2017
comment
@dougmacklin Просто к вашему сведению: это удачно или нет, потому что в моем случае использование вашего включения не решило мои проблемы с IE 11. К сожалению, консоль разработчика в IE 11 также очень бесполезна в выяснении того, какая языковая функция ее сбивает. В итоге мы использовали babel-polyfill. Тяжелые руки, я знаю, но нам нужно было запустить производственную площадку. - person Clinton Chau; 16.04.2018
comment
@ClintonChau, совершенно понятно. Поскольку я опубликовал этот комментарий, мне пришлось использовать babel-polyfill в другом проекте, чтобы исправить другую проблему IE 11. - person dougmacklin; 16.04.2018
comment
@DanAbramov, по какой причине они не включены по умолчанию? Или бабель / полифилл? - person patotoma; 17.10.2018
comment
@patotama, Дэн объясняет в этом посте: github.com/facebook / create-response-app / issues / - person Daniel Loiterton; 17.10.2018
comment
polyfill.io CDN вызовет проблемы (по крайней мере) с Redux Saga в IE11, я бы выбрал babel-polyfill, если у меня нет времени для извлечения каждой функции, которая мне нужна. - person PhoenixPan; 31.10.2018
comment
@DanielLoiterton Похоже, core-js изменил внутреннюю структуру своего пакета в последней 3.0.0 версии. Таким образом, путь для импорта изменился с core-js/fn/** -> core-js/features/**. Я создал суть с обновленными путями здесь, не стесняйтесь обновлять пример кода в своем ответе :-) gist.github.com/ofhouse/d9a67e306526b317b0f6b9cbedf391e5 - person ofhouse; 17.04.2019
comment
Спасибо, @ofhouse. Я обновил ответ соответственно - person Daniel Loiterton; 17.04.2019
comment
Теперь есть polyfill v2 - ›Это обновленный URL - https://polyfill.io/v3/polyfill.min.js?features=default%2CArray.prototype.includes - person Gal Bracha; 19.10.2019
comment
согласно аудитам хрома, ‹script› с полифилом блокирует рендеринг и стоит 760 миллисекунд ... - person Seeliang; 22.01.2020
comment
Что касается подхода №1: действительно ли нужен response-app-polyfill, если мы включим core-js? Какие полифиллы существуют только в первом, а во втором - нет? - person Per Quested Aronsson; 15.01.2021

Используйте react-app-polyfill который имеет полифиллы для общих функций ES6, используемых в React. И это часть create-response-app. Убедитесь, что вы включили его в начало index.js, как определено в README.

person icewhite    schedule 20.11.2018
comment
Я думаю, что мой ответ лучший, но это только потому, что он более свежий - response-app-polyfill был создан всего несколько месяцев назад, и до тех пор другие ответы были явно лучше :-) - person icewhite; 26.11.2018
comment
Привет, @icewhite, я думаю, вы немного неправильно поняли насчет react-app-polyfill. Пакет просто включает полифиллы: Promise, window.fetch, Object.assign, Symbol, Array.from. Он не включает Array.prototype.includes() или другие. - person Huong Nguyen; 24.01.2019

Я использовал пряжу для загрузки полифилла и импортировал его прямо в свой index.js.

В командной строке:

yarn add array.prototype.fill

А затем вверху index.js:

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

Мне нравится этот подход, поскольку я специально импортирую в проект то, что мне нужно.

person gus3001    schedule 10.09.2017
comment
Что-то вроде этого, по-видимому, теперь является рекомендуемой лучшей практикой для проектов Create React App. См .: github.com/ facebook / create-react-app / blob / master / packages / - person Peter W; 12.10.2018

Как бы то ни было, у меня возникли проблемы с новой консолью поиска Google и моим приложением React (create-response-app). После добавления es6shim все разрешилось.

Я добавил ниже на свою общедоступную страницу index.html.

<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
person David J Barnes    schedule 15.04.2019

Извлечь из своего проекта приложения Create React

После этого вы можете поместить все свои полифиллы в свой /config/polyfills.js файл.

Поместите в конец файла следующее

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

Webpack автоматически исправит это за вас;)

person webmaster    schedule 01.07.2018
comment
на самом деле нашел лучший способ, npm install --save core-js; импортировать 'core-js / fn / object / values'; - person webmaster; 10.07.2018
comment
Не могли бы вы отредактировать свой ответ таким лучшим способом? - person MattSidor; 15.07.2019

У меня такая же проблема. Решение от Дэниела Лойтертона у меня не сработало. Но! Я добавил еще один импорт из core-js import 'core-js/modules/es6.symbol';, и это работает для меня в IE11.

person Dual    schedule 13.02.2019