- PVSM.RU - https://www.pvsm.ru -

Autopolyfiller — Precise polyfills

Autopolyfiller — Precise polyfills
В этой статье я хочу рассказать об инструменте Autopolyfiller, который помогает вам использовать последние функции EcmaScript и при этом не думать об подключаемых полифиллах.

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

Есть целый ряд способов исправить эту ситуацию:

lodash и underscore

Это достаточно популярный способ «починить» браузеры на сегодняшний день, плюс ко всему lodash приносит ряд полезных функций для работы с данными. К тому же он позволяет беречь нервы разработчиков, которые до сих пор боятся менять прототип базовых классов «во благо».

_.chain([1, 2, 3, 4])
.map(function (item) {
    return item * item;
})
.filter(function (item) {
    return item < 9;
})
.value();


Лично мне он не нравится из-за того, что lodash делает код «зашумленным». Но это дело каждого.

es5shim

es5shim чинит практически все отсутствующие функции [1], которые были утверждены в спецификации ES5. Вам достаточно подключить файл es5-shim.js [2] и можно свободно пользоваться практически всеми благами EcmaScript 5.

[1, 2, 3, 4]
.map(function (item) {
    return item * item;
})
.filter(function (item) {
    return item < 9;
});

Такой код, безусловно, выглядит гораздо чище.

polyfill.io

Суть очень проста. Вы включаете в ваш html код скрипт, который динамически генерируется исходя из заголовка User-Agent браузера клиента и чинит все, что в нем поломано:

<script src="//polyfill.io"></script>

(не используйте эту ссылку в Production)

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

Сам проект polyfill [3].

Autopolyfiller

Предыдущие способы починки JavaScript имеют значительный недостаток. Они заставляют вас думать. Точнее самостоятельно разрешать все зависимости вашего кода, учитывая версии поддерживаемых браузеров (подключать какие-то дополнительные скрипты). Либо могут разбиться о реальность www. Да и именно по этому многие разработчики включают весь es5shim (без спец сборок) и боятся его отключить после отказа от поддержки IE8 (а мало ли что сломается). Проект постепенно обрастает лишними зависимостями и вычищать эти зависомости очень-очень больно.

Как вариант, можно создать какой-то файл в котором хранить все используемые ES5 методы. И при при добавлении нового метода в код расширять этот файл, учитывая все версии поддерживаемых браузеров. Используя этот список, можно получить кастомную сборку es5shim. А как быть если мы повышаем версию браузеров, удаляем используемый метод? Писать скрит? В общем, шило на мыло.

Если посмотреть с другой стороны, то ваш код — это и есть тот самый файл со списком зависимостей, просто этот список не явный:

[1, 2, 3, 4]
.map(function (item) {
    return item * item;
})
.filter(function (item) {
    return item < 9;
});

Мы можем легко понять, что в этом коде используется 2 функции из ES5: Array.prototype.map и Array.prototype.filter.

Нам достаточно научить робота находить в нашем коде зависомости и мы получим возможность автоматически «патчить» наш код только нужными полифиллами. Огромный плюс в том, что данный список зависимостей сам очищается и сам расширяется по ходу изменения вашего кода.

Из этой простой идеи родился проект Autopolyfiller, который помогает вам не думать. Как вы уже заметили его название схоже с Autoprefixer [4], который исповедует те же принципы, но касательно CSS.

Алгоритм работы Autopolyfiller очень прост:
— Вы определяете список браузеров, которые поддерживает ваш проект (это не оябзательно)
— Скармливаете Autopolyfiller'у ваш код
— Autopolyfiller разбирает AST и находит методы ES*
— Убирает методы, которые вам не нужны, используя список браузеров
— Вы получаете код с полифиллами

Из-за того, что JavaScript это интерпретируемый язык, Autopolyfiller может промахнуться в некоторых очень граничных случаях.

— В этом коде $('div').map() он найдет Array.prototype.map.
— В этом коде eval('Object.keys(this)') и этом коде Object['k' + 'eys']() он ничего не найдет.

Но если не делать ничего странного и не использовать eval-подобные структуры, то его точность будет достаточно высока.

Autopolyfiller из коробки поддерживает только безопасные, кроссбраузерные и стабильные полифилы (ES6 нет), которые берутся из открытой «базы данных» полифиллов [5]. Однако вы можете с легкостью его расширять своими.

Кроме консольной утилиты и API, на данный момент написаны таски под Gulp [6], Grunt [7] и Enb [8]. Так, что вы можете легко прикрутить Autopolyfiller в ваш сборочный процесс уже сегодня. А если вы все еще сомневаетесь — попробуйте демку [9]!

Ссылки:
Проект Autopolyfiller на Github [10]
Качество кода Autopolyfiller [11]
Демо Autopolyfiller [9]

Буду рад ответить на все ваши вопросы.

Автор: azproduction

Источник [12]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/64318

Ссылки в тексте:

[1] практически все отсутствующие функции: https://github.com/es-shims/es5-shim#shims

[2] es5-shim.js: http://cdnjs.cloudflare.com/ajax/libs/es5-shim/3.4.0/es5-shim.js

[3] polyfill: https://github.com/jonathantneal/polyfill

[4] Autoprefixer: https://github.com/ai/autoprefixer

[5] открытой «базы данных» полифиллов: https://github.com/jonathantneal/polyfill/tree/master/source

[6] Gulp: https://github.com/azproduction/gulp-autopolyfiller/

[7] Grunt: https://github.com/azproduction/grunt-autopolyfiller/

[8] Enb: https://github.com/enb-make/enb-autopolyfiller/

[9] демку: http://azproduction.ru/autopolyfiller/

[10] Проект Autopolyfiller на Github: https://github.com/azproduction/autopolyfiller

[11] Качество кода Autopolyfiller: https://codeclimate.com/github/azproduction/autopolyfiller/code

[12] Источник: http://habrahabr.ru/post/229001/