Зачем нужно собирать фронтенд
Содержание:
- Режимы Webpack
- Маппинг исходных файлов тестового кода
- Четыре базовые концепции Webpack
- Rule.generator
- Собираем JavaScript
- Сборка HTML страниц
- Loading Polyfills
- Introduction
- UseEntry
- Разное
- Creating a Bundle
- Добавление тестовых сценариев в сборку
- Постановка задачи
- Options
- Решение на webpack 5
- Setup
- Базовые понятия Webpack
- Структура проекта
Режимы Webpack
Данные режимы (появившиеся в 4-й версии Webpack) настраивают среду, в которой будет работать Webpack. Режим может быть настроен на или (по умолчанию стоит ).
Режим :
- менее оптимизирован, чем
- работает быстрее
- не удаляет комментарии
- предоставляет более подробные сообщения об ошибках и способы их решения
- сильно облегчает отладку
Режим работает медленнее, чем , так как ему нужно создать более оптимизированный бандл. Полученный JavaScript файл меньше по размеру, поскольку многое из режима в нем отсутствует.
Я написал небольшое приложение, которое выводит содержимое .
Вот бандл :
Вот бандл :
Запуск Webpack
Если Webpack установлен глобально, его можно вручную запустить из командной строки. Но, обычно, вы прописываете скрипт внутри файла , который затем запускаете через или .
Например, эти скрипты, которые мы использовали ранее:
позволяют запускать , набрав:
или:
или просто:
Просмотр изменений
Webpack может автоматически перестраивать бандл, когда в вашем приложении происходят изменения. Для этого добавьте данный скрипт:
и запустите данную функцию:
или:
или просто:
Одной из приятных особенностей watch mode (режима просмотра) является то, что бандл изменяется только в том случае, если в сборке нет ошибок. Если ошибки присутствуют, продолжит следить за изменениями и будет пытаться перестраивать бандл, но текущий, рабочий бандл не зависит от проблемных бандлов.
Обработка изображений
С помощью Webpack можно очень удобно работать с изображениями, используя загрузчик .
Эта простая конфигурация:
Позволяет импортировать изображения в ваш JavaScript:
Где — это HTMLImageElement. Ознакомьтесь с документацией по Image().
может обрабатывать и другие типы ассетов, например, шрифты, CSV-файлы, XML и т.д.
Еще одним приятным инструментом для работы с изображениями является загрузчик.
В этом примере загружается любой PNG-файл размером менее 8 КБ в качестве data:URL.
Генерация Source Maps
С транспилированным кодом, зачастую, возникают проблемы при отладке кода в браузере или анализе ошибок. Так как транспилированный и трудночитаемый JavaScript, а не оригинальный код, затрудняет поиск и исправление ошибок. Source Map — это JSON-файл, который содержит информацию о том, как транспилировать код обратно в исходный код.
Source Maps можно сгенерировать, используя свойство конфигурации :
имеет множество возможных значений, из которых наиболее часто используемые:
- : не добавляет Source Maps
- : идеально подходит для режима , предоставляет отдельную Source Map, которую можно свернуть и добавляет ссылку в бандл, чтобы инструменты разработки знали о том, что Source Map доступна
- : идеально подходит для режима , встраивает Source Maps в качестве data:URL
Перевод статьи Flavio Copes: A beginner’s introduction to Webpack
Маппинг исходных файлов тестового кода
Тестовая сборка готова, но есть один нюанс, касающийся тестирования кода. Если запустить Mocha для файла и один из этих тестов не пройдёт, как это будет выглядеть? Давайте сделаем тест формулы расстояния в ошибочным:
Выполните и вот что получится:
Тест провален, но нельзя узнать, в какой строке исходного кода находится ошибка. Если таких тестов для веб-приложения у вас много, то поиски строки с ошибкой затянутся надолго.
Код с ошибкой находится в строке 8 в файле , но Mocha запускается для файла , поэтому, с точки зрения Mocha, ошибка находится в строке 116. К счастью, Webpack поддерживает source maps, которые покажут, какая строка кода соответствует ошибке. Source maps (или карты кода) — это файлы исходного кода, которые показывают точное соответствие элементов готового рабочего кода проекта и вашего кода разработки. Выполняется своего рода проход декодером по пакетному файлу , чтобы получить исходные строки кода, которые соответствуют связному коду. Давайте обновим оператор в файле :
Затем в объект добавим строку:
Теперь в тестировочных сборках каталог будет содержать файл типа source maps. Выполните и каталог будет содержать файл в дополнение к пакету .
Чтобы Mocha мог использовать эту source map при запуске тестов, необходимо установить ещё один пакет:
Теперь, чтобы его использовать, нужно обновить скрипт Mocha в разделе файла :
Флаг требует пакет , это означает, что Mocha будет использовать source map, если она доступна. Теперь, если вы выполните и получите ошибку, вы увидите, в какой строке она находится, и сможете исправить код (Commit 8).
Итак, теперь у вас есть пример настройки обычных и тестовых сборок с использованием маппинга. Существует также множество других способов, которыми вы можете воспользоваться в своих сборках, например, объединение нескольких загрузчиков JavaScript для обработки вашего кода как на конвейере или же запуск Webpack как отладочного сервера, чтобы моментально видеть, как изменения в коде влияют на окончательную сборку Webpack. Продолжайте пробовать различные пакеты для компоновки файла !
Для более точной настройки Webpack вам может быть полезен следующий материал:
Перевод статьи Webpack: From 0 to automated testing
Четыре базовые концепции Webpack
Рассмотрим базовые концепции Webpack. Их всего четыре.
Entry
Webpack создает граф зависимостей вашего приложения. Стартовая точка в этом графе называется — “точкой входа” (“entry point”). Точка входа указывает вебпаку, где ваше приложение берет начало и далее следует по графу зависимостей, чтобы понять, что включить в бандл. Проще говоря, точка входа — это первый файл, с которого начинается ваше приложение.
PHP
module.exports = {
entry: ‘./path/to/my/entry/file.js’
};
1 |
module.exports={ entry’./path/to/my/entry/file.js’ }; |
Output
После того как вебпак собрал все исходники (“assets”) вашего приложения вместе, ему нужно знать, куда их положить и как назвать.
PHP
output: {
path: path.resolve(__dirname, ‘dist’),
filename: ‘my-first-webpack.bundle.js’
}
1 |
output{ pathpath.resolve(__dirname,’dist’), filename’my-first-webpack.bundle.js’ } |
Loaders
Webpack может работать с любыми файлами, как с модулями. Однако сам он “из коробки” понимает только javascript-файлы. Чтобы вебпак мог работать с CSS, html, jpg и пр. ему понадобится помощь. “Лоадеры” трансформируют все эти файлы ( .css, .html, .scss, .jpg, и пр.) в модули, совершают над ними определённые действия (например компилируют SCSS в CSS) и добавляют их в граф зависимостей.
Рассмотрим пример
Обратите внимание на то, что лоадеры выполняются снизу вверх
PHP
module: {
rules: [{
test: /\.scss$/,
include: paths,
use:
}]
}
1 |
module{ rules{ test\.scss$, includepaths, use ‘style-loader’, ‘css-loader’, ‘sass-loader’ } } |
В этом примере мы говорим: “Эй, вебпак, если ты встретишь .scss-файлы в нашем приложении, объявленные как модули, то, сначала, скомпилируй SCSS в CSS (sass-loader), затем помоги вебпаку их загрузить и добавить в граф (css-loader), после чего научи вебпак добавлять стили в DOM-дерево при помощи тега ˂style˃ (style-loader).”
Plugins
Плагины могут влиять непосредственно на процесс сборки (компиляции) бандлов.
PHP
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: ‘./src/index.html’})
]
1 |
plugins newwebpack.optimize.UglifyJsPlugin(), newHtmlWebpackPlugin({template’./src/index.html’}) |
Они могут минифицировать javascript или, например, генерировать html-файлы (в том числе работать с шаблонами).
Rule.generator
Rule.generator.dataUrl
When is used as an object, you can configure two properties:
- encoding: When set to , module source will be encoded using Base64 algorithm. Setting to false will disable encoding.
- mimetype: A mimetype for data URI. Resolves from module resource extension by default.
webpack.config.js
When used a a function, it executes for every module and must return a data URI string.
Rule.generator.emit
Opt out of writing assets from Asset Modules, you might want to use it in Server side rendering cases.
-
Type:
-
Available: 5.25.0+
-
Example:
The same as but for specific rule. Overrides and works only with and module types.
webpack.config.js
Собираем JavaScript
Так как Webpack создан в первую очередь для сборки js файлов, то эта часть будем самой простой. Чтобы можно было писать javascript в современном виде ES2015, который не поддерживается браузерами, поставим пакеты , , .
После создаем файл настроек с таким содержимым:
В разделе (точки входа) указываем, какой js файл будем собирать, в разделе указываем путь в папке , куда будем помещаться собранный файл
Обратите внимание, что в webpack 4 в пути саму папку указывать не нужно! И да, как же мне не нравится, что в одном файле webpack в одних случаях нужно писать относительный путь, в других случаях относительный путь в специальной папке, в третьих случаях нужен уже абсолютный путь (например, его получаем этой командой )
Также указано значение параметра , равное: , что позволит создавать карты исходников для js и css файлов.
Для обработки конкретных файлов (по расширению, по месторасположению) в webpack создаются правила в разделе . Сейчас у нас там стоит правило, что все js файлы пропускаем через транслятор Babel, который преобразует наш новомодный ES2015 в стандартный javascript вариант, понятный браузерам.
В нашем тестовом примере мы верстаем наши странице на Boostrap 4. Поэтому нам нужно будет установить три пакета: , , . Второй и третий пакет мы устанавливаем по требованию Bootstrap.
Обратите внимание на то, что эти три пакета нам нужны именно для самого сайта, а не для его сборки. Поэтому эти пакеты мы устанавливаем с флагом , а не
Теперь можно приступить к написанию нашего файла:
В качестве примера пользовательского кода js просто перекрасили цвет текста на синий.
Теперь можно перейти к сборке js файла. Для этого в файле в разделе пропишем следующие npm скрипты:
Теперь при запуске в командной строке строчки npm run dev произойдет сборка проекта (css и html файлы потом также будут собираться этой командой), и в папке появятся файлы и .
При запуске команды npm run build также произойдет сборка проекта, но уже итоговая (с оптимизацией, максимальной минимизацией файла), которую можно выкладывать на хостинг.
При запуске npm run watch запускается режим автоматического просмотра изменений файлов проекта с автоматическим допостроением измененных файлов. Да, чтобы в командной строке отключить этот режим (например, чтобы можно было написать другие команды) можно нажать (как минимум в PowerShell).
При запуске npm run start запустится локальный сервер, который запустит html страницу и также будет отслеживать изменения в файлах. Но пока этой командой не пользуемся, так как сборку html страниц не добавили.
Режим построения проекта создает или переписывает файлы в папке . Но во время разработки проекта при разных сборках файлы могут переименовываться, удаляться. И Webpack не будет следить, чтобы уже ненужные файлы, оставшиеся после предыдущих сборок, удалялись из папки . Поэтому добавим еще один пакет , который будет очищать папку перед каждой сборкой проекта.
Update 2018.04.11. Пришлось отказаться от . Почему? Когда запускаешь сервер через команду (), то webpack компилирует файлы автоматом, не сохраняя их в папку . И это нормально. Но при этом папка очищается из-за наличия . В результате в режиме работы локального сервера папка пустует, что негативно сказывается на работе с git (только в случае, если вы в git репозиторий сохраняется сборку проекта, как и я): после каждого запуска сервера появляется куча изменений из-за удаленных файлов. Было бы хорошо, чтобы очистка папки происходила только при полноценной сборке, например, (об этой команде ниже). Плагин настроить нужным способом не смог. Поэтому использую другой плагин , который не связан с webpack и работает отдельно.
Внесем изменения в файл .
Сборка HTML страниц
Перейдем к самому веселому: к сборке HTML страниц, где у меня возникли самые большие трудности.
Для сборки HTML страниц будем использовать плагин , который поддерживает различные виды шаблонизаторов. Также нам потребуются пакет .
В качестве шаблонизатора HTML будем использовать шаблонизатор по умолчанию lodash. Вот так будет выглядеть типичная HTML страница до сборки:
Вначале в переменной прописываем все наши переменные страницы, которые хотим использовать на этой странице. Потом встраиваем шаблоны шапки и футера через .
Важное уточнение. В статьях про сборку HTML страниц через обычно подключают встраиваемые шаблоны просто через команду:. Но при этом в этих встраиваемых шаблонах синтаксис lodash работать не будет (я так и не понял, почему так происходит)
И данные из переменной туда не передадутся. Поэтому принудительно говорим webpack, что мы встраиваем именно шаблон, который надо обработать как lodash шаблон
Но при этом в этих встраиваемых шаблонах синтаксис lodash работать не будет (я так и не понял, почему так происходит). И данные из переменной туда не передадутся. Поэтому принудительно говорим webpack, что мы встраиваем именно шаблон, который надо обработать как lodash шаблон.
Теперь мы можем использовать полноценные lodash синтаксис в встраиваемых шаблонах. В коде файла ниже через печатаем заголовок статьи.
В пакете html-webpack-plugin генерировать несколько HTML страниц:
Но прописывать для каждой страницы создание своего экземпляра плагина точно не есть хорошо. Поэтому автоматизируем этот процесс, найдя все HTML файлы в папке и создадим для них свои версии .
Для этого в файле внесем следующие изменения:
Функция будет осуществлять поиск всех HTML страниц
Обратите внимание, что в коде функции есть настройка , которая говорит Webpack, что не нужно встраивать ссылки на js и css файл в HTML код самостоятельно: мы сделаем всё сами вручную в шаблонах и
Также нужно отметить, что встраиваемые шаблоны обрабатываются плагином (содержимое файла просто загрузить как текст), а не , как чаще всего предлагают. И также, как в случае с CSS, не использую пакеты или .
И остается последний необязательный момент для работы с HTML. JavaScript файл и CSS файл у нас будут минимифицроваться. А вот HTML файлы хочу, наоборот, сделать красивыми и не минифицировать. Поэтому после сборки всех HTML файлов хочется пройтись по ним каким-то beautify плагином. И тут меня ждала подстава: не нашел способа как это сделать в Webpack. Проблема в том, что обработать файлы нужно после того, как будут вставлены встраиваемые шаблоны.
Нашел пакет html-cli, который может это сделать независимо от Webpack. Но у него 38 установок в месяц. То есть это означает два варианта: либо никому не нужно приводить к красивому внешнему виду HTML файлы, либо есть другое популярное решение, о котором я не знаю. А ради только одной этой функции Gulp прикручивать не хочется.
Устанавливаем этот плагин:
И в файле прописываем еще два скрипта, которые после работы Webpack будут приводить к красивому внешнему виду HTML файлы с установкой табуляции в два пробела.
Update 2018.04.11 Обратите внимание на то, что в команду я добавил еще , который очищает папку перед сборкой. Поэтому для итоговой сборки рекомендую использовать не команду *npm run build, а команду npm run build-and-beautify
Поэтому для итоговой сборки рекомендую использовать не команду *npm run build, а команду npm run build-and-beautify.
Loading Polyfills
Almost everything we’ve discussed thus far has been in relation to handling legacy packages. Let’s move on to our second topic: polyfills.
There’s a lot of ways to load polyfills. For example, to include the we might simply:
and it so as to include it in our main bundle:
src/index.js
Note that this approach prioritizes correctness over bundle size. To be safe and robust, polyfills/shims must run before all other code, and thus either need to load synchronously, or, all app code needs to load after all polyfills/shims load. There are many misconceptions in the community, as well, that modern browsers «don’t need» polyfills, or that polyfills/shims merely serve to add missing features — in fact, they often repair broken implementations, even in the most modern of browsers. The best practice thus remains to unconditionally and synchronously load all polyfills/shims, despite the bundle size cost this incurs.
If you feel that you have mitigated these concerns and wish to incur the risk of brokenness, here’s one way you might do it: Let’s move our to a new file and add the polyfill:
src/index.js
project
src/polyfills.js
webpack.config.js
With that in place, we can add the logic to conditionally load our new file. How you make this decision depends on the technologies and browsers you need to support. We’ll just do some simple testing to determine whether our polyfills are needed:
dist/index.html
Now we can some data within our entry script:
src/index.js
If we run our build, another file will be emitted and everything should still run smoothly in the browser. Note that this set up could likely be improved upon but it should give you a good idea of how you can provide polyfills only to the users that actually need them.
Introduction
webpack is a bundler for modules. The main purpose is to bundle JavaScript
files for usage in a browser, yet it is also capable of transforming, bundling,
or packaging just about any resource or asset.
TL;DR
- Can create a single bundle or multiple chunks that are asynchronously loaded at runtime (to reduce initial loading time).
- Dependencies are resolved during compilation, reducing the runtime size.
- Loaders can preprocess files while compiling, e.g. TypeScript to JavaScript, Handlebars strings to compiled functions, images to Base64, etc.
- Highly modular plugin system to do whatever else your application requires.
UseEntry
It must have a property being a string. It is resolved relative to the configuration with the loader resolving options ().
It can have an property being a string or object. This value is passed to the loader, which should interpret it as loader options.
For compatibility a property is also possible, which is an alias for the property. Use the property instead.
Note that webpack needs to generate a unique module identifier from the resource and all loaders including options. It tries to do this with a of the options object. This is fine in 99.9% of cases, but may be not unique if you apply the same loaders with different options to the resource and the options have some stringified values.
It also breaks if the options object cannot be stringified (i.e. circular JSON). Because of this you can have a property in the options object which is used as unique identifier.
webpack.config.js
A can also be a function which receives the object argument describing the module being loaded, and must return a non-function object. This can be used to vary the loader options on a per-module basis.
The object parameter has the following fields:
- : The current webpack compiler (can be undefined)
- : The path to the module that is importing the module being loaded
- : Always the path to the module being loaded
- : The path to the module being loaded, it is usually equal to except when the resource name is overwritten via in request string
webpack.config.js
Разное
Регулярно обновляйте ваше ПО и зависимости. Более свежие версии Node.js, npm / yarn и инструментов для сборки (webpack, Babel и др.) часто содержат улучшения производительности. Разумеется, перед началом эксплуатации новой версии стоит внимательно ознакомиться с changelog, issues, отчётами по безопасности, убедиться в стабильности и провести тестирование.
При использовании PostCSS и postcss-preset-env обратите внимание на настройку stage, которая отвечает за набор поддерживаемых фич. Например, в нашем проекте был установлен stage-3, из которого использовались только Custom Properties, и переключение на stage-4 сократило время сборки на 13%
Если вы используете Sass (node-sass, sass-loader), попробуйте Dart Sass (реализация Sass на Dart, скомпилированная в JS) и fast-sass-loader. Возможно, на вашем проекте они дадут прирост производительности сборки. Но даже если не дадут — dart-sass хотя бы устанавливается быстрее, чем node-sass, потому что является чистым JS, а не биндингом для libsass.
Пример использования Dart Sass можно найти в
Обратите внимание на явное указание конкретной имплементации препроцессора Sass и использование модуля fibers
Если вы используете CSS-модули, попробуйте отключить добавление хешей в сгенерированные имена классов в dev-режиме. Генерирование уникальных идентификаторов занимает какое-то время, которое можно сэкономить, если включения путей к файлам в имена классов достаточно, чтобы избежать коллизий.
Пример:
Выгода, тем не менее, невелика: на нашем проекте это менее полсекунды.
Возможно, вы когда-нибудь встречали в документации webpack таинственный PrefetchPlugin, который вроде бы обещает ускорить сборку, но каким образом — неизвестно. Создатель webpack в кратко рассказал о том, какую проблему решает этот плагин. Однако как же его использовать?
- Выгрузить в файл статистику сборки. Это делается с помощью CLI-опции , подробнее см. в документации. Актуально, скорее всего, только для dev-режима сборки.
- Загрузить полученный файл в специальный онлайн-анализатор и перейти на вкладку Hints.
- Найти секцию, озаглавленную “Long module build chains”. Если её нет, на этом можно закончить — PrefetchPlugin не понадобится.
- Для найденных длинных цепочек использовать PrefetchPlugin. В качестве стартового примера см. топик на StackOverflow.
Итого: слабо документированный способ без гарантии на заметный положительный результат.
Creating a Bundle
First we’ll tweak our directory structure slightly, separating the «source» code () from our «distribution» code (). The «source» code is the code that we’ll write and edit. The «distribution» code is the minimized and optimized of our build process that will eventually be loaded in the browser. Tweak the directory structure as follows:
project
To bundle the dependency with , we’ll need to install the library locally:
Now, let’s import in our script:
src/index.js
Now, since we’ll be bundling our scripts, we have to update our file. Let’s remove the lodash , as we now it, and modify the other tag to load the bundle, instead of the raw file:
dist/index.html
In this setup, explicitly requires to be present, and binds it as (no global scope pollution). By stating what dependencies a module needs, webpack can use this information to build a dependency graph. It then uses the graph to generate an optimized bundle where scripts will be executed in the correct order.
With that said, let’s run , which will take our script at as the entry point, and will generate as the output. The command, which ships with Node 8.2/npm 5.2.0 or higher, runs the webpack binary () of the webpack package we installed in the beginning:
Open from the directory in your browser and, if everything went right, you should see the following text: .
Добавление тестовых сценариев в сборку
Добавим несколько тестовых сценариев в файл . Для этого будем использовать Mocha, пакетный инструмент для написания тестов, и Chai в качестве нашей библиотеки установок. Выполните следующую команду:
Затем создайте новый каталог и новый файл , содержащий следующий фрагмент:
Теперь у вас есть тестовые сценарии для функций и , устанавливающие, что вычисляет формулу расстояния, а сортирует массивы координат с помощью формулы расстояния, используя наборы тестов Mocha и установки Chai. Довольно стандартная тестовая настройка.
Однако, если выполнить , будет ошибка «Код JavaScript недопустим», потому что он содержит ключевое слово , которое Node в данный момент не поддерживает. Но что если обойти это ограничение, используя Webpack для управления зависимостями тестового кода?
Прим.: это можно легко исправить, просто используя вместо в тестовых файлах. Но тестовый код также будет проходить через процесс сборки, если вы тестируете JavaScript-код типа Flow, который использует аннотации, или веб-приложения Vue.js, которые используют файлы . Все они должны быть преобразованы в обычный JavaScript.
Список тестовых инструкций:
- Webpack строит граф зависимостей, начинающийся с тестовых файлов, а не с файлов приложения.
- Webpack создаёт файл JavaScript, содержащий весь тестовый код и его зависимости без ключевого слова .
- Выполняются тесты, запуская Mocha для этого JavaScript-файла.
Всё это будет выглядеть следующим образом:
Как можно увидеть, будут происходить две отдельные сборки. Одна из которых содержит код приложения в качестве точки входа и папку в качестве выходной директории, а другая — тестовые файлы в качестве точки входа и папку в качестве выходного каталога. Итак, давайте обновим конфигурационный файл, чтобы Webpack поддерживал вторую сборку:
Давайте разберёмся, что этот код делает. В строке 4 есть оператор , который выполняется, если системная переменная имеет непустое значение. Так что, если вы выполните , то вам придётся вводить оператор , но это не потребуется, если просто выполнить .
Внутри оператора происходит выбор, какой JS-файл является точкой входа. Вместо уже установленного выходного каталога будет папка . А вместо точки входа — массив файлов, соответствующих глобальному выражению . Другими словами, это все файлы, которые находятся в каталоге и имеют путь, заканчивающийся на .
Новая точка входа и выходной путь передаются в объект , затем запускается Webpack для создания тестовой сборки. Конфигурация Webpack представляет собой обычный код JavaScript, поэтому можно использовать стандартную библиотеку Node и операторы для её настройки. Если выполнить , то можно увидеть каталог . А если запустить , то можно увидеть, как выполняются ваши тесты.
Наконец, в разделе вашего добавьте следующую строку:
Это означает, что когда вы выполняете , создаётся каталог (каталог сборки тестирования) с помощью Webpack, затем запускается Mocha для этой сборки, и, наконец, код удаляет каталог , поскольку он больше не используется (Commit 7).
Постановка задачи
- из SASS (точнее SCSS) файлов формируется один CSS файл;
- из различных JavaScript библиотек и пользовательского кода формируется один JavaScript файл;
- HTML страницы собираются с помощью шаблонизатора, где содержимое шапки и футера можно разнести по отдельным файлам.
В собранном сайте не должны использоваться React, Vue.js.
При выборе технологий выбираются по возможности наиболее популярные на данный момент. По этой причине отказался и от Grunt и Gulp в пользу Webpack, хотя, если честно, синтаксис Gulp мне понравился больше своим однообразием.
Для примера будет сверстано несколько страничек на базе Bootstrap 4. Но это только для примера.
Предполагается, что Node.js установлен (в Windows просто скачивается установщик и устанавливается в стиле «далее, далее»), и вы умеете работать с командной строкой.
Update. Нужно получить набор готовых HTML страниц, которые можно залить на хостинг без дополнительных настроек (например, на GitHub Pages) или открыть локально на компьютере.
Options
Type: — default:
Test to match files against.
Type: Default:
Files to include.
webpack.config.js
Type: Default:
Files to exclude.
webpack.config.js
Type: Default:
Use multi-process parallel running to improve the build speed. Default number of concurrent runs: .
Enable/disable multi-process parallel running.
webpack.config.js
Enable multi-process parallel running and set number of concurrent runs.
webpack.config.js
Type: Default:
Allows to override default minify function. By default plugin uses cssnano package. Useful for using and testing unpublished versions or forks.
Possible options:
- CssMinimizerPlugin.cssnanoMinify
- CssMinimizerPlugin.cssoMinify
- CssMinimizerPlugin.cleanCssMinify
- async (data, inputMap, minimizerOptions) => {return {code: , map: , warnings: []}}
webpack.config.js
If an array of functions is passed to the option, the must also be an array. The function index in the array corresponds to the options object with the same index in the array.
webpack.config.js
Type: Default:
Cssnano optimisations options.
The function index in the array corresponds to the options object with the same index in the array. If you use like object, all function accept it.
Type: Default:
Allows to specify options for the cssnano. The , and can be either a function or a string indicating the module that will be imported.
Type: Default:
Allow to filter css-minimizer warnings (By default cssnano). Return to keep the warning, a falsy value (//) otherwise.
webpack.config.js
Решение на webpack 5
Для начала, необходимо явно указать, что мы хотим использовать Asset Modules. Для этого добавим в конфигурацию следующее:
На данный момент это экспериментальная фича и мы ждем от пользователей обратную связь по ее использованию.
После этого, достаточно просто пометить svg-файлы как и всё то, что было описано выше касаемо и — заработает само, из коробки, без каких-либо лоадеров:
Вот и всё, для файлов, которые попадают под правило с будет применяться следующая логика: Если файл меньше 8кб (по умолчанию), то встроить его в собранный бандл, в ином случае поместить его в директорию с собранным бандлом.
Свойство так же учитывается.
Помимо есть и другие встроенные типы модулей.
asset/inline
Это аналог . Файлы, которые будут подпадать под правило с будут всегда инлайниться в бандл в виде data-url:
Более того, для можно задавать кастомный генератор data-url.
Например, для svg-файлов можно использовать , который инлайнит svg как data-url, но без использования base64, что позволяет уменьшить размер встроенного фрагмента:
В результате получим такой css:
Таким образом можно совмещать использование лоадеров и кастомное поведение для генерирования data-url.
asset/resource
Это аналог file-loader. Файлы, которые будут подпадать под правило с будут складываться в директорию с бандлом:
Указываем путь
По умолчанию, модули с типом складываются в директорию, которую вы указываете в (по умолчанию ), но при помощи можно переопределить это поведение:
Вывод:
А заменив на мы получим прекрасный вариант для long term caching:
Вывод:
Более того, мы можем переопределить имя выходного файла для конкретного asset-правила. Например, можно складывать svg-иконки в директорию , а остальные asset-модули в директорию :
Вывод:
asset/source
Это аналог raw-loader. Файлы, которые будут подпадать под правило с будут всегда инлайниться в бандл в неизменном виде:
Вывод:
asset
Объединяет в себе и , автоматически выбирая что-то одно, в зависимости от некоторых условий. По умолчанию, если размер файла больше 8кб, то применяется стратегия , в ином случае — .
Лимит для применения можно установить:
Подводя итог: Asset Modules в webpack 5 позволяют отказаться от некоторых привычных лоадеров за счет поддержки их функциональности «из коробки».
Полноценный пример можно посмотреть здесь.
Setup
The goals of development and production builds differ greatly. In development, we want strong source mapping and a localhost server with live reloading or hot module replacement. In production, our goals shift to a focus on minified bundles, lighter weight source maps, and optimized assets to improve load time. With this logical separation at hand, we typically recommend writing separate webpack configurations for each environment.
While we will separate the production and development specific bits out, note that we’ll still maintain a «common» configuration to keep things DRY. In order to merge these configurations together, we’ll use a utility called . With the «common» configuration in place, we won’t have to duplicate code within the environment-specific configurations.
Let’s start by installing and splitting out the bits we’ve already worked on in previous guides:
project
webpack.common.js
webpack.dev.js
webpack.prod.js
In , we now have setup our and configuration and we’ve included any plugins that are required for both environments. In , we’ve set to . Also, we’ve added the recommended for that environment (strong source mapping), as well as our simple configuration. Finally, in , is set to which loads , which was first introduced by the tree shaking guide.
Note the use of calls in the environment-specific configurations to include our common configuration in and . The tool offers a variety of advanced features for merging but for our use case we won’t need any of that.
Базовые понятия Webpack
- Entry – модуль, который используется для построения внутреннего графа зависимостей. С его помощью webpack определяет, от каких модулей и библиотек зависит точка входа (напрямую и не напрямую). Затем включает их в граф, пока не останется ни одной зависимости. По умолчанию для свойства entry установлено значение ./src/index.js. Но можно указать другой модуль в файле конфигурации сборщика.
- Output – это свойство указывает, где webpack должен сохранять бандл и как называть его файл (или файлы). Значением по умолчанию является ./dist/main.js для основного бандла и ./dist для других сгенерированных файлов.
- Загрузчики. По умолчанию webpack понимает только файлы JavaScript и JSON. Чтобы обработать другие типы файлов и конвертировать их в модули, сборщик использует загрузчики. Например, загрузчик может трансформировать файлы из языка CoffeeScript в JavaScript или встроенные изображения в URL-адреса. С помощью загрузчиков можно даже импортировать CSS-файлы прямо из модулей JavaScript.
- Плагины. Используются для задач, которые не могут выполнять загрузчики.
- Режимы. Webpack позволяет настроить режим на development, production или none. Благодаря этому он может использовать встроенные оптимизации для каждой среды. По умолчанию установлено значение Режим none означает, что все опции оптимизации по умолчанию будут отключены. Чтобы узнать больше об опциях, которые webpack использует в development и production, посетите страницу конфигурации режимов.
Структура проекта
Общая структура проекта представлена ниже:
Под favicon выделена целая папка, так как в современном web обычным одним ico файлом не обойтись. Но для примера используется только этот один файл.
Спорным решением может показаться разделение картинок на две папки: и . Но здесь использовал идеологию расположения файлов из WordPress. На мой взгляд, кидать все изображения в одну папку — не очень хорошая идея.
Для работы с проектом использую Visual Studio Code, которым очень доволен. Особенно мне нравится, что командная строка встроена в программу и вызывается через Ctrl + `.
Сделаем болванку Node.js проекта. Для этого создадим папку нашего проекта с вышеописанной структурой и перейдем в неё в командной строке, где вызовем команду для создания файла .
На все вопросы можно просто отвечать, нажимая , если заполнять подробную информацию не хочется.
Установим три общих пакета, которые нам потребуются в любом случае: , (работу с командной строкой в webpack вынесли в отдельный пакет) и (для запуска локального сервера, чтобы в браузере сразу отображались сохраненные изменения проекта).
Также создастся файл , который вообще не трогаем. Но в git репозиторий добавлять этот файл нужно, в отличии от папки , которую нужно прописать в файле , если пользуетесь git.