webpack_06(dev-server)
搭建本地服务器
目前我们开发的代码,为了运行需要有两个操作:
操作一:npm run build,编译相关的代码;
操作二:通过live server或者直接通过浏览器,打开index.html代码,查看效果;
这个过程经常操作会影响我们的开发效率,我们希望可以做到,当文件发生变化时,可以自动的完成 编译 和 展示;
为了完成自动编译,webpack提供了几种可选的方式:
webpack watch mode;
webpack-dev-server(常用);
webpack-dev-middleware;
Webpack watch
webpack给我们提供了watch模式:
在该模式下,webpack依赖图中的所有文件,只要有一个发生了更新,那么代码将被重新编译;
我们不需要手动去运行 npm run build指令了;
如何开启watch呢?两种方式:
方式一:在导出的配置中,添加 watch: true;
方式二:在启动webpack的命令中,添加 --watch的标识;
webpack-dev-server
#安装 npm install webpack-dev-server -D #package.json 配置dev-server启动命令 "scripts": { "build": "webpack", "dev": "webpack serve" } #webpack.config.js 配置 devServer: { contentBase: './public' //告知dev server,从什么位置查找文件 }
webpack-dev-server 在编译之后不会写入到任何输出文件。而是将 bundle 文件保留在内存中:
事实上webpack-dev-server使用了一个库叫memfs(memory-fs webpack自己写的)
模块热替换(HMR)
什么是HMR呢?
HMR的全称是Hot Module Replacement,翻译为模块热替换;
模块热替换是指在 应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个页面;
HMR通过如下几种方式,来提高开发的速度:
不重新加载整个页面,这样可以保留某些应用程序的状态不丢失;
只更新需要变化的内容,节省开发的时间;
修改了css、js源代码,会立即在浏览器更新,相当于直接在浏览器的devtools中直接修改样式;
如何使用HMR呢?
默认情况下,webpack-dev-server已经支持HMR,我们只需要开启即可;
在不开启HMR的情况下,当我们修改了源代码之后,整个页面会自动刷新,使用的是live reloading;
#webpack开启HMR devServer: { hot: true },
浏览器可以看到
但是你会发现,当我们修改了某一个模块的代码时,依然是刷新的整个页面:
这是因为我们需要去指定哪些模块发生更新时,进行HMR;
框架的HMR
比如vue开发中,我们使用vue-loader,此loader支持vue组件的HMR,提供开箱即用的体验;
比如react开发中,有React Hot Loader,实时调整react组件(目前React官方已经弃用了,改成使用reactrefresh);
HMR的原理
那么HMR的原理是什么呢?如何可以做到只更新一个模块中的内容呢?
webpack-dev-server会创建两个服务:提供静态资源的服务(express)和Socket服务(net.Socket);
express server负责直接提供静态资源的服务(打包后的资源直接被浏览器请求和解析);
HMR Socket Server,是一个socket的长连接:
长连接有一个最好的好处是建立连接后双方可以通信(服务器可以直接发送文件到客户端);
当服务器监听到对应的模块发生变化时,会生成两个文件.json(manifest文件)和.js文件(update chunk);
通过长连接,可以直接将这两个文件主动发送给客户端(浏览器);
浏览器拿到两个新的文件后,通过HMR runtime机制,加载这两个文件,并且针对修改的模块进行更新;
开发中 dev-server webpack配置选项
https://www.webpackjs.com/configuration/dev-server/