Webpack
Why does Webpack exist?
Webpack - это сборщик модулей. Он анализирует модули приложения, создает граф зависимостей, затем собирает модули в правильном порядке в один или более бандл (bundle), на который может ссылаться файл «index.html».
App.js -> |
Dashboard.js -> | Bundler | -> bundle.js
About.js -> |
What problem is webpack solving?
Обычно, при создании приложения на JavaScript, код разделяется на несколько частей (модулей). Затем в файле «index.html» необходимо указать ссылку на каждый скрипт.
<body>
...
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="libs/react.min.js"></script>
<script src='src/admin.js'></script>
<script src='src/dashboard.js'></script>
<script src='src/api.js'></script>
<script src='src/auth.js'></script>
<script src='src/rickastley.js'></script>
</body>
What problem is webpack solving?
Если загрузить скрипт, зависящий от React, до загрузки самого React, приложение сломается.
<body>
...
<script src='dist/bundle.js'></script>
</body>
В папке dist обычно храним наш bundle.js который формируется нашим сборщиком (webpack).
What problem is webpack solving?
При необходимости можно заставить webpack осуществить некоторые преобразования модулей перед их добавлением в bundle. Например, преобразование SASS/LESS в обычный CSS, или современного JavaScript в ES5 для старых браузеров.
Webpack
npm init
Установка webpack. В вашем проекте должен быть файл package.json
Установка webpack. В вашем проекте должен быть файл package.json
npm i webpack webpack-cli --save-dev
Теперь в вашем проекте будет добавлен webpack в dev dependencies.
Webpack
{
//...
"scripts": {
"build": "webpack"
}
}
Теперь обновим скрипт в нашем packege.json
Как только все будет сделано, вы можете запустить Webpack, набрав:
npm run build
Webpack
По умолчанию, Webpack (начиная с 4-й версии) не требует никакой настройки, если вы соблюдаете эти правила:
- точкой входа вашего приложения является ./src/index.js
- вывод (output) размещается в ./dist/main.js
- Webpack работает в production mode (режим производства)
Webpack
Если у нас точка вода в другом месте можем это указать в конфиге.
// webpack.config.js
module.exports = {
entry: './src/index.js'
}
Webpack
Конечно, если понадобится, вы сможете настроить каждую мельчайшую деталь в Webpack. Конфигурационный файл Webpack -webpack.config.js хранится в корневой директории проекта.
// webpack.config.js
module.exports = {
entry: './src/index.js'
}
Webpack
По умолчанию, вывод размещается в ./dist/main.js. В нижеприведенном примере, результат работы в Webpack генерируется в файле app.js:
// webpack.config.js
const path = require('path');
module.exports = {
/*...*/
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
}
/*...*/
}
Webpack
С помощью Webpack можно использовать оператор import или require в своем JavaScript коде для того, чтобы подключать файлы любого типа (например, CSS).
// webpack.config.js
const path = require('path');
module.exports = {
/*...*/
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
}
/*...*/
}
Webpack
По умолчанию при создании графика зависимостей на основе операторов import / require() вебпак способен обрабатывать только JavaScript и JSON-файлы.
Webpack
Едва ли в своем приложении вы решитесь не ограничиться JS и JSON-файлами, скорее всего, вам также потребуются стили, SVG, изображения и т.д. Вот где нужны лоадеры. Основной задачей лоадеров, как следует из их названия, является предоставление вебпаку возможности работать не только с JS и JSON-файлами.
Webpack
В Webpack загрузчики являются аналогами задач (tasks) в Grunt и Gulp. Они принимают содержимое файлов, а затем преобразуют его необходимым образом и включают результат преобразования в общую сборку. Например, они могут компилировать TypeScript, загружать компоненты Vue.js и многое другое.
Webpack
Например, в своем коде вы можете использовать:
import 'style.css'
Указав конфигурацию данного загрузчика в файле webpack.config.js:
module.exports = {
/*...*/
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' }
]
}
/*...*/
}
Предварительно данный лоадер нужно установить.
npm install --save-dev css-loader
Webpack
Однако для того, чтобы наши стили работали корректно, нужно добавить еще один лоадер. Благодаря css-loader мы можем импортировать CSS-файлы. Но это не означает, что они будут включены в DOM. Мы хотим не только импортировать такие файлы, но и поместить их в тег <style>, чтобы они применялись к элементам DOM. Для этого нужен style-loader.
npm i style-loader --save-dev
Webpack
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
}]
}
}
Обратите внимание, что поскольку для обработки CSS-файлов используется два лоадера, значением свойства use является массив.
Webpack
npm install --save-dev babel-loader @babel/core @babel/preset-env webpack
Лоадеры могут использоваться не только для импорта файлов, но и для их преобразования. Самым популярным является преобразование JavaScript следующего поколения в современный JavaScript с помощью Babel. Для этого используется babel-loader.
Webpack
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
}
}
Webpack plugins
В отличие от лоадеров, плагины позволяют выполнять задачи после сборки бандла. Эти задачи могут касаться как самого бандла, так и другого кода. Вы можете думать о плагинах как о более мощных, менее ограниченных лоадерах.
Webpack plugins
HTMLWebpackPlugin
Плагин HTMLWebpackPlugin автоматически создает HTML-файл в дириктории с бандлом с уже подключенным скриптом.
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
plugins: [
new HtmlWebpackPlugin(),
]
}
npm i --save-dev html-webpack-plugin
Webpack plugins
Еще один полезный плагин,CleanWebpackPlugin, мы можем использовать перед перегенерацией файлов, чтобы очистить нашу папку dist/ и получить аккуратный файл с конфигурацией.
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
plugins: [
new HtmlWebpackPlugin(),
new CleanWebpackPlugin(),
]
}
npm install --save-dev clean-webpack-plugin
Webpack environments
Данные режимы (появившиеся в 4-й версии Webpack) настраивают среду, в которой будет работать Webpack. Режим может быть настроен на development или production (по умолчанию стоит production).
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development',
}
Webpack environments
Режим development:
- менее оптимизирован, чем production
- работает быстрее
- не удаляет комментарии
- предоставляет более подробные сообщения об ошибках и способы их решения
- сильно облегчает отладку
Webpack watch
Webpack может автоматически перестраивать бандл, когда в вашем приложении происходят изменения. Для этого добавьте данный скрипт:
{
"name": "test-app",
"version": "1.0.0",
"description": "",
"main": "src/index.js",
"scripts": {
"build": "webpack",
"watch": "webpack --watch"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.58.1",
"webpack-cli": "^4.9.0"
}
}
npm run watch
Webpack watch
Одной из приятных особенностей watch mode (режима просмотра) является то, что бандл изменяется только в том случае, если в сборке нет ошибок. Если ошибки присутствуют, watch продолжит следить за изменениями и будет пытаться перестраивать бандл, но текущий, рабочий бандл не зависит от проблемных бандлов.
Webpack source map
С транспилированным кодом, зачастую, возникают проблемы при отладке кода в браузере или анализе ошибок. Так как транспилированный и трудночитаемый JavaScript, а не оригинальный код, затрудняет поиск и исправление ошибок. Source Map — это JSON-файл, который содержит информацию о том, как транспилировать код обратно в исходный код.
Source Maps можно сгенерировать, используя свойство конфигурации devtool:
Webpack source map
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin()
],
mode: 'development',
devtool: 'inline-source-map',
}
Webpack source map
- none: не добавляет Source Maps
- source-map: идеально подходит для режима production, предоставляет отдельную Source Map, которую можно свернуть и добавляет ссылку в бандл, чтобы инструменты разработки знали о том, что Source Map доступна
- inline-source-map: идеально подходит для режима development, встраивает Source Maps в качестве data:URL
Webpack
By Oleg Rovenskyi
Webpack
- 218