在日常开发中,我们可能需要以下几个功能:
webpack-dev-middleware
假设我们在服务端使用 express 开发一个站点,同时也想利用 webpack 对静态资源进行打包编译,那么在开发环节,每次修改完文件后,都得先执行一遍 webpack 的编译命令,等待新的文件打包到本地,再做进一步调试。虽然咱们可以利用 webpack 的 watch mode 来监听变更、自动打包,但等待 webpack 重新执行的过程往往很耗时。webpack-dev-middleware 的出现很好地解决了上述问题,它会开启 watch mode 监听文件变更,并自动地在内存中快速地重新打包、提供新的 bundle。
说白了就是 —— 自动编译(watch mode)+速度快(全部走内存)
webpack-hot-middleware
webpack-hot-middleware可以让页面也能自动更新呢,提供的这种能力称为 HMR(即模块热替换(hot module replacement)的简称,它可以在应用运行的时候,不需要刷新页面,就可以直接替换、增删模块。)。
webpack 可以通过配置 webpack.HotModuleReplacementPlugin 插件来开启全局的 HMR 能力,开启后 bundle 文件会变大一些,因为它加入了一个小型的 HMR 运行时(runtime),当你的应用在运行的时候,webpack 监听到文件变更并重新打包模块时,HMR 会判断这些模块是否接受 update,若允许,则发信号通知应用进行热替换。
webpack-dev-server 相对前两个工具多了个“server”,实际上它的确也是在 webpack-dev-middleware 的基础上多套了一层壳来提供 CLI 及 server 能力(这也是为何我称 webpack-dev-middleware 是 webpack-dev-server 他爹)。
“devServer”的 webpack-dev-server 配置项:
const path = require('path');
module.exports = {
entry: './app.js',
output: {
publicPath: "/assets/",
filename: 'bundle.js'
},
devServer: { //新增配置项
contentBase: path.join(__dirname, "src/html"),
port: 3333
}
};
中 devServer.port 表示 SERVER 的监听端口,即运行后我们可以通过 http://localhost:3333 来访问应用;
而 devServer.contentBase 表示 SERVER 将从哪个目录去查找内容文件(即页面文件,比如 HTML)。
确保安装好 webpack-dev-server 后执行其 CLI 命令来召唤支持热更新的 SERVER:webpack-dev-server
要让 webpack-dev-server 加上 HMR 的翅膀,其实就得像前面 webpack-hot-middleware 的配置那样,把 HMR 相关的东西通通加上,同时将 devServer.hot 设为 true:
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './app.js',
output: {
publicPath: "/assets/",
filename: 'bundle.js'
},
devServer: {
contentBase: path.join(__dirname, "src/html"),
port: 3333,
hot: true // 让 dev-server 开启 HMR
},
plugins: [
new webpack.HotModuleReplacementPlugin() //让 webpack 启动全局 HMR
]
};
常用的介绍:
即 SERVERROOT,如上方示例配置为 “path.join(__dirname, “src/html”)”,后续访问 http://localhost:3333/index.html 时,SERVER 会从 src/html 下去查找 index.html 文件。
contentBase: path.join(__dirname, "public")
//多个:
contentBase: [path.join(__dirname, "public"), path.join(__dirname, "assets")]
若不填写该项,默认为项目根目录。
监听的端口
传入一个 boolean 值,通知 SERVER 是否启用 gzip。
传入一个 boolean 值,通知 SERVER 是否启用 HMR。
可以传入 true 来支持 https 访问,也支持传入自定义的证书:
https: true
//也可以传入一个对象,来支持自定义证书
https: {
key: fs.readFileSync("/path/to/server.key"),
cert: fs.readFileSync("/path/to/server.crt"),
ca: fs.readFileSync("/path/to/ca.pem"),
}
代理配置,适用场景是,除了 webpack-dev-server 的 SERVER(SERVER A) 之外,还有另一个在运行的 SERVER(SERVER B),而我们希望能通过 SERVER A 的相对路径来访问到 SERVER B 上的东西。
devServer: {
contentBase: path.join(__dirname, "src/html"),
port: 3333,
hot: true,
proxy: {
"/api": "http://localhost:5050"
}
}
运行 webpack-dev-server 后,你若访问 http://localhost:3333/api/user,则相当于访问 http://localhost:5050/api/user。
如同 webpack-dev-middleware 的 publicPath 一样,表示从内存中的哪个路径去存放和检索静态文件。
webpack-dev-server 的服务应用层使用了 express,故可以通过 express app 的能力来模拟数据回包,devServer.setup 方法就是干这事的:
devServer: {
contentBase: path.join(__dirname, "src/html"),
port: 3333,
hot: true,
setup(app){ //模拟数据
app.get('/getJSON', function(req, res) {
res.json({ name: 'vajoy' });
});
}
}
devServer.headers配置项可以在HTTP响应中注入一些HTTP响应头,使用如下:
devServer: {
headers: {
'X-foo': 'bar'
}
}
devServer.host配置项用于配置DevServer服务器监听的地址。如果你想要局域网中其他设备访问你本地的服务,可以在启动的时候带上–host 0.0.0.0.host的默认值是127.0.0.1即只有本地可以访问DevServer的HTTP服务。
devServer.allowedHosts配置一个白名单列表,只有HTTP请求的HOST在列表里才正常返回,使用如下:
allowedHosts: [
//匹配单个域名
'host.com',
'sub.host.com',
/ host2.com 和所有的子域名 *.host2.com 都将匹配
'.host.com'
]
devServer.disableHostCheck配置项用于配置是否关闭用于DNS重绑定的HTTP请求的host检查。DevServer 默认只接受来自本地的请求,关闭后可以接受来自任何 HOST 的请求。 它通常用于搭配 --host 0.0.0.0 使用,因为你想要其它设备访问你本地的服务,但访问时是直接通过 IP 地址访问而不是 HOST 访问,所以需要关闭 HOST 检查。