前言
webpack-dev-server配置热更新看起来很简单,但是实际上是有很多坑的,目前为止我没有搜到一篇深入讲解这个的,如果你觉得它很简单,那么或许等你看完这篇文章你会有不一样的看法。
由于HMR非常强大,本来这篇文章我是准备总结webpack-dev-server
的,最后基本只总结了它的两个参数:inline
和hot
,其它的配置我会另外再写一篇文章讲解。
模块热替换(Hot Module Replacement)
HMR是webpack最令人兴奋的特性之一,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换老的模块,这样在不刷新浏览器的前提下就能够对应用进行更新。HMR是一个非常值得去深入研究的东西,它绝不是目前我们看到的大多数技术文章说的配置一个hot
参数这么简单,有兴趣的小伙伴可以去看看它的实现原理,目前为止我也只看过一点点。
其实实现HMR的插件有很多,webpack-dev-server
只是其中的一个,当然也是优秀的一个,它能很好的与webpack配合。另外,webpack-dev-server
只是用于开发环境的。
webpack-dev-server实现自动刷新
全局安装:npm install webpack-dev-server --g
(全局安装以后才可以直接在命令行使用webpack-dev-server)
本地安装:npm install webpack-dev-server --save-dev
在webpack的配置文件里添加webpack-dev-server
的配置:
module.exports = {
devServer: {
contentBase: path.resolve(__dirname, 'build'),
},
}
webpack-dev-server
为了加快打包进程是将打包后的文件放到内存中的,所以我们在项目中是看不到它打包以后生成的文件/文件夹的,但是,这不代表我们就不用配置路径了,配置过webpack.config.js
的小伙伴都知道output.path
这个参数是配置打包文件的保存路径的,contentBase
就和output.path
是一样的作用,如果不配置这个参数就会打包到项目的根路径下。有关这几个配置路径的参数我会再写一篇文章总结,这里就不展开了。
当然你也可以选择在命令行中启动的时候加这个参数:
webpack-dev-server --content-base build/
webpack-dev-server
支持两种自动刷新方式:
- Iframe mode
- Inline mode
使用iframe模式不需要配置任何东西,只需要在你启动的项目的端口号后面加上/webpack-dev-server/
即可,比如:
http://localhost:8080/webpack-dev-server/
打开调试器可以看到webpack-dev-server
在页面中嵌入了一个
inline模式实在是个磨人的小妖精,官方文档有关Inline mode的使用说明比较少,而且还极容易误导人,再加上网上很多自己都没搞清楚webpack-dev-server
的博主的文章,就更容易让人懵逼了。
误导一:inline模式的HTML方式和Node.js方式都需要配置参数inline
才能生效。
文档把HTML方式和Node.js方式都称为inline模式,以至于很多人都误解了这两种用法,但是文档里有这么一句话:
Inline mode with Node.js API
There is no inline: true flag in the webpack-dev-server configuration, because the webpack-dev-server module has no access to the webpack configuration.
意思是使用Node.js方式是没有inline这个参数的,这里的inline模式其实就是三种配置方式,三选一就行。
- 在webpack.config.js里面配置
module.exports = {
...
devServer: {
inline: true,
},
}
- 在HTML里面添加
- 在node.js的配置文件里面配置(以下摘自官网,后面我会详解这个配置)
var config = require("./webpack.config.js");
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");
var compiler = webpack(config);
var server = new WebpackDevServer(compiler, {...});
server.listen(8080);
误导二:需要在entry属性里添加webpack-dev-server/client?http://«path»:«port»/
这个误解应该来自于别的博客,我搜了很多文章都在entry里加了这句话,如果是开启热更新还会加webpack/hot/dev-server
。这一点官网解释的非常清楚,由于采用Node.js配置,webpack-dev-server模块无法读取webpack的配置,所以用户必须手动去webpack.config.js的entry指定webpack-dev-server客户端入口。意思是只有采用Node.js方式才会需要添加这句话,而且,我们并不需要去污染webpack.config.js文件,而是将这句代码写在Node.js 的配置文件里:
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");
config.entry
就是webpack.config.js
的entry, entry是一个数组,这里要注意一下你自己的entry配置,如果是
entry: [
path.resolve(__dirname, './src/index.js')
],
那你应该写成:
config.entry.unshift("webpack-dev-server/client?http://localhost:8080/");
还懵逼吗?那我再多说两句
以上这些乱七八糟的配置估计把你都看晕了吧,我再梳理一下有关inline模式的东西,HTML方式最简单,在index.html
页面里添加一个