webpack-dev-server 原理探討
我們都知道webpack是一個構建工具,但是在開發測試過程中,我們會經常修改程式碼後,然後頻繁重新整理頁面檢視效果,可惜我們就是厭舊重複工作的物種。
剛好webpack這個工具,提供了另外一個工具——webpack-dev-server,它可以幫我們從中解脫。
初試——監聽入口的JS檔案
我們可以監聽入口檔案和其它被它引用(匯入)的檔案,並在檔案更新的時候,通知瀏覽器重新整理網頁。
使用webpack-dev-server的方式很簡單:
npm install --save-dev webpack-dev-server
devServer: { contentBase: './dist', } 複製程式碼
-
然後使用指令
webpack-dev-server --open
就可以了。也可以把這個指令放在package.js檔案裡的scripts欄位裡。
基本原理
其實就是藉助Express開啟一個伺服器,然後設定兩個路由出口:
-
靜態資源出口:可以通過devServer的欄位
contentBase
設定靜態資源目錄 -
webpack output的出口:預設是
/
,可以通過devServer的欄位publicPath
設定
所以,我可以看出,webpack output其實就是Express的一個router物件,webpack根據入口檔案觀察相關的檔案,並在它們發生變化的時候,重新編譯打包,並輸出到router物件上,這樣我們就可以訪問該router拿到最新的資源,不過這個資源是放在記憶體上的,並不是檔案系統上。
網頁和webpack-dev-server是通過websocket協議互聯的。當監聽到檔案變化的時候,會通過websocket通知網頁呼叫reload介面重新整理頁面。
晉級——監聽靜態HTML檔案
監聽靜態檔案的變化並更新。
步驟:
npm i -D html-webpack-plugin npm i -D raw-loader
module.exports = { mode: 'development', entry: './index.js', // ... plugins: [ new HtmlWebpackPlugin({ template: "./dist/index.html" // 指定HTML模板的路徑 }) ], module: { rules: [ { test: /\.html$/, use: 'raw-loader' } ] } } 複製程式碼
require('./dist/index.html') webpack-dev-server
目前為止,監聽檔案變更後,都是通過通知瀏覽器重新整理的方式重新訪問伺服器獲取新的資源。
缺陷:
每個靜態的HTML檔案都需要在配置檔案裡配置一個HtmlWebpackPlugin
。
使用gulp監聽靜態檔案
假如我們只想簡單監聽靜態檔案變更,然後讓瀏覽器重新整理的話,使用gulp也是不錯的選擇。
npm i -D gulp browser-sync run-sequence
var gulp = require('gulp'), browserSync = require('browser-sync'), runSequence = require('run-sequence'); gulp.task('browserSync', function () { browserSync.init({ server: { baseDir: './dist' // 指定伺服器的根目錄,預設為專案的根目錄 } }) }); gulp.task('watch', ['browserSync'], function () { gulp.watch('./static/**/*.css', browserSync.reload); // 指定監聽css檔案 gulp.watch('./static/**/*.js', browserSync.reload); // 指定監聽js檔案 gulp.watch('./dist/*.html', browserSync.reload); // 指定監聽html檔案 }); gulp.task('default', function (callback) { runSequence(['browserSync', 'watch'], callback); }); 複製程式碼
高階——模組熱替換
熱替換功能其實也沒有那麼神奇。
用一句話描述就是,通過webpack提供的API監聽一個檔案,並替換已經存在的模組——這需要開發者自己提供替換的邏輯。
步驟:
-
開啟熱替換功能:
devServer: true
-
註冊兩個外掛:
new webpack.NamedModulesPlugin()
和new webpack.HotModuleReplacementPlugin()
- 在需要監聽的檔案裡,用邏輯設定需要熱替換的條件,並提供熱替換的邏輯。
代理功能
如果你有單獨的後端開發伺服器 API,並且希望在同域名下發送 API 請求 ,那麼代理某些 URL 會很有用。
比如在配置檔案裡設定:
proxy: { "/api": "http://localhost:3000" } 複製程式碼
請求到 /api/users 現在會被代理到請求http://localhost:3000/api/users
。
對於多個代理介面:
proxy: [{ context: ["/auth", "/api"], target: "http://localhost:3000", }] 複製程式碼
常用配置
devServer.compress,啟用gzip壓縮。 devServer.contentBase,告訴伺服器從哪裡提供內容。只有在你想要提供靜態檔案時才需要。 devServer.host,指定host。使用0.0.0.0可以讓區域網內可訪問。 devServer.hot,啟用 webpack 的模組熱替換特性(Hot Module Replacement)。 devServer.hotOnly,構建失敗的時候是否不允許回退到使用重新整理網頁。 devServer.inline,模式切換。預設為內聯模式,使用false切換到iframe模式。 devServer.open,啟動webpack-dev-server後是否使用瀏覽器開啟首頁。 devServer.overlay,是否允許使用全屏覆蓋的方式顯示編譯錯誤。預設不允許 devServer.port,監聽埠號。預設8080。 devServer.proxy,代理,對於另外有單獨的後端開發伺服器API來說比較適合。 devServer.publicPath,設定記憶體中的打包檔案的輸出目錄。區別於output.publicPath。 複製程式碼
參考
ofollow,noindex">webpack-dev-server使用方法,看完還不會的來找我~ 開發中 Server(devServer) Extra - Make your HTML hot reload gulp+browser-sync 監聽檔案實現瀏覽器自動重新整理