当webpack
打包源代码后,可能很难追踪错误和警告。例如三个源文件a.js
,b.js
和c.js
打包到一个bundle(bundle.js)
中,而其中一个源文件包含错误,那么错误只会简单指向到bundle.js
。这对于分析原因没有太大帮助。
以上节的src/print.js
文件为例,如果将代码改成下面内容,则从consle
中只能看到错误出自app.bundle.js:1
export default function printMe() {
// console.log('I get called from print.js')
console.error('I get called from print.js')
}
使用source map
为了更容易追踪错误和警告,JavaScript
提供了source map
功能,将编译后的代码映射回原始代码。具体使用如下,在webpack.config.js
文件张添加devtool: "inline-source-map"
。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
devtool: "inline-source-map",
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: "output management"
})
],
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, 'dist')
}
};
然后重新构建npm run build
,完成后用浏览器打开index.html
文件。在控制台可以看到错误出自print.js
的第三行。
自动编译
每次要编译代码时,手动运行npm run build
比较麻烦。webpack
提供几个选项来当代码发生变化时自动编译代码。
watch mode
观察模式依赖图中的所有文件来进行更改,如果其中一个文件被更新,代码将被重新编译,所以不必手动运行整个构建。
在package.json
文件中添加script
脚本,"watch: "webpack --watch"
。
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"build": "webpack"
},
"dependencies": {
"lodash": "^4.17.14"
},
"devDependencies": {
"clean-webpack-plugin": "^3.0.0",
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.35.3",
"webpack-cli": "^3.3.6"
}
}
然后在命令行中运行npm run watch
,就会看到webpack
编译代码,然而却不会退出命令行。接着用浏览器打开index.html
文件,查看控制台显示。
然后修改src/print.js
文件,内容如下:
export default function printMe() {
console.log('I get called from print.js')
// console.error('I get called from print.js')
}
修改后,你可以在命令行看到webpack
自动重新编译修改后的模块。但为了看到实际效果,需要手动刷新浏览器。而且不是很及时,可能几秒之后才看到构建。
webpack-dev-server
webpack-dev-server
提供了一个简单的web
服务器,能够实时重新加载。设置如下:
npm install --save-dev webpack-dev-server
修改配置文件,告诉dev server
在哪里查找文件。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
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')
}
};
以上配置告知webpack-dev-server
,在localhost:8080
上建立服务。将dist目录下的文件作为可访问的文件。
在package.json
中添加一个script
脚本,可以直接运行dev server
。内容如下:
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"start": "webpack-dev-server --open",
"build": "webpack"
},
"dependencies": {
"lodash": "^4.17.14"
},
"devDependencies": {
"clean-webpack-plugin": "^3.0.0",
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.35.3",
"webpack-cli": "^3.3.6",
"webpack-dev-server": "^3.7.2"
}
}
然后在命令行中运行npm start
,就可以在浏览器中自动加载页面。并且如果源文件有修改和保存,web服务器就会自动重新加载编译后的代码。
webpack-dev-middleware
webpack-dev-middleware
是一个容器,可以把webpack
处理后的文件传递给一个服务器。webpack-dev-server
在内部使用了它,同时,它也可以作为一个单独的包来使用,以便进行更多自定义设置来实现更多的需求。
首先需要安装express
和webpack-dev-middleware
。
npm install --save-dev express webpack-dev-middleware
修改webpack
的配置文件,确保中间件middleware
能正常启用。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
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: "/"
}
};
接着设置自定义的express
服务,webpack-demo
项目中添加文件server.js
,目录结构如下:
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);
app.use(webpackDevMiddleware(compiler,{
publicPath:config.output.publicPath
}));
app.listen(3000,function () {
console.log('example app listening on port 3000!\n');
});
上面的服务建立在localhost:3000
端口上,接着需要添加一个npm script
,来使我们方便的运行服务。
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"start": "webpack-dev-server --open",
"server": "node server.js",
"build": "webpack"
},
"dependencies": {
"lodash": "^4.17.14"
},
"devDependencies": {
"clean-webpack-plugin": "^3.0.0",
"express": "^4.17.1",
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.35.3",
"webpack-cli": "^3.3.6",
"webpack-dev-middleware": "^3.7.0",
"webpack-dev-server": "^3.7.2"
}
}
然后运行npm run server
,就可以在浏览器看自动构建。webpack-dev-middleware
虽然能自动构建,但还是像观察模式一样,需要手动刷新浏览器才能看到重新构建后的结果。