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

87

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

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

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

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

Дэниел Лойтертон
источник
1
Babel предоставляет babel-polyfillпростой полифил ES6 +.
loganfsmyth
1
Обратите внимание, что Array.prototype.includes()на самом деле это ES7, а не ES6
huyz

Ответы:

122

Обновление : подход и документация 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 или 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функцию, поскольку она не включена в набор функций по умолчанию.

Дэниел Лойтертон
источник
18
Я бы, наверное, стал более детальным. Вместо копирования и вставки вы можете установить core-jsи импортировать отдельные глобальные полифиллы из вашего polyfills.js. В остальном оба подхода звучат нормально.
Дан Абрамов
1
Звучит умнее, спасибо Дэн. Вы имеете в виду github.com/zloirock/core-js , я полагаю (например, npm install core-js)?
Дэниел Лойтертон
7
У меня возникла проблема с приложением, созданным с помощью последнего приложения create-response-app, которое не отображается в IE 11 и ниже. Благодаря этому решению я включил <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=default,es6"></script>(обратите внимание es6), и теперь он работает как шарм. Я считаю, что основная проблема заключалась в необходимости создания полифила для Symbol.
dougmacklin 06
1
@dougmacklin Просто к сведению: это удачно или нет, потому что в моем случае использование вашего включения не решило мои проблемы с IE 11. К сожалению, консоль разработчика в IE 11 также очень бесполезна в выяснении того, какая языковая функция его сбивает. В итоге мы использовали babel-polyfill. Тяжелые руки, я знаю, но нам нужно было запустить производство.
Клинтон Чау
1
@ClintonChau, совершенно понятно. С тех пор как я разместил этот комментарий, мне пришлось использовать babel-polyfill в другом проекте, чтобы исправить другую проблему IE 11
dougmacklin
12

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

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

Я использовал yarn для загрузки полифилла и импортировал его прямо в свой 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';
...

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

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

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

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

<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
Дэвид Дж. Барнс
источник
0

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

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

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

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

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

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

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

Двойной
источник