Подводные камни, костыли и полученный опыт.
В первую очередь, рассказ ориентирован на тех, кто хочет заменить сборку Грантом или Гальпом на вебпак. Я рассмотрю тонкости настройки и необычные проблемы, с которыми мы столкнулись, ибо стандартные ситуации хорошо описаны на просторах интернета.
2. Исходные данные
183 компонента
190 файлов Less
428 файлов Jade (pug)
718 файлов JS
Все “классы” в глобальной области видимости
Все сторонние библиотеки в нашем репозитории
Самодельная система сборки
Переводы в формате gettext (*.po)
2
3. Предыдущая система сборки
Самодельная система сборки написанная на ПХП
Конфигурационные файлы зависимостей
grunt-webfont, grunt-contrib-jade; самоделка над spritesmith, less и postcss
jsmin.c для минификации Джс, cssmin.php для ЦСС
Обёртка над lazyload.js для отложенной загрузки
3
4. Почему существующая ситуация не подходит
Нужно создать и поддерживать свою модульную систему
Нужно создать и поддерживать свою систему сборки
Без какой-либо модульной системы сложно отследить зависимости
между компонентами
Все сторонние библиотеки в нашем репозитории, что искушает добавить
"немного" изменений прямо на месте
В момент сборки не ясно, что и когда будет подключено на страницу
4
5. Модульные системы бывают разные
Browserify
Webpack
Require.js
Rollup.js
Jspm
Assetgraph
Brunch
Lasso
5
6. Почему вебпак
Умеет автоматически разделять результирующие файлы на части
Поддерживает отложенную загрузку из коробки
Есть инструменты для визуализации и анализа результирующих файлов
Умеет работать с CommonJS, AMD, UMD
Умеет работать с любыми типами файлов
Поддерживает Source Maps
Проблемы активно устраняют, помогают решить вопросы, экосистема развивается
Посмотреть сравнительную характеристику.
6
7. Алгоритм перехода
1. Добавить недостающие require() и module.exports
2. JST['<TemplateName>'] -> require('./<TemplateName>.jade')
3. Добавить @import “~styles/main.less” во все подключаемые стили
4. Добавить require('style.less') в шапки соответствующих файлов джейд
5. lazyload.load() -> require.ensure()
7
8. Добавить module.exports, используя jscodeshift
Добавить require(), используя ESList
Заменить обращения к шаблонам, используя регулярные выражения
К сожалению, изменения в отложенных загрузках и стилях нужно сделать
вручную.
Частичная автоматизация
8
9. Настройка вебпака
Сборка переводов - msgcat + po-loader
Спрайтинг - SpritesmithPlugin
Шрифтовые иконки - fontgen-loader
Загрузка модулей, которые вынесены в отдельные файлы - file-loader
Вынесение общих участков кода в отдельные файлы - CommonChunksPlugin
Вынесение ЦСС в отдельный файл - ExtractTextPlugin
Автоматическое импортирование модулей - ProvidePlugin
9
10. Настройка вебпака
Создание фавиконок - FaviconsPlugin
Создание файла хтмл с подключёнными ассетами - HtmlWebpackPlugin
Распараллеливание сборки - happypack
Минификация яваскрипта - UglifyJsPlugin
Сборка Less и применение PostCSS - less-loader + postcss-loader
11. Уменьшение размера результирующих файлов
Анализ размера файлов - BundleAnalyzerPlugin
Игнорирование модулей анализатором - module.noParse
Алиасы при подключении модулей - resolve.alias
Не генерировать модули для определённых путей - IgnorePlugin
Создание дополнительного файла и его отложенная загрузка
То же самое, что и пункт выше - bundle-loader
11
12. Уменьшение размера результирующих файлов
Анализатор и визуализация результатов сборки
Слияние похожих частей кода для уменьшения размера -
AggressiveMergingPlugin
Удаление похожих и одинаковых результирующих файлов - DedupePlugin
14. Стало ли лучше?
Зависимости указаны явно в каждом файле
Появилась возможность использовать модули нпм
Появилась модульная система
Уменьшилось время сборки
Теперь можно написать юнит-тесты
Теперь можно применить ESLint и stylelint в гит коммит хуке и не
пропускать несоответствующие стилю задачи
14
15. Дальнейшие улучшения
Уменьшить размер бандла
Оптимизировать отложенные загрузки
Сжимать изображения и шрифты
Отображать заглушки изображений до их загрузки
Server-side rendering
Полноценно применить линтер для джаваскрипта
Не отдавать на клиент неиспользуемый ЦСС и джаваскрипт
15
16. Дополнительная информация
Учебник по вебпаку
Документация по вебпаку первой версии
Документация по вебпаку второй версии
Мои наработки по автоматической миграции кода
Вчера появился релиз-кандидат вебпака версии 2.2.0
16
Добрый вечер. Кто-то работал с вебпаком? Слышал о модульных системах?
Зовут меня Илья Зуб. Сейчас активно приводим фронтенд в порядок и решили внедрить модульную систему.
В первую очередь, рассказ ориентирован на тех, кто хочет заменить сборку Грантом или Гальпом на вебпак. Я рассмотрю тонкости настройки и необычные проблемы, с которыми мы столкнулись, ибо стандартные ситуации хорошо описаны на просторах интернета.
В нашей системе имеется
Наш фронтенд лежал в одном репозитории с бекендом. Сборка самодельная, ибо на момент создания системы не было никаких модульных систем. Частично применили грант. Исторически сложилось, что только частично.
На самом деле, они чуть более, чем похожи. Есть сравнительная характеристика: https://webpack.js.org/get-started/why-webpack/#comparison
Самая крутая фича вебпака, которая есть и в реквайр.джс, - поддержка отложенной загрузки автоматически сгенерированных частей кода из коробки.
Так как все наши “классы” были в глобальной области видимости, то при переходе на модульную систему появилась необходимость импортирования зависимостей.
Первые два пункта можно автоматизировать применив инструменты анализа и изменения кода, и регулярные выражения. Все желающие могут посмотреть реализацию на гитхабе.
Советую использовать chunksSortMode: 'dependency' для хтмл вебпак плагин.
У меня вышло так, что файлы джейд весят больше всего, ибо миксины - это вещь.
А вообще, вышло уменьшить размер конечного бандла с 1,5 МБ до 840 КБ. Это 8 файлов. И это очень много. Дальнейшие работы будут вестись. Если кому-то будет интересно, то когда-нибудь сделаю продолжение рассказа об оптимизациях.
Если у вас есть маршрутизация на клиенте, то советую вынести все контроллеры и экшны в отдельные файлы и загружать их отложенно. То же самое можно сделать и с отображением чего-то по событию или условию.
Если у вас ещё нет модульной системы, то очень советую внедрить таковую.