2016-01-23 9 views
2

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

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

+0

Я думаю, что что-то, что сработает, является опцией на данный момент :) –

+0

«* мы снова и снова будем требовать перезагрузки». - Я не понимаю, что с этим не так. Он будет загружен и выполнен только один раз. Вот как работают модули. – Bergi

+1

@ Bergi, который зависит от того, как 'npm' устанавливает его. Если 'npm' устанавливает его несколько раз, он также будет выполняться несколько раз, что на самом деле будет бросать и ошибка, проверьте это: https://github.com/babel/babel/blob/master/packages/babel-polyfill/src /index.js –

ответ

4

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

Требуя babel-polyfill из внутри Lib выглядит как анти-модель; это по двум причинам:

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

2) делать это приведет в Значительное увеличение размера библиотеки, так как вам нужно многократно связывать полиполк.

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

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

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

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

Хороших примеров первого подхода является

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

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

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

, который использует генераторы, но не делает ничего, чтобы обеспечить, что они действительно есть (в общем, просто скомпилировать код с Бабелем не достаточно, и вы должны требовать polyfill чтобы они работали).

-------- EDIT --------

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

Object.keys({}) 

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

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

но

var aaa = Object 
aaa.keys(obj) 

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