1. webpack中的文件监听
文件监听是在发现源码发生变化时,自动重新构建出新的输出文件。
webpack 开启监听模式,有两种方法:
- 启动 webpack 命令时,带上--watch 参数
- 在配置 webpack.config.js 中设置 watch:true
{
"name": "hello-webpack",
"version": "1.0.0",
"description" "Hello webpack",
"main": "index.js",
"scripts": {
"build": "webpack",
"watch": "webpack --watch"
},
"keywords": [],
"author": "",
"license": "ISC"
}
唯一缺陷:每次需要手动刷新浏览器
文件监听的原理:
轮询判断文件的最后编辑时间是否在变化
某个文件发生了变化,并不会立即告诉监听者,而是先缓存起来,等 aggregateTimeout
module.exports = {
// 默认为 false, 也就是不开启
watch: true,
// 只有开启监听模式的时候,watchOptions 才有意义
watchOptions: {
// 默认为空,不监听的文件或文件夹,支持正则匹配
ignored: /node_modules/,
// 监听到变化后会等 300ms 再去执行,默认 300ms
aggregateTimeout: 300,
// 判断文件是否发生变化是通过不停询问系统指定文件有没有变化实现的,默认每秒问 1000 次
poll: 1000
}
}
2. webpack 热更新及原理解析
webpack-dev-server (修改文件后不用手动刷新)
WDS 不刷新浏览器
WDS 不输出文件,而是放在内存中
使用 HotModuleReplacementPlugin 插件
{
"name": "hello-webpack",
"version": "1.0.0",
"description": "Hello webpack",
"main": "index.js",
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server --open"
// --open 每次构建完以后默认打开浏览器
},
"keywords": [],
"author": "",
"license": "ISC"
}
webpack.HotModuleReplacementPlugin是内置在 webpack 里面的,直接调用就好了
// 首先引入 webpack
const webpack = require("webpack");
// 加入热更新插件
plugins: [
// 热更新插件为 webpack 内置的
new webpack.HotModuleReplacementPlugin(),
],
devServer: {
// 设定 devServer 默认服务目录 dist
contentBase: "/dist",
// 开启热更新
hot: true,
},
3. webpack 热更新中间件
wenpack-dev-middleware
WDM 将 webpack 输出的文件传输给服务器
用于灵活的定制场景
这个等遇到的时候要去翻官方文档才行
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");
})
4. 热更新的原理分析
Webpack Compiler:将 JS 编译成 Bundle
HMR Server:将热更新的文件输出给 HMR Runtime
Bundle Server:提供文件在浏览器的访问
比如说编译好的 bundle.js,其实在浏览器里面正常访问是以文件目录的形式来访问的,然后使用 BundleServer 可以让我们以类似于服务器的方式来访问,比如说 localhost:8080
HMR Runtime:会被注入到浏览器,更新文件的变化
开发阶段,打包阶段,会注入到浏览器中的 bundle.js里面,这样的话浏览器端的 bundle.js 会和服务器建立一个链接,通常会是 websocket。这样就能动态更新了。
bundle.js:构建输出的文件
热更新阶段有两个:
- 初始阶段就是文件经过 wepack compiler 进行打包,打包好了后把编译好的文件传输给 bundleServer, bundleServer 就可以 run 这个文件
- 文件经过文件系统发生了变化,然后还是 webpack compiler 进行编译,编译好了会将代码发送给 HMR Server,它就可以知道哪些资源、哪些模块发生了改变。然后 HMR server 会通知 HRM Runtime,浏览器就会进行对应的刷新。