开发环境中使用source map
当 webpack 打包源代码时,可能会很难追踪到 error(错误) 和 warning(警告) 在源代码中的原始位置。例如,如果将三个源文件(a.js
, b.js
和 c.js
)打包到一个 bundle(bundle.js
)中,而其中一个源文件包含一个错误,那么堆栈跟踪就会直接指向到 bundle.js
。你可能需要准确地知道错误来自于哪个源文件,所以这种提示这通常不会提供太多帮助。
为了更容易地追踪 error 和 warning,JavaScript 提供了 source maps 功能,可以将编译后的代码映射回原始源代码。如果一个错误来自于 b.js
,source map 就会明确的告诉你。
source map 有许多 可用选项,请务必仔细阅读它们,以便可以根据需要进行配置。
对于本指南,我们将使用 inline-source-map
选项,这有助于解释说明示例意图(此配置仅用于示例,不要用于生产环境):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| const path=require('path') const HtmlWebpackPlugin=require("html-webpack-plugin") module.exports={ entry:{ index: './src/index.js', print:'./src/print.js'
}, output:{ filename:'[name]bundle.js', path:path.resolve(__dirname,'dist'), clean:true, publicPath:'/', }, module:{ rules:[ { test: /\.css$/i, use:['style-loader','css-loader'], }, { test:/\.(png|jpg|jpeg|svg|gif)$/i, type:'asset/resource'
}, ] }, devtool:'inline-source-map', devServer:{ static:'./dist', }, plugins:[ new HtmlWebpackPlugin({ title:'Development', })
], mode:'development'
}
|
选择开发工具
webpack 提供几种可选方式,帮助你在代码发生变化后自动编译代码:
- webpack’s Watch Mode
- webpack-dev-server
- webpack-dev-middleware
多数场景中,你可能需要使用 webpack-dev-server
,但是不妨探讨一下以上的所有选项。
使用watch mode
你可以指示 webpack “watch” 依赖图中所有文件的更改。如果其中一个文件被更新,代码将被重新编译,所以你不必再去手动运行整个构建。
我们添加一个用于启动 webpack watch mode 的 npm scripts:
package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| { "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-dev-server
实现此功能。
webpack-dev-server
webpack-dev-server
为你提供了一个基本的 web server,并且具有 live reloading(实时重新加载) 功能。设置如下:
1
| npm install --save-dev webpack-dev-server
|
修改配置文件,告知 dev server,从什么位置查找文件:
webpack.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 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, }, };
|
以上配置告知 webpack-dev-server
,将 dist
目录下的文件 serve 到 localhost:8080
下。(译注:serve,将资源作为 server 的可访问文件)
我们添加一个可以直接运行 dev server 的 script:
package.json
1 2 3 4 5 6
| "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "watch": "webpack --watch", + "start": "webpack serve --open", "build": "webpack" },
|
现在,在命令行中运行 npm start
,我们会看到浏览器自动加载页面。如果你更改任何源文件并保存它们,web server 将在编译代码后自动重新加载
webpack-dev-middleware
webpack-dev-middleware
是一个封装器(wrapper),它可以把 webpack 处理过的文件发送到一个 server。webpack-dev-server
在内部使用了它,然而它也可以作为一个单独的 package 来使用,以便根据需求进行更多自定义设置。下面是一个 webpack-dev-middleware 配合 express server 的示例。
首先,安装 express
和 webpack-dev-middleware
:
1
| npm install --save-dev express webpack-dev-middleware
|
调整webpack.config,js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 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: '/', }, };
|
我们将会在 server 脚本使用 publicPath
,以确保文件资源能够正确地 serve 在 http://localhost:3000
下,稍后我们会指定 port number(端口号)。接下来是设置自定义 express
server:
1 2 3 4 5 6 7 8 9 10
| webpack-demo |- package.json |- package-lock.json |- webpack.config.js + |- server.js |- /dist |- /src |- index.js |- print.js |- /node_modules
|
server.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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);
app.use( webpackDevMiddleware(compiler, { publicPath: config.output.publicPath, }) );
app.listen(3000, function () { console.log('Example app listening on port 3000!\n'); });
|
现在,添加一个 npm script,以使我们更方便地运行 server:
package.json
1 2 3 4 5 6 7
| "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "watch": "webpack --watch", "start": "webpack serve --open", + "server": "node server.js", "build": "webpack" },
|
现在,在 terminal(终端) 中执行 npm run server