Все бы хорошо, но они обе обошли стороной вопрос разделение бандлов на ES6 и ES5 для целей минификации и другой оптимизации. И вообще, в то время как одни все пишут и пишут статьи про это — другие (почти все) данную технику игнорируют.
Потому что Долго. Дорого. И не так чтобы очень очень.
А надо быстро, дешево, и потупее. Возможно следует просто обратить эволюцию вспять.

Идея
Описывать «идею» — не самая лучшая идея. Лучше описать то, как она должна работать. То как процесс формирования бандла должен работать:
— у меня есть код
— я его компилирую под мой «разработческий» браузер
— и оно все работает
Разработческий браузер тут — так чтобы async/await, generator, classes, arrow functions и так далее. В общем target: esmodules в бабеле.
Не знаю как вам, а мне такая идея нравится. Вот только старым браузерам, которые все еще среди нас, эта идея не так чтобы заходит. (и потому мы все шипим es5 в продакшен, приправив полмегабайтом полифилов)
И именно это надо исправить.
Devolution
Devolution — маленькая cli утилитка, которая возьмет ваш бандл, скомпилированный в target: esmodules, и деградирует его до es5, добавив все нужные полифилы по пути.
Если в кратце то:
— находятся все js скрипты
— прогоняются через babel с одним активным плагином (форк useBuiltins: «usage»), который определяет требуемые полифилы. Это быстро, так как трансформаций нет.
— для каждого файла собираются все нужные ему полифилы (минус те, что уже есть в главном бандле), обьединяются, прогоняются через terser и добавляются в начало файла.
— каждый файл прогонятся через swc, rust версию babel, которая де-модернизирует код до уровня понятному IE11. Работает в 10-60 раз быстрее babel. Он не поддерживает различные плагины, но это и не нужно — все что нужно __уже__ применено.
— на результат еще раз накладывается terser, но с выключеным mangle(сжатие имен), что опять же — быстро.
— все это выполняется в воркерах.
Я прогнал код на трех проектах разного уровня сложности:
— проект 1, 60 конечных js файлов (code-splitting). Время сборки 400s. Devolution 30s.
— проект 2, 1 конечный js файл (30mb). Время сборки 120s. Devolution 10s.
— проект 3, 1 конечный js файл (2mb). Время сборки 20s. Devolution 5s (на старте воркеров много что-то да и теряется).
Бонус от ESM бандла получился немного странный:
— один проект похудел на 400kb babel/polyfill. Банально там не использовалось ничего «сверх» браузерных фишек, и в «esm» их полифилить не надо
— один проект похудел на 10% из-за сильно более компактного кода генераторов, async/await и конструкторов классов
— один проект потолстел, так как «loose» babel трансформации иногда делают код более компактным. Но loose mode немного опасная опция, в то время как «ES6» код — «безопасный».
Еще раз:
— берем ES6 код (точнее esmodule, let/const будут заменены на var в целях скорости)
— делаем из него ES5
— докидываем сбоку полифилов
— раскидываем по папочкам, добавляем симлинки на остальные файлы
— меняем подключение скриптов на страницы на чуть более умное (IE11 modules/nomodules не понимает)
— готово — ESM для 85% кастомеров, ES5 для тех кто в танке.
Просто. Быстро. Просто Тупо. Мы де-модернизировали бандл. Старые браузеры! Ау — кушать подано.
Ну а новые браузеры получат бандл почти без полифилов, без страшных трансформаций генераторов и async/await, с arrow functions без бубнов (и они вообще быстрее). В общем все счастливы, вроде так изначально и задумывалось.
github.com/thekashey/devolution
PS: На самом деле в данный момент devolution не использует swc, так как он иногда делает код не очень рабочим — github.com/swc-project/swc/issues/280, Бабель при этом не так чтобы сильно медленее — там где swc правлялся за 20 секунд, babel справляется за минуту. При времени «нормальной» сборки — от 5ти и далее — это большой плюс
PS: Если вдруг стало интересно почему devolution — www.youtube.com/watch?v=MdrlALQVEKM
Комментариев нет:
Отправить комментарий