Перевод Webpack Tutorial: Understanding How it Works

Мотивация

Это заметка это моя попытка задокументировать то что я узнал при изучение Webpack в течение нескольких месяцев.

Когда я только начал работать в ag-Grid я столкнулся со множеством технологий и фреймворков, с которыми я раньше не работал. Один из них Webpack — мощный упаковщик используемый во множествах приложений и фрейворках.

Мы в ag-Grid используем Webpack для упаковки большинства наших приложений. Несмотря на наличие альтернатив, Webpack все еще остается очень популярным упаковщиком и с выходом версии 2.2 я надеюсь его популярность будет только расти.

Введение в Webpack

Webpack модульный упаковщик. Он позволяет загружает несопоставимые зависимости, создавать модули для них и упаковывать все это в единую сеть контролируемых файлов. Это особенно необходимо при создание Одностраничных приложений (SPA), что на данных момент является стандартом веб приложений.

Все примеры кода этой заметки могут быть найдены: Understanding How it Works repository on GitHub (https://github.com/seanlandsman/ag-grid-understanding-webpack)

Давай предположим что у нас есть приложение которое выполняет две простые математические задачи — суммирование и умножение.
Мы решили разделить эти функции в отдельные файлы для лучшего управления:

Результат выполнения будет:

Чем нам можно помочь?

Зависимости — модули это путь к спасению!

В нашем примере вы можете видеть что оба файла multiply.js и index.js зависят от sum.js. Мы можем отобразить эту зависимость ввиде диаграммы:

Если мы нарушим порядок загрузки файлов в index.html наше приложение не будет работать. Теперь представьте что речь идет о реальном веб приложений с загрузкой десятком файлов. Придерживаться определенного порядка загрузки будет очень сложно и поддержка все это может очень быстро превратиться в ночной кошмар.

Ну и наконец активно используя глобальные переменные, мы рискуем непреднамеренно переопределить их в одном из модулей.

Webpack может сконвертировать эти зависимости в модули — у каждого модуля будет отдельная область видимости (что гораздо безопаснее). Так же Webpack может управлять этими зависимостями — он может подгружать зависимости в нужно время, в определенную область видимости (мы расскажем об этом чуть позже).

Смерть от тысячи порезов — Сокращение трафика

Если мы взглянем на index.html, то увидим что нам надо подгрузить 3 отдельных файла. Это не страшно но представьте что нам надо подгрузить 20 — 30 отдельных файлов, не каждый пользователь будет готов дожидаться когда загрузятся все эти файлы до того как приложение сможет запуститься.
Еще одной фичей Webpack является группирование. Это означает что Webpack может сгруппировать все зависимости в один файл, который будет загружен гораздо быстрее чем множество отдельных файлов.

Группирование и модулизация это главные фичи Webpack. Но существо много плагинов и лоудеров которые значительно увеличивают возможности Webpack.

Сделаем зависимости доступными и привязываемся к ним.

Для нашего примера мы воспользуемся CommonJS синтаксисом. Так же можно использовать AMD и ES2015, но сейчас мы используем CommonJS а позже используем ES2015.

CommonJS использует module.exports для экспорта функций или переменных. Он использует require для загрузки экспортируемых значений.

С помощью функции экспорта мы экспортировали sum и multiply сделав доступными в любой части проекта. А с помощью require подгрузили их там где они нам понадобились.

Так же index.html мы теперь будем подгружать только один файл bundle.js.

Теперь нам не нужно заботиться о последовательности загрузки наших модулей и мы увеличим скорость запуска нашего проекта.

Webpack — Установка

Полная документация

Для инсталяции запустите команду:

Webpack — Начальная конфигурация

Для того что бы наш код заработал нам нужно сконфигурировать Webpack

Создайте файл webpack.config.js со следующем содержимым:

Это минимум что мы должны настроить в Webpack что бы наше приложение заработало.

entry: Это точка входа в наше приложение. Тут должна быть начальная логика нашего приложения. Webpack использует это как начальную точку построения дерева зависимостей.

output.path: Абсолютный путь к результату обработки. Что бы сделать путь платформо-независиммым мы использовали встроенную в Node.js функцию path. Он динамически создаст абсолютный путь.

output.filename: Имя результирующего файла. Мы назвали наш файл ‘bundle.js’

Примечание: __dirname переменная в Node.js — она возвращает директорию где был запущен текущий скрипт.

Далее запустите команду :

Посмотрим что внутри bundle.js

Вы можете увидеть что Webpack упаковал каждый из наших файлов в модуль и передал их загрузчику Webpack как массив модулей. А так же делает каждый из модулей доступным для других модулей.

Загрзчики — делаем Webpack умнее

По умолчанию Webpack понимает Javascript, но если вам нужно что то другое типа ES2015/ES6, то вам нужно настроить Webpack соотвествующим образом. Точнее вам нужны будут препроцессоры для этих языков и сконфигурировать их запуск. В компании где я работаю ag-Grid, мы используем TypeScript, но для данной заметки я покажу пример использования ES2015 и Babel.
Babel на поможет сконвертировать код из ES2015 в ES5.

Сначала, сконвертируем наш ES5 код в ES2015:

Для использования Babel, нам нужен Babel Loader. Загрузчики это то как Webpack может обрабатывает контент отличный от JavaScript. С загрузками мы можем научить Webpack обрабатывать любой контент, такой как CSS, картинки, TypeScript, ES2015 и т.д.

Нам нужны будут зависимости:
babel-loader: Интерфес между Babel и Webpack
babel-core: Обработчик кода
babel-preset-es2015: Правила для Babel о том как обрабатывать ES2015 код и конвертировать его в ES5

Вам нужно будет установить эти зависимости самостоятельно

Измените файл webpack.config.js следующим образом:

Опишем что мы добавили:

test: Нам нужно сказать загрузчику что мы хотим обрабатывать только JavaScript файлы. Для этого мы использовали регулярное выражение
loader: Здесь указали загрузчик который мы использовали
exclude: Мы хотим исключить из обработки каталог node_modules
query.presets: правила для Babel которые мы используем — в нашем случае мы используем ES2015 код

Взглянем на bundle.js, как мы можем увидеть мы сконвертировали код в JavaScript:

Научим Webpack работать с CSS

Давайте расширем наш пример, улучшим отображение результатов расчета.

Отредактируем index.js:

Теперь результат работы должен отображаться не только в консоле но и на странице.
Улучшим внешний вид с помощью CSS .

Создайте файл math_output.css со следующим содержанием:

Нам нужно загрузить этот CSS в приложение. Мы конечно же можем для использовать тег link внутри html, но мы можем это сделать и с помощью Webpack. Измените index.js следующим образом:

Для обработке CSS на нужно два загрузчика:

css-loader: загрузчик CSS — загружает его контент
style-loader: Обрабатывает CSS данные(из imports) и добавляет это в HTML документ

Теперь наш webpack.config.js будет выглядить следующим образом:

Добавленные атрибуты:

test: как и раньше, нам нужно сказать загрузчику что мы хотим обрабатывать только только CSS файлы — это регулярное приложение будет искать только .css файлы
loaders: используемые загрузчики. Теперь мы использовали массив загрузчиков. Обратите внимание что Webpack будет обрабатывать загрузчиками с право на лево, потому css-loader (содержимое файла) перенаправит поток в style-loader (который добавить стили к HTML документу)
Если мы сейчас запустим Webpack и перезагрузим наше приложение то мы должны увидеть нечто такое:

Два загрузчика динамически добавили стили к HTML документу. Если мы посмотрим на HTML код в Chrome мы должны увидеть что то типа такого:

Это не единственный способ обрабатывать CSS. Мы можем разделить CSS в кеше (файлы с уникальными хешами) и затем включить эти файлы в результирующую сборку.

Для начало давайте вытащим CSS и перенаправим содержимое в файл который мы сможем импортировать. Для этого нам нужно использовать плагин: ExtractTextPlugin. Установите ExtractTextPlugin самостоятельно.

Загрузчики используются для предварительной обработки данных. Плагины могут обрабатывать данные уже помещенные в сборку.

Изменим конфиг Webpack webpack.config.js следующим образом:

Перед импортом ExtractTextPlugin мы так же изменили неастройки загручика для CSS что бы он использовал наш плагин:

Внизу мы подключили плагин:

Взгянем на dist/style.css:

Что конечно же является нашим CSS. Что бы это использовать нам нужно изменить index.html:

Одна картинка ценее тысячи слов

Давайте добавим несколько картинок в наше приложение — и обработаем их Webpack (подходящим загрузчиком).

Добавим две картинки одну маленькую и одну большую — одну для суммирования и другую для умнлжения.

Что бы х обрабатывать нам нужно будет два загручика:

image-webpack-loader: будет автоматически сжимать большие файлы
url-loader: будет вставлять результат обработки image-webpack-loader если результатом будет файл меньше исходного, или брать исходные файлы

Установите эти загрузки в проект самостоятельно.

Добавим два файла — multiply.png размером (около 32kb) и sum.png поменшье (около 13kb).

Добавим новую функцию которая создает новую картинку и добавляем ее к документу.
Создайте файл image_util.js:

Импортируем картинки и новую функцию в наше приложение. Измените index.js:

Сконфигурируем Webpack так что бы он мог обрабатывать эти картинки с помощью загрузчиков:

output.publicPath устанавливаем префик для url-loader который будет добавлен к файлам которые будут сохранятся на диск. Для примера img.src будет иметь значение img.src=’dist/output_file.png’
test: как и раньше говорим загрузчику какие файлы будем обрабатывать
loaders: наши загрузчики — помните что Webpack обрабатывает с права на лево.

После запуска Webpack мы должны увидеть следующее:

А наше приложение должно отображать:

На этом я бы хотел завершить эту заметку. Надеюсь мне удалось рассказть для чего нужен Webpack и как начать с ним работать. Попробуйте поработать с Webpack и вы не заметите как он станет для вас не заменимым инструментом.

 

It's only fair to share...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInShare on VK