Разработка
Это руководство дополняет примеры кода, представленные в руководстве Управление выводом.
Если вы следовали руководствам, то должны хорошо понимать некоторые основы webpack. Прежде чем продолжить, давайте рассмотрим настройку среды разработки, чтобы немного облегчить себе жизнь.
Инструменты в этом руководстве предназначены только для разработки, пожалуйста, не используйте их в рабочей среде!
Начнем с настройки mode до 'development'.
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
+ mode: 'development',
entry: {
app: './src/index.js',
print: './src/print.js',
},
plugins: [
// new CleanWebpackPlugin(['dist/*']) for < v2 versions of CleanWebpackPlugin
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
}; Использование source map
Когда webpack собирает ваш исходный код, может быть сложно отслеживать ошибки и предупреждения до их исходного расположения. Например, если вы объедините три исходных файла (a.js, b.js и c.js) в один пакет (bundle.js), и один из исходных файлов содержит ошибку, сообщение об ошибке будет указывать только на bundle.js. Это не всегда полезно, так как вы, вероятно, хотите знать, из какого именно исходного файла исходит ошибка.
Чтобы облегчить отслеживание ошибок и предупреждений, JavaScript предлагает source map, которые сопоставляют ваш скомпилированный код с исходным кодом. Если ошибка произошла из b.js, source map покажет именно это.
Существует множество различных вариантов для source map. Обязательно ознакомьтесь с ними, чтобы настроить их под свои нужды.
Для этого руководства давайте воспользуемся вариантом inline-source-map, который подходит для наглядных примеров (хотя не для рабочей среды):
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
app: './src/index.js',
print: './src/print.js',
},
+ devtool: 'inline-source-map',
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
}; Теперь давайте создадим что-то для отладки, добавив ошибку в наш print.js файл:
src/print.js
export default function printMe() {
- console.log('I get called from print.js!');
+ cosnole.log('I get called from print.js!');
} Запустите npm run build, оно должно скомпилироваться примерно так:
...
Asset Size Chunks Chunk Names
app.bundle.js 1.44 MB 0, 1 [emitted] [big] app
print.bundle.js 6.43 kB 1 [emitted] print
index.html 248 bytes [emitted]
... Теперь откройте получившийся index.html файл в вашем браузере. Нажмите кнопку и посмотрите в консоль, где отображается ошибка. Ошибка должна быть примерно такой:
Uncaught ReferenceError: cosnole is not defined at HTMLButtonElement.printMe (print.js:2)
Мы видим, что ошибка также содержит ссылку на файл (print.js) и номер строки (2), где произошла ошибка. Это замечательно, потому что теперь мы точно знаем, где искать решение проблемы.
Выбор инструмента разработки
В некоторых редакторах текста есть функция «безопасной записи», которая может конфликтовать с некоторыми из следующих инструментов. Прочитайте раздел Настройка текстового редактора для решения этих проблем.
Ручной запуск npm run build каждый раз, когда вам нужно скомпилировать код, быстро становится проблемой.
В webpack есть несколько вариантов, которые позволяют автоматически перекомпилировать код при изменении:
- Режим наблюдения (Watch Mode) webpack
- webpack-dev-server
- webpack-dev-middleware
В большинстве случаев вы, вероятно, захотите использовать webpack-dev-server, но давайте рассмотрим все вышеперечисленные варианты.
Использование режима наблюдения
Вы можете указать webpack «наблюдать» за всеми файлами в вашем графе зависимостей на предмет изменений. Если один из этих файлов обновляется, код будет перекомпилирован, так что вам не придётся запускать полную сборку вручную.
Давайте добавим npm скрипт, который запустит режим наблюдения webpack:
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
+ "watch": "webpack --watch",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"clean-webpack-plugin": "^2.0.0",
"css-loader": "^0.28.4",
"csv-loader": "^2.1.1",
"file-loader": "^0.11.2",
"html-webpack-plugin": "^2.29.0",
"style-loader": "^0.18.2",
"webpack": "^4.30.0",
"xml-loader": "^1.2.1"
}
} Теперь запустите npm run watch из командной строки и посмотрите, как webpack компилирует ваш код. Вы увидите, что командная строка не закрывается, так как скрипт следит за вашими файлами.
Теперь, пока webpack следит за файлами, давайте удалим ошибку, которую мы добавили ранее:
src/print.js
export default function printMe() {
- cosnole.log('I get called from print.js!');
+ console.log('I get called from print.js!');
} Теперь сохраните файл и проверьте окно терминала. Вы увидите, что webpack автоматически перекомпилирует изменённый модуль!
Единственный недостаток заключается в том, что вам нужно обновить браузер, чтобы увидеть изменения. Было бы намного удобнее, если бы это происходило автоматически, поэтому давайте попробуем webpack-dev-server, который сделает именно это.
Использование webpack-dev-server
webpack-dev-server предоставляет вам простой веб-сервер и возможность использования живой перезагрузки. Давайте его настроим:
npm install --save-dev webpack-dev-server
Измените свой конфигурационный файл, чтобы указать серверу разработки, где искать файлы:
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
app: './src/index.js',
print: './src/print.js',
},
devtool: 'inline-source-map',
+ devServer: {
+ contentBase: './dist',
+ },
plugins: [
// new CleanWebpackPlugin(['dist/*']) for < v2 versions of CleanWebpackPlugin
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
}; Это говорит webpack-dev-server обслуживать файлы из каталога dist по адресу localhost:8080.
webpack-dev-server не записывает никакие выходные файлы после компиляции. Вместо этого он хранит файлы пакета в памяти и отображает их как реальные файлы, смонтированные в корневом пути сервера. Если ваша страница ожидает найти файлы пакета по другому пути, вы можете изменить это с помощью опции
publicPathв конфигурации сервера разработки.
Давайте добавим скрипт для простого запуска сервера разработки:
package.json
{
"name": "development",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
+ "start": "webpack-dev-server --open",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"clean-webpack-plugin": "^2.0.0",
"css-loader": "^0.28.4",
"csv-loader": "^2.1.1",
"express": "^4.15.3",
"file-loader": "^0.11.2",
"html-webpack-plugin": "^2.29.0",
"style-loader": "^0.18.2",
"webpack": "^4.30.0",
"webpack-dev-server": "^3.8.0",
"xml-loader": "^1.2.1"
}
} Теперь мы можем запустить npm start из командной строки, и наш браузер автоматически загрузит нашу страницу. Если вы измените любые исходные файлы и сохраните их, веб-сервер автоматически перезагрузится после компиляции кода. Попробуйте!
У webpack-dev-server много настраиваемых опций. Обратитесь к документации, чтобы узнать больше.
Теперь, когда ваш сервер работает, вы можете попробовать горячую перезагрузку модулей!
Использование webpack-dev-middleware
webpack-dev-middleware — это оболочка, которая будет передавать файлы, обработанные webpack, на сервер. Это используется в webpack-dev-server в качестве внутренней функции, однако оно доступно как отдельный пакет для более настраиваемых сценариев, если это необходимо. Мы рассмотрим пример, объединяющий webpack-dev-middleware с сервером express.
Давайте установим express и webpack-dev-middleware, чтобы начать:
npm install --save-dev express webpack-dev-middleware
Теперь нам нужно внести некоторые изменения в наш конфигурационный файл webpack, чтобы убедиться, что middleware будет работать правильно:
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
app: './src/index.js',
print: './src/print.js',
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Output Management',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
+ publicPath: '/',
},
}; publicPath будет использоваться в нашем скрипте сервера, чтобы убедиться, что файлы будут корректно обслуживаться на http://localhost:3000. Мы укажем номер порта позже. Следующим шагом будет настройка нашего собственного сервера express:
project
webpack-demo
|- package.json
|- webpack.config.js
+ |- server.js
|- /dist
|- /src
|- index.js
|- print.js
|- /node_modules server.js
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);
// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath,
}));
// Serve the files on port 3000.
app.listen(3000, function () {
console.log('Example app listening on port 3000!\n');
}); Теперь добавим npm скрипт, чтобы было легче запускать сервер:
package.json
{
"name": "development",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"start": "webpack-dev-server --open",
+ "server": "node server.js",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"clean-webpack-plugin": "^2.0.0",
"css-loader": "^0.28.4",
"csv-loader": "^2.1.1",
"express": "^4.15.3",
"file-loader": "^0.11.2",
"html-webpack-plugin": "^2.29.0",
"style-loader": "^0.18.2",
"webpack": "^4.30.0",
"webpack-dev-middleware": "^1.12.0",
"webpack-dev-server": "^3.8.0",
"xml-loader": "^1.2.1"
}
} Теперь в вашем терминале запустите npm run server, оно должно вывести вывод, похожий на этот:
Example app listening on port 3000!
...
Asset Size Chunks Chunk Names
app.bundle.js 1.44 MB 0, 1 [emitted] [big] app
print.bundle.js 6.57 kB 1 [emitted] print
index.html 306 bytes [emitted]
...
webpack: Compiled successfully. Теперь откройте ваш браузер и перейдите по адресу http://localhost:3000. Вы увидите, что приложение webpack запущено и работает!
Если вы хотите узнать больше о том, как работает горячая перезагрузка модулей, мы рекомендуем вам прочитать руководство горячей перезагрузки модулей.
Настройка текстового редактора
При использовании автоматической компиляции кода могут возникнуть проблемы при сохранении файлов. Некоторые редакторы имеют функцию «безопасной записи», которая потенциально может мешать перекомпиляции.
Чтобы отключить эту функцию в некоторых распространённых редакторах, см. список ниже:
-
Sublime Text 3: Добавьте
atomic_save: 'false'в ваши пользовательские настройки. -
IDE JetBrains (например, WebStorm): Снимите флажок «Использовать безопасную запись» в
Preferences > Appearance & Behavior > System Settings. -
Vim: Добавьте
:set backupcopy=yesв ваши настройки.
Заключение
Теперь, когда вы узнали, как автоматически компилировать код и запускать простой сервер разработки, вы можете перейти к следующему руководству, которое расскажет о горячей перезагрузке модулей.
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://v4.webpack.js.org/guides/development