dev-server
dev-server为本地开发提供 server层,你可以简单的理解为,webpack根据配置将打包的文件通过express静态服务挂载出去了,但是它本身作为一个node服务可以做很多配置,比如基本的中间件(做一些拦截)。
dev-server的server配置
-
static 作为express后端服务向外暴露的公共资源路径
-
port 启动服务的端口
-
compress:boolean,打包的文件是否进行gz压缩
-
open: boolean,是否自动打开浏览器
-
headers 添加请求html返回的响应头部信息
-
proxy 设置代理
const proxy = { '/API': { target: '......', // 代理的目标路径 pathRewrite: { '^/api': '', // 把匹配到的部分替换成空字符 } } } -
https: 是否开启https服务(但是是本地的证书,所以给警告)
-
http2:是否开启http2
-
historyAPIFallBack:是否为history路由做对应的配置(重定向)
-
hot HMR(热模块替换)
-
liveReload 热更新(重新刷新浏览器)
-
watchFiles 配置可以被监听的文件
HMR 和 LR
介绍:
- 模块热替换:某个模块发生替换的时候单独重新打包替换该模块,而不是整个重新打包
- 热更新:当检测到代码更新的时候重新刷新浏览器
const devServer = {
hot: true, // boolean | 'only'(在HMR失败的时候拒绝使用liveReload)
liveReload: true, // boolean
}
原理:
webpack 会监听所有打包的资源组成的资源图中的文件,如果对应的文件做出修改,webpack会通知 webpack-dev-server,到底改进行 HMR 还是 liveReload。但是需要注意的是,虽然 webpack-dev-server的 hot 和 liveReload 配置默认是true,但是hot只是开启,至于那些文件需要热替换,需要在使用的地方(import)进行 module.hot.accept,才能开启改文件的热更新,否则即使是hot为true,更新了模块文件也只是 liveReload
比如为某个js文件开启HMR:
import myModule from 'xxx.js';
// 注意,使用 myModule不能在入口文件理解调用,而是需要延时调用才能进行热更,不然无法拆解模块 无法热更
if(module.hot) {
module.hot.accept('xxx.js', (...args) => {
console.log(args,'成功hmr的文件路径')
// HMR该模块成功 的回调
})
}
值得高兴的是,一些loader能够自动的添加 module.hot.accept,比如css-loader:css-loader默认的为所以的css启用了 HMR,因此当我们更新css的时候是不会重刷浏览器的,而是只替换了样式
总结
webpack的HMR有点奇怪,即使accept也不一定热替换,而是热更新
留个坑,确实不太懂