如果您一直在学习这些指南,您应该对 webpack 的一些基础知识有了扎实的理解。在继续之前,让我们研究一下如何设置开发环境,以便让我们的工作更轻松一些。
首先将mode
设置为 'development'
,并将 title
设置为 'Development'
。
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
+ mode: 'development',
entry: {
index: './src/index.js',
print: './src/print.js',
},
plugins: [
new HtmlWebpackPlugin({
- title: 'Output Management',
+ title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};
当 webpack 打包您的源代码时,要追踪错误和警告的原始位置可能会变得困难。例如,如果您将三个源文件(a.js
、b.js
和 c.js
)打包成一个文件(bundle.js
),并且其中一个源文件包含错误,则堆栈跟踪将指向 bundle.js
。这并非总是很有用,因为您可能想确切知道错误来自哪个源文件。
为了更容易地追踪错误和警告,JavaScript 提供了Source Maps,它可以将您的编译代码映射回原始源代码。如果错误源自 b.js
,Source Maps 会准确地告诉您这一点。
关于 Source Maps,有许多不同的选项可用。请务必查看它们,以便您可以根据自己的需求进行配置。
对于本指南,让我们使用 inline-source-map
选项,它适用于演示目的(但不适用于生产环境)
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
print: './src/print.js',
},
+ devtool: 'inline-source-map',
plugins: [
new HtmlWebpackPlugin({
title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};
现在,让我们确保我们有可调试的内容,所以在 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
,它应该会编译成类似这样的内容
...
[webpack-cli] Compilation finished
asset index.bundle.js 1.38 MiB [emitted] (name: index)
asset print.bundle.js 6.25 KiB [emitted] (name: print)
asset index.html 272 bytes [emitted]
runtime modules 1.9 KiB 9 modules
cacheable modules 530 KiB
./src/index.js 406 bytes [built] [code generated]
./src/print.js 83 bytes [built] [code generated]
./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
webpack 5.4.0 compiled successfully in 706 ms
现在在浏览器中打开生成的 index.html
文件。点击按钮,在控制台中查看显示的错误。错误应该会显示类似这样的内容
Uncaught ReferenceError: cosnole is not defined
at HTMLButtonElement.printMe (print.js:2)
我们可以看到错误还包含对发生错误的文件(print.js
)和行号(2)的引用。这很棒,因为现在我们确切地知道在哪里查找以解决问题。
每次想要编译代码时手动运行 npm run build
会很快变得很麻烦。
webpack 中有几种不同的选项可以帮助您在代码更改时自动编译代码
在大多数情况下,您可能希望使用 webpack-dev-server
,但让我们探讨所有以上选项。
您可以指示 webpack“观察”您的依赖图中的所有文件以进行更改。如果其中一个文件被更新,代码将被重新编译,这样您就不必手动运行完整的构建。
让我们添加一个 npm 脚本来启动 webpack 的观察模式
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
+ "watch": "webpack --watch",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"html-webpack-plugin": "^4.5.0",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0"
},
"dependencies": {
"lodash": "^4.17.20"
}
}
现在从命令行运行 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
为您提供一个基本的 Web 服务器以及使用实时重新加载的功能。让我们来设置它
npm install --save-dev webpack-dev-server
更改您的配置文件以告诉开发服务器在哪里查找文件
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
print: './src/print.js',
},
devtool: 'inline-source-map',
+ devServer: {
+ static: './dist',
+ },
plugins: [
new HtmlWebpackPlugin({
title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
+ optimization: {
+ runtimeChunk: 'single',
+ },
};
这告诉 webpack-dev-server
从 dist
目录在 localhost:8080
上提供文件。
让我们添加一个脚本,以便轻松运行开发服务器
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
+ "start": "webpack serve --open",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"html-webpack-plugin": "^4.5.0",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"lodash": "^4.17.20"
}
}
现在我们可以从命令行运行 npm start
,我们将看到浏览器自动加载我们的页面。如果您现在更改任何源文件并保存它们,Web 服务器将在代码编译后自动重新加载。试试看吧!
webpack-dev-server
附带许多可配置选项。前往文档了解更多信息。
webpack-dev-middleware
是一个包装器,它将 webpack 处理的文件输出到服务器。它在 webpack-dev-server
内部使用,但作为单独的包提供,如果需要,可以允许更自定义的设置。我们将看一个将 webpack-dev-middleware
与 express 服务器结合使用的示例。
让我们安装 express
和 webpack-dev-middleware
以便开始
npm install --save-dev express webpack-dev-middleware
现在我们需要对 webpack 配置文件进行一些调整,以确保中间件能够正常工作
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
print: './src/print.js',
},
devtool: 'inline-source-map',
devServer: {
static: './dist',
},
plugins: [
new HtmlWebpackPlugin({
title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
+ publicPath: '/',
},
};
publicPath
也将在我们的服务器脚本中使用,以确保文件在 https://:3000
上正确提供。我们稍后将指定端口号。下一步是设置我们的自定义 express
服务器
项目
webpack-demo
|- package.json
|- package-lock.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": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"start": "webpack serve --open",
+ "server": "node server.js",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"express": "^4.17.1",
"html-webpack-plugin": "^4.5.0",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0",
"webpack-dev-middleware": "^4.0.2",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"lodash": "^4.17.20"
}
}
现在在您的终端中运行 npm run server
,它应该会给您类似这样的输出
Example app listening on port 3000!
...
<i> [webpack-dev-middleware] asset index.bundle.js 1.38 MiB [emitted] (name: index)
<i> asset print.bundle.js 6.25 KiB [emitted] (name: print)
<i> asset index.html 274 bytes [emitted]
<i> runtime modules 1.9 KiB 9 modules
<i> cacheable modules 530 KiB
<i> ./src/index.js 406 bytes [built] [code generated]
<i> ./src/print.js 83 bytes [built] [code generated]
<i> ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
<i> webpack 5.4.0 compiled successfully in 709 ms
<i> [webpack-dev-middleware] Compiled successfully.
<i> [webpack-dev-middleware] Compiling...
<i> [webpack-dev-middleware] assets by status 1.38 MiB [cached] 2 assets
<i> cached modules 530 KiB (javascript) 1.9 KiB (runtime) [cached] 12 modules
<i> webpack 5.4.0 compiled successfully in 19 ms
<i> [webpack-dev-middleware] Compiled successfully.
现在启动您的浏览器并访问 https://:3000
。您应该会看到您的 webpack 应用程序正在运行并正常工作!
当使用代码的自动编译时,您在保存文件时可能会遇到问题。一些编辑器具有“安全写入”功能,可能会干扰重新编译。
要在一些常用编辑器中禁用此功能,请参阅以下列表
atomic_save: 'false'
添加到您的用户首选项中。Preferences > Appearance & Behavior > System Settings
中取消勾选“Use safe write”。:set backupcopy=yes
添加到您的设置中。现在您已经学会了如何自动编译代码和运行开发服务器,您可以查看下一个指南,它将涵盖代码分割。