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,瀏覽器就會進行對應的刷新。