Должна ли библиотека Javascript, использующая функции ES6 и ES7, использовать babel-polyfill?

Я занимаюсь разработкой библиотеки, в которой интенсивно используются функции ES6 и ES7. Компиляция этого с Babel приводит к коду, который (естественно) использует примитивы, такие как Symbol или Promise. Нужно ли мне require('babel-polyfill') чтобы убедиться, что такие примитивы есть наверняка?

В первый момент ответ кажется "да" - особенно если я не знаю, в какие среды выполнения кто-то может выполнить мою библиотеку. С другой стороны, если каждая библиотека делает это, мы в конечном итоге потребуем babel-polyfill снова и снова (и я не уверен, что это хорошая идея).

1 ответ

Решение

Я провел некоторое исследование по этому вопросу:

требующий babel-polyfill изнутри библиотека выглядит как анти-шаблон; Это по двум причинам:

1) babel-polyfill не хочет, чтобы его требовали несколько раз, и он выдаст, если вы попытаетесь это сделать (см. примечание ниже)

2) это приведет к значительному увеличению размера библиотеки, так как вам придется объединять полифилл несколько раз.

Оба пункта 1) и 2) актуальны только тогда, когда npm не в состоянии дедупликации нескольких babel-polyfill зависимостей. Это может произойти, если вы используете старую версию npm или дедупликация может быть невозможна из-за ограничений зависимости. Поскольку последним нельзя легко управлять, я считаю 1) и 2) довольно серьезным.

А теперь, как вы (вероятно) должны это сделать:

Если вам нужна определенная функция в вашей библиотеке (например, Promise), вы можете require это конкретно (т.е. не весь polyfill, просто функция). Этот подход смягчает 1) и частично смягчает 2).

Вероятно, лучший способ сделать это - просто предупредить своих пользователей, что ваша библиотека ожидает некоторые функции ES6, поэтому они должны требовать полифилла.

Хорошие примеры первого подхода

https://www.npmjs.com/package/promisify-node

для которого требуется собственная версия Promise, совместимого с A+. Хороший пример второго подхода

https://github.com/ubolonton/js-csp

который использует генераторы, но не делает ничего, чтобы гарантировать, что они действительно есть (в общем, просто компиляции кода с помощью Babel недостаточно, и для их работы требуется полифилл).

-------- РЕДАКТИРОВАТЬ --------

Я узнал что babel-plugin-transform-runtime может быть использован именно для этой проблемы: он позволяет использовать функции ES6 / ES7, не затрагивая глобальное пространство имен, требуя полизаполнения. Грустная часть истории заключается в том, что этот плагин чрезвычайно глючит, вероятно, потому что это принципиально сложно сделать работу. Например:

Object.keys({})

превращается в нечто похожее на:

var _keys=require("babel-runtime/core-js/object/keys")
_keys(obj)

но

var aaa = Object
aaa.keys(obj)

не преобразуется вообще и, следовательно, потерпит неудачу (если Object.keys не определен ни браузером, ни полифилом). Мой совет - не используйте плагин для этой цели.

Другие вопросы по тегам