如果此篇對您有所幫助,在此求一個star。專案地址: OrcasTeam/my-cli
webpack-dev-server使用
什麼是webpack-dev-server
使用vue-cli 、react-cli腳手架時,執行yarn start
命令會啟動一個本地伺服器,瀏覽器訪問伺服器就可以預覽程式碼,並且程式碼檔案更新後頁面會重新載入資料,非常方便,這個功能就叫做dev-server。
在webpack中,由webpack-dev-server提供。
webpack-dev-server 庫作用開啟一個伺服器。瀏覽器訪問伺服器時,與瀏覽器使用WebSocket進行長連結。
並且webpack-dev-server 會開啟webpack監聽原生程式碼檔案功能。當原生程式碼檔案更新後,進行重新打包編譯,webpack-dev-server 通過WebSocket將更新模組資訊推送給瀏覽器。瀏覽器根據此次編譯資訊,去獲取最新程式碼,一個大致這樣的操作。
? webpack本身就支援監聽檔案變化,webpack-dev-server只是預設開啟webpack的監聽屬性。
webpack-dev-server庫並不複雜,不過裡面涉及到的東西有些多。
關於webpack-dev-server庫,想深入的介紹下。
在此分為兩篇來介紹:
- 介紹webpack-dev-server屬性配置,並且介紹部分屬性原始碼中的設定
- 稍微介紹webpack-dev-server流程和原理。
webpack-dev-server 安裝
webpack-cli/bin/config-yargs 的問題
截至到寫此篇時,webpack-dev-server的最新版本是3.11.2
有使用過此版本的朋友會知道,webpack-dev-server@3.11.2與webpack@5.X共同使用時會具有一個錯誤:Cannot find module 'webpack-cli/bin/config-yargs
這個問題個人感覺是官方有些坑了。
先來安裝webpack-dev-server@3.11.2,看看這個錯誤。
yarn add -D webpack-dev-server@3.11.2
使用過webpack-dev-server的朋友都會知道,執行webpack-dev-server的命令為:webpack-dev-server
官方NPM文件中也是webpack-dev-server
命令
一般都會將yarn start
命令設定為:webpack-dev-server
,
? 在這裡將
yarn start:dev
命令設定為:webpack-dev-server
。主要是為了這個錯誤
此時,如果不出意外的話, 執行yarn start:dev
就可以執行webpack-dev-server。
但是,執行就會碰到那個錯誤:
錯誤提示是找不到webpack-cli庫中的config.yargs模組。感覺會有不少剛學習webpack並且搜尋能力稍微弱一些的朋友會卡在這。
? 配置使用的webpack-cli@4.5.0和webpack@5.24.0
這個錯誤其實很簡單,直接在issues就可以找到答案。
原來是使用了新的執行命令了:webpack serve
。現在將新命令進行配置
此時使用yarn start
執行就可以成功執行。預設啟動的是8080埠
那麼這到底怎麼回事呢?通過檢視原始碼和測試webpack-dev-server@4.0.0beta.0個人略有些猜測。
先看一下webpack-dev-server@3.11.2中 /bin/webpack-dev-server.js 檔案模組中一段程式碼。
/bin/webpack-dev-server.js會是使用webpack-dev-server
命令執行的檔案模組
在 /bin/webpack-dev-server.js 檔案模組中載入了webpack-cli庫中的 /bin/ [config/] config-yargs 和 /bin/ [utils/] convert-argv 。
但是在版本 程式碼結構進行了巨大的改變,已經去掉了這兩個檔案模組,所以也就導致了報錯。
這個問題就是目前處於迭代期的原因。
在之前使用webpack@4.X版本時,使用的webpack-cli@3.X和webpack-dev-server@3.X
現在更新到了webpack@5.X,webpack-cli也進行了大版本的更新:webpack-cli@4.X。並且內部結構發生了巨大的變化。
但是webpack-dev-server的新版本還沒有開發完成,並且webpack-dev-server@3.X程式碼沒有修復這個問題。
webpack-cli@4.X中加入了webpack serve
這個新命令。webpack serve
也是以後webpack推薦的命令。
webpack-dev-server
這個,命令問題在webpack-dev-server@4.X中修復了。不過目前webpack-dev-server@4.X只有一個webpack-dev-server@4.0.0beta.0。
還沒有穩定版本
在webpack-dev-server@4.0.0beta.0的程式碼可以看到 /bin/webpack-dev-server.js 檔案模組中沒有了上面兩段程式碼。
在webpack-dev-server@4.0.0beta.0文件中的命令改為了webpack serve
。不過webpack-dev-server
依然可以使用。
??? webpack-cli@4.X版本開始,webpack團隊將dev-server的命令改為了
webpack serve
。webpack與webpack-cli都進行了大版本的更新。webpack-dev-server目前新版本還沒有開發完成。所以暫時就出了這麼一個問題
webpack serve
命令在 webpack-cli@4.0.0版本文件中可以找到。
webpack serve
關於webpack serve
命令的執行,執行入口檔案與webpack
命令一樣,都是 webpack 庫的 /bin/index.js 。在此檔案模組中呼叫了webpack-cli庫模組。
然後在webpack-cli庫根據其命令引數呼叫@webpack-cli庫中的 /serve/lib/index.js ,在此模組檔案中啟動 webpack-dev-server伺服器。這些程式碼都是webpack-cli@4.X版本新增加的。詳細內容在下一篇介紹。
?? webpack、webpack-cli、webpack-dev-server跨庫呼叫都是根據模組路徑呼叫。所以只要某個庫檔案結構稍微改動,就會像
webpack-dev-server
命令這樣直接報錯。 不過在新版本程式碼進行了優化,通過約定名稱進行跨庫呼叫。儘可能降低了耦合度。
? @webpack-cli是webpack-cli@4.X依賴的一個庫。
webpack-dev-server@3.X 和webpack@5.X WebSocket問題
執行yarn start
後,會開啟一個8080埠的伺服器。
但是webpack@5.X和webpack-dev-server@3.X一起使用時WebSocket還有問題
上面簡單說過WebSocket是與瀏覽器建立長連結,通過WebSocket向瀏覽器推送資訊進行改變瀏覽器狀態。
下面來做一個測試,執行yarn start
後,使用瀏覽器訪問。
此時如果將程式碼更新,會發現瀏覽器並沒有同步更新,並且瀏覽器WS視窗沒有推送資料
? WS“:WebSocket資料顯示視窗
後來我對原始碼進行了除錯,發現根本就沒有連線WebSocket Server。
最後在github中找到了答案。
原因是package.json檔案中的browserslist屬性,將此屬性去掉就可以進行推送。
這是webpack-dev-server@3.X的一個問題。但是按照官方給出的解釋好像只會在webpack-dev-server@4.X中修復這個問題。
我也使用webpack-dev-server@4.0.0beta.0版本進行了測試,這個bug被修復了。
版本選擇
目前webpack@5.X穩定版才4個月,並且webpack-dev-server還沒有對應新版本的穩定版。所以webpack@5.X還只能供學習使用。
在此直接使用webpack@5.24.0+webpack-cli@4.5.0+webpack-dev-server@4.0.0beta.0版進行學習。
webpack-dev-server@4.0.0beta.0 屬性配置相對webpack-dev-server@3.X稍微有些變動,在此也會稍微提一提webpack-dev-server@4.0.0beta.0與webpack-dev-server@3.X屬性對應關係和差異性。
yarn add -D webpack-dev-server@4.0.0beta.0
?? webpack-dev-server@4.0.0beta.0 提供了比較完善的錯誤提示,當設定了錯誤屬性時,webpack-dev-server@4.0.0beta.0能夠給出詳細提示資訊。
webpack-dev-server配置
webpack-dev-server屬性是配置在webpack配置檔案中的devServer屬性。webpack-dev-server執行時會讀取這個屬性來做配置。
由於webpack-dev-server只是開發時使用的一個功能,所以配置屬性寫在webpack.dev.js檔案中就可以
const path = require('path');
const { merge } = require('webpack-merge');
const { config } = require('./config');
const common = require('./webpack.common');
// 使用node.js的匯出,將配置進行匯出
module.exports = merge([
common(true),
{
mode: 'development',
devServer:{
// 伺服器host,預設為localhost,
host: '127.0.0.1',
// 伺服器埠號,
// 預設為8080
port: 7777,
// string | boolean
// 啟動後是否開啟瀏覽器
// 預設為false,如果設定為true, 啟動時會自動開啟瀏覽器
// 當為字串時,開啟指定瀏覽器
open: true, // 'chrome'
// 開啟瀏覽器後預設開啟的頁面
// string | Array<string>
// 當設定為Array時,會開啟多個頁面
openPage: '', // ['', 'index.html'], //'index.html',
// 是否啟用gzip壓縮,
// 預設為false
compress: true,
// 是否啟動熱更新(HMR)
// 預設為false,
// 熱更新使用的是webpack中HotModuleReplacementPlugin
hot: true,
// 設定允許訪問的IP地址,設定為true,則不允許任何IP訪問,
// 也可以設定為陣列,與webpack-devser@3.X 的allowedHosts一樣
// 此屬性相當於webpack-devser@3.X 的allowedHosts屬性
firewall: true,
// 是否設定HTTP/2伺服器。
// 對於nodeV10以上的版本 由於spdy有問題
// 所以如果將此屬性設定為true,則預設使用https作為服務
http2: false,
// // 是否使用https安全連線
// // boolean 或者 object
// // 當為object時,可以設定安全證書
// // 預設為false,但是當開啟http2屬性時,會預設使用https 預設情況下, dev-server使用HTTPS為HTTP/2提供服務
// https: {
// // 證書,證書屬性也可以設定在devServer下,當https設定為boolean時, 與https同級設定
// key: '',//fs.readFileSync('/path/to/server.key'),
// cert: '',//fs.readFileSync('/path/to/server.crt'),
// ca: '',//fs.readFileSync('/path/to/ca.pem'),
// },
// 伺服器代理配置,當前後端分離開發時,前端請求API需要指定地址
// 此屬性可以設定代理的IP地址
// 例如如下,當api請求 /api/user真實地址為http://localhost:3000/user
// 詳情使用請參考官網https://webpack.js.org/configuration/dev-server/#devserverproxy
proxy: {
'/api':{
target: 'http://localhost:3000',
// pathRewrite屬性可以設定字首,如果不設定pathRewrite: /api/user真實地址為http://localhost:3000/api/user
pathRewrite: {'^/api' : ''},
// HTTPS設定為無效證書
// secure: false
}
},
// 伺服器返回時加入的response的自定義header
headers: {
'X-Custom-Foo': 'bar'
},
// 靜態檔案屬性
// 此屬性是對webpack-devser@3.X某些屬性的彙總
static: {
// 要掛載在伺服器上靜態檔案的本地目錄
// 預設為為當前工作目錄
// 建議使用絕對地址
// 例如設定為 /assets後, 會載入使用本地/assets目錄下的靜態檔案到伺服器
// 相當於webpack-dev-server@3.X的 contentBase屬性
directory: path.join(config.root),
// 掛載到伺服器中介軟體的可訪問虛擬地址
// 例如設定為/static,在訪問伺服器靜態檔案時,就需要使用/static字首
// 相當於webpack-dev-server@3.X的 contentBasePublicPath屬性
publicPath: '/',
// 設定掛在靜態檔案時使用的引數
// 相當於webpack-dev-server@3.X的 staticOptions屬性
staticOptions: undefined,
// 是否加入serve-index中介軟體,預設為true
// 相當於webpack-dev-server@3.X的 // 是否可以在瀏覽器訪問靜態檔案列表。
// 預設為true,webpack-dev-server使用的是serve-index中介軟體實現這一功能
// 相當於webpack-dev-server@3.X的 serveIndex屬性
serveIndex: true,
// 是否使用chokidar庫進行監聽文帝靜態檔案變化。
// webpack使用的是檔案系統的的變化通知,但是有時候可能會不管用,例如使用網路檔案系統
// 所以可以設定屬性使用chokidar庫進行輪詢檢測檔案變化。
// 此屬性可以設定為boolean型別也可以設定為物件型別指定輪詢時間(毫秒數)
// 相當於webpack-dev-server@3.X的 watchOptions屬性
watch: {
poll: 3000
},
},
// 設定WebSocket客戶端的一些屬性
client: {
// 推送客戶端日誌級別,
// 屬性具有 "none" | "error" | "warn" | "info" | "log" | "verbose"
// 例如設定error ,WS並不是推送打包警告和訊息, WS客戶端會將日誌列印在控制檯上
// 如果設定為none, 就算打包失敗也不會有訊息
// 相當於webpack-dev-server@3.X的 clientLogLevel屬性
logging: 'verbose',
// 是否在瀏覽器控制檯列印打包進度,
// 相當於webpack-dev-server@3.X的 progress屬性
progress: true,
// 相當於webpack-dev-server@3.X的 sockPath屬性
// path: '',
// 相當於webpack-dev-server@3.X的 sockHost屬性
// host: '',
// 相當於webpack-dev-server@3.X的 sockPort屬性
// port: '',
},
public: undefined,
// webpack-dev-middleware中介軟體使用的屬性
dev:{
// 設定伺服器response加入的自定義header資訊
// 此屬性在webpack-dev-middleware中介軟體使用
headers:{
// 響應頭新增資料
'X-Dev-Header': 'X-Dev-Header',
serverSideRender: false,
},
// 設定webpack-dev-middleware中介軟體的mimeTypes
// 相當於webpack-dev-server@3.X的 mimeTypes屬性
// 相當於webpack-dev-server@3.X的 mimeTypes屬性
mimeTypes:{
},
// 是否將打包結果寫入到磁碟之中
// 預設為false
// 相當於webpack-dev-server@3.X的 writeToDisk屬性
writeToDisk: true,
// 設定打包檔案儲存的目錄地址。此屬性由webpack-dev-middleware設定
// 例如當設定為/public,那麼訪問伺服器所有資訊都需要加入/public字首
// 相當於webpack-dev-server@3.X的 publicPath屬性
publicPath: '/',
// 設定根目錄所指向的頁面。
// 例如localhost:8080可以直接訪問到index.html是因為預設值為index.html
// 預設值也是index.html
// 相當於webpack-dev-server@3.X的 index屬性
index: 'index.html',
// none" | "summary" | "errors-only" | "errors-warnings" | "minimal" | "normal" | "detailed" | "verbose" | boolean | object { … }
// 設定打包檔案日誌輸出級別,會輸出在伺服器終端
// 相當於webpack-dev-server@3.X的 stats屬性
stats: 'minimal',
// 自定義打包檔案的輸出流
// 預設情況下,輸入流為memory
outputFileSystem: undefined,
methods: undefined,
serverSideRender: undefined
},
// 設定編譯出錯或警告後,頁面是否會直接顯示資訊, boolean | {}
// 預設為false,當失敗後會顯示空白頁
// 設定為true後,編譯失敗會顯示錯誤/警告的覆蓋層,也可以設定為object,顯示多種型別資訊
overlay: {
warning:true,
errors: true
},
// 是否要注入WebSocket客戶端。也就是是否要進行長連結通訊
// boolean | function (compilerConfig) => boolean
// 將此屬性設定為false,那麼hot、overlay等功能都會失效
// 預設為true, 有興趣的諸君可以設定為false測試一下
injectClient: true,
// 是否注入HMR, 這個屬性是injectClient的子集。隻影響熱更新
injectHot: true,
// 是否開啟自動重新整理瀏覽器功能
// 此屬性優先順序低於hot
liveReload: false,
// 是否開啟ZeroConf網路
bonjour: false,
// 是否將所有404頁面都跳轉到index.html
// boolean | object
// 當此屬性設定為true或為object時並且使用HTML5 API時 所有404頁面會跳轉到index.html
// 使用的connect-history-api-fallback庫 設定為物件,則會將此物件傳參給connect-history-api-fallback庫
historyApiFallback: false,
// 是否使用區域網IP開啟頁面
useLocalIp: false,
// 是否監聽node中stdin.end事件, 關閉伺服器
stdin: false,
// 終止訊號,設定為true時 監聽['SIGINT', 'SIGTERM'];事件,事件觸發後結束程式
// 目前dev-server強制將此屬性設定為true了,所以改為false不管用。
setupExitSignals: true,
// 設定WebSocket
// 可以設定使用的WebSocket庫。內建的庫為sockjs和ws
// 還可以自定義設定WebSocket Server和WebSocket Client
transportMode:{
// 設定使用的WebSocket, 值為 sockjs或者ws
// sockjs 使用的sockjs庫
// ws 使用的ws庫
// webpack-dev-server@4.X使用的是WS webpack-dev-server@3.X 使用的是sockjs
// 目前在webpack-dev-server@4.X使用sockjs會出錯, webpack-dev-server@3.X使用WS也會報錯
server: 'ws'
},
// 自定義中介軟體鉤子屬性
// 優先於server內部中介軟體執行
// 相當於webpack-devser@3.X 的before函式
onBeforeSetupMiddleware: (app, server, compiler) =>{
//console.log('我是before', compiler.options)
},
// server內部執行完所有中介軟體後執行當前中介軟體
// 相當於webpack-devser@3.X 的after函式
onAfterSetupMiddleware: (app, server, compiler) =>{
},
// dev-server提供的當伺服器啟動後執行的鉤子函式
onListening: (server) => {
// const port = server.listeningApp.address().port;
// console.log('Listening on port:', port);
},
},
}
])
-
host:伺服器啟動使用的host地址
屬性可設定為:String
預設值:localhost
-
port:伺服器啟動使用的埠號
屬性可設定為:Number
預設值:8080
-
open:啟動伺服器後是否自動開啟瀏覽器,
屬性可設定為:String、Boolean
屬性值為Boolean:是否開啟預設瀏覽器
屬性值為String:設定開啟指定的瀏覽器,例如:chrome
預設值:false
-
openPage:自動開啟瀏覽器時的路由地址。
屬性可設定為:String、Array
屬性值為String:開啟指定的地址
屬性值為Array:開啟陣列中的所有地址。
預設值:index.html
-
compress:是否啟動gzip壓縮資料。
使用的compression中介軟體進行壓縮。
預設值:false
-
hot:是否啟動熱更新(HMR)。
熱更新(HMR)技術是程式碼更新後,瀏覽器只載入需要更新的資料。熱更新(HMR)屬性是必備屬性之一。
熱更新(HMR)真正執行的是webpack中HotModuleReplacementPlugin
預設值:false
-
firewall:是否啟用防火牆
屬性可設定為:Boolean、Array
屬性值為Boolean:是否啟用防火牆,為true,則不允許其它任意主機訪問;為false,則允許其它主機訪問
屬性值為Array:設定可以訪問的IP地址。 相當於 webpack-dev-server@3.X中allowedHosts
預設值:true
? 此屬性就是webpack-dev-server@3.X的allowedHosts屬性
-
https:是否使用HTTPS安全連線方式。
屬性可設定為:Boolean、Object
屬性值為Boolean:是否使用HTTPS連線方式
屬性值為Object:設定HTTPS安全證書資訊
預設值:false
-
http2:是否使用HTTP/2
當此屬性設定為true時,預設會使用HTTPS安全連線方式。也就是https會設定為true
預設值:false。
-
proxy:伺服器代理配置。
前後端分離時,前端請求API需要指定地址,此屬性可以配置IP地址,當訪問指定請求時就請求配置的IP地址。
例如在請求 /api 的介面時會訪問http://localhost:3000。具體可參考官網:devserverproxy。
當然也可以不使用此屬性,直接使用一個靜態字串或者配置檔案。看個人編碼習慣
-
headers:設定伺服器Response訊息內自定義header資訊。
屬性可設定為:Object
預設值:null
-
static:對靜態檔案屬性的配置
屬性可設定為:Object、Array
屬性值為Object:配置靜態檔案屬性
屬性值為Array:配置多個靜態檔案屬性
webpack-dev-server@3.X不具有此屬性。此屬性只是將webpack-dev-server@3.X中關於靜態檔案配置的屬性進行彙總封裝
-
directory:設定伺服器掛在靜態檔案的 本地目錄。
例如設定為 /assets 後, 會載入使用本地 /assets 目錄下的靜態檔案到伺服器
屬性可設定為:String
預設值:/ package.json檔案所在地址。
? 此屬性就是webpack-dev-server@3.X的contentBase屬性
-
publicPath:靜態檔案掛載到伺服器中的虛擬地址,
例如設定為 /static 後, 那麼使用靜態檔案時必須加入 /static 字首
屬性可設定為:String
預設值:/
? 此屬性就是webpack-dev-server@3.X的contentBasePublicPath屬性
-
staticOptions:伺服器掛載靜態檔案時使用到的引數
webpack-dev-server掛在靜態檔案使用的是 express.static(directory,staticOptions) 中介軟體,此屬性進行 express.static(directory,staticOptions) 使用的引數,具體請參考express框架
屬性可設定為:Object
-
serveIndex: 是否可以在瀏覽器訪問靜態檔案列表。
webpack-dev-server使用的是serve-index庫作為瀏覽器訪問靜態檔案功能。
屬性可設定為:Boolean
預設值:true
? 此屬性就是webpack-dev-server@3.X的serveIndex屬性
-
watch:是否使用輪詢方式檢查檔案變化。
webpack預設使用的是檔案系統的變化通知。但是在特殊情況下(例如網路檔案系統)時訊息通知會失效
所以可以使用輪詢方式進行檢查檔案變化。使用的chokidar來做輪詢檢測
屬性可設定為:Boolean、Object
屬性值為Boolean:是否開啟輪詢檢測
屬性值為Object:配置輪詢引數,例如配置輪詢時間等
預設值:false
? 此屬性就是webpack-dev-server@3.X的watchOptions屬性
-
client:WebSocket客戶端屬性的設定。
屬性可設定為:Object
webpack-dev-server@3.X不具有此屬性。此屬性只是將webpack-dev-server@3.X中關於WebSocket客戶端配置屬性的彙總封裝
-
logging:WebSocket客戶端在瀏覽器控制檯中輸出日誌級別。
屬性可設定為:"none" | "error" | "warn" | "info" | "log" | "verbose"
預設值:info
例如設定為verbose 便會將所有日誌輸出在瀏覽器控制檯;none則不會輸出任何日誌
?此屬性就是webpack-dev-server@3.X的clientLogLevel屬性
-
progress:是否將打包進度輸出在瀏覽器控制檯中(瀏覽器控制檯是否顯示打包進度)
屬性可設定為:Boolean
預設值:false
?此屬性就是webpack-dev-server@3.X的progress屬性
-
-
dev:設定webpack-dev-middleware中介軟體使用的一些配置屬性。
屬性可設定為:Object
webpack-dev-server@3.X不具有此屬性。此屬性只是將webpack-dev-server@3.X中關於webpack-dev-middleware使用屬性的彙總封裝
-
headers:設定伺服器Response訊息內自定義header資訊。
webpack-dev-server@3.X 中devServer.headers在兩個地方使用到了。而webpack-dev-server@4.X進行了拆分,此屬性只負責webpack-dev-middleware中介軟體。只不過最後結果都一致。
屬性可設定為:Object
-
mimeTypes:設定webpack-dev-middleware mimeTypes屬性,具體請參考webpack-dev-middleware文件 。
?此屬性就是webpack-dev-server@3.X的 mimeTypes屬性
-
writeToDisk:是否將打包編譯檔案寫入磁碟
webpack-dev-middleware預設會將打包編譯檔案寫入到記憶體流,以達到更快的訪問速度。
屬性可設定為:Boolean
預設值:false
?此屬性就是webpack-dev-server@3.X的writeToDisk屬性
-
publicPath:設定打包編譯檔案存放的目錄地址
例如設定為 /public ,那麼在訪問打包編譯生成的檔案資源時都需要新增 /public 字首
屬性可設定為:String
預設值:/
?? static.publicPath和dev.publicPath屬性設定不一樣, static.publicPath
static.publicPath 代表靜態檔案在伺服器中儲存的地址,程式碼使用靜態檔案時需要新增目錄字首
dev.publicPath 代表將程式碼編譯打包的目錄地址,瀏覽器訪問時需要新增目錄字首
? 此屬性就是的publicPath屬性
-
index:根目錄所指向的檔案。
此屬性就是能夠在瀏覽器訪問根目錄指向index.html的原因。
屬性可設定為:String
預設值:index.html
? 此屬性就是webpack-dev-server@3.X的index屬性
-
stats:設定打包檔案時日誌輸出級別。
啟動dev-server時會在控制檯中看到好多打包資訊:檔案大小、檔名稱等資訊,就是使用此屬性進行控制。
屬性可設定為:“none" | "summary" | "errors-only" | "errors-warnings" | "minimal" | "normal" | "detailed" | "verbose" | boolean | object { … }
預設值:normal
? 此屬性就是webpack-dev-server@3.X的stats屬性
-
outputFileSystem:控制打包檔案的輸出流。
預設輸出流是記憶體流,之將檔案編譯打包至記憶體中,此屬性可以更改輸出流。
-
-
-
overlay:打包編譯時出現錯誤/警告時,是否直接顯示在頁面。
此屬性在webpack-dev-server@4.0.0beta.0具有bug。
屬性可設定為:Boolean、Object
屬性值為Boolean:為false時不顯示;為true時,當編譯出現錯誤時,顯示在頁面中
屬性值為Object:自定義配置警告和錯誤狀態。
-
injectClient:是否注入WebSocket
屬性可設定為:Boolean、function (compilerConfig) => boolean
預設值:true
-
injectHot:是否注入熱更新(HMR)。
此屬性是相當於injectClient屬性的一個子集,只控制熱更新(HMR)
屬性可設定為:Boolean、function (compilerConfig) => boolean
預設值:true
?? 此屬性在webpack-dev-server@4.0.0beta.0原始碼中還可以設定only字串,也就是webpack-dev-server@3.X 中的hotOnly屬性。但是屬性校驗中只允許設定Boolean。
-
liveReload:是否啟動重新整理瀏覽器
此屬性開啟後會在在更新程式碼資料後重新重新整理瀏覽器
但是此屬性優先順序低於hot,當開啟熱更新後,會優先使用熱更新。
屬性可設定為:Boolean
預設值:false
-
bonjour:是否開啟Zeroconf網路
關於Zeroconf,有興趣的朋友可以檢視相關文件
屬性可設定為:boolean
預設值:false
-
historyApiFallback:是否將所有404頁面指向index.html
此屬性使用了connect-history-api-fallback來處理404頁面
屬性可設定為:Boolean、Object
屬性值為Boolean:是否啟用此功能
屬性值為Object:設定connect-history-api-fallback庫的引數
預設值:false
-
useLocalIp:是否使用本地區域網啟用伺服器
屬性可設定為:Boolean
預設值:false
-
stdin:是否監聽Node.js中stdin.end事件關閉伺服器
屬性可設定為:Boolean
預設值:false
-
setupExitSignals:是否監聽Node.js中的 ['SIGINT', 'SIGTERM'] 事件關閉伺服器。
此屬性為webpack-dev-server@4.0.0beta.0新增加,在webpack-dev-server@4.0.0beta.0版本測試,此屬性內建了true屬性,無法更改
-
transportMode:設定WebSocket庫資訊。
webpack-dev-server內建了兩個WebSocket庫:ws、sockjs。可以進行使用,並且可以自定義WebSocket Server和WebSocket Client。具體請參考官網
?
webpack-dev-server@4.0.0beta.0預設使用:ws
webpack-dev-server@3.X預設使用:sockjs
-
onBeforeSetupMiddleware:自定義鉤子中介軟體函式,此中介軟體會優先其它中介軟體執行。
?此屬性就是webpack-dev-server@3.X的before屬性
-
onAfterSetupMiddleware:自定義鉤子中介軟體函式,此中介軟體會在所有中介軟體之後執行。
?此屬性就是webpack-dev-server@3.X的after屬性
-
onListening:設定webpack-dev-server伺服器啟動後執行的鉤子函式。
-
以上便是webpack-dev-server@4.0.0beta.0中部分配置屬性。
相對於webpack-dev-server@3.X,webpack-dev-server@4.0.0beta.0版本對配置屬性做了更好的整合。
host / port
這兩個屬性是最容易理解並且使用最多屬性之一。
webpack-dev-server內部使用express框架。
webpack-dev-server@4.0.0beta.0庫中 /lib/Server.js 檔案就是webpack-dev-server伺服器模組。
/lib/Server.js 具有一個 listen(),listen() 就是啟動伺服器函式。
而listen()的呼叫是在@webpack-cli庫的serve/lib/startDevServer.js。
可以看到在serve/lib/startDevServer.js中使用了options.port和options.host屬性值來啟動伺服器。
這兩個屬性就是來自webpack配置中的devServer。
至於預設8080埠號的提供是在findPort()
?? 原始碼是基於webpack-dev-server@4.0.0beta.0。?raw=true
open、 openPath
這兩個屬性在伺服器啟動後判斷是否啟動瀏覽器。
Server.listen() 回撥函式呼叫了showStatus()。
隨後呼叫了 /lib/util/runOpen.js模組啟動瀏覽器
可以看到,open和openPath屬性都做了型別判斷。
open屬性支援設定字串開啟指定瀏覽器;
openPath可以配置為陣列開啟多個頁籤。最後使用了open庫來開啟瀏覽器
hot、lveReload
在Server.listen() 回撥函式中使用 hot屬性做了判斷 ,當設定了hot或liveReload屬性時,就會建立WebSocket· Server 。
也就是隻有設定了hot或者liveReload時,才會使用WebSocket 與瀏覽器進行長連結
static
static屬性剛才說了,是webpack-dev-server@4.X對關於靜態檔案屬性的封裝:訪問路徑、檔案監聽等。
在這裡只是詳細介紹下部分屬性。
directory、publicPath、staticOptions
這三個屬性是express伺服器設定靜態檔案使用的屬性。
在Server.setupStaticFeature(),使用了express伺服器掛載了靜態檔案中介軟體(express.static)。
將中介軟體掛載到伺服器上的訪問地址是:static.publicPath。
而掛載的本地靜態檔案地址是:static.directory。
可以看到,express伺服器掛載了其訪問目錄為publicPath。而要掛載本地靜態檔案目錄為directory。
靜態檔案中介軟體使用的引數是:static.staticOptions
例如
將static.directory屬性設定為: path.join(config.root, 'assets');static.publicPath屬性設定為:/static
在訪問 /assets/images/yj.png 圖片時就應該使用 /static/images/yj.png
?? static.publicPath和static.directory屬性一般不會自定義,如需自定義,需要注意將目錄地址設定好,避免在production找不到
? 原始碼中static和static.publicPath屬性都是Array。所以配置屬性時可以配置為Array
? 在此只是以圖片做一個例子,並不涉及到檔案打包。
serveIndex
此屬性是設定能否在瀏覽器中檢視靜態檔案。webpack-dev-server內部使用的是serve-index庫
如果將static.serverIndex屬性設定為false,那麼在瀏覽器中檢視靜態檔案路徑,會直接是404
如果static.serverIndex屬性為true,那就可以在瀏覽器中檢視靜態檔案
dev
此屬性是webpack-dev-middleware庫使用的一系列屬性彙總。
index
此屬性是設定根目錄所指向的檔案,程式碼在webpack-dev-middleware庫中 /dist/utils/getFilenameFromUrl.js 檔案
可以看到,在處理static.index屬性時做了型別判斷。
並且其預設值為index.html。
由於html-webpack-plugin庫中的filename屬性預設值也是index.html
也就可以在不做配置情況下預設就可以在根目錄下訪問程式碼。
當然也可以更改此屬性。不過在更改程式碼時也要將html-webpack-plugin庫的filename屬性進行更改。否則訪問時會404
??? 約定大於配置,編寫程式碼時儘量做到使用統一約定。
stats
此屬性是控制打包日誌輸出等級的。在預設情況的執行webpack-dev-server。總是能在控制檯輸出好多日誌資訊。這些日誌資訊就是由此屬性控制的。
程式碼是在webpack-dev-middleware庫中 /dist/utils/setupHook.js 模組。
程式碼中 stats 欄位是內部提供的一個狀態物件,根據 statsOptions(dev.stats) 屬性獲取指定的狀態資訊。
如果將dev.stats設定為errors-only,控制檯就不會有這麼多日誌,errors-only屬性值代表只有在程式碼打包錯誤時才輸出日誌。
而如果設定為none,那麼連錯誤日誌都不會再輸出。.
overlay
此屬性是控制程式碼打包編譯時出現警告和錯誤時,是否在頁面上顯示錯誤資訊。
此屬性在webpack-dev-server@4.0.0beta.0版本具有bug。
在下面Server.js檔案中可以看到使用了clientOverlay屬性,但是在dev物件中並沒有此屬性。
所需在測試時需要改動一下原始碼。將clientOverlay改為overlay。
所以在測試時需要改動一下原始碼。將clientOverlay改為overlay。
當overlay屬性值為true時,如果程式碼出現編譯錯誤,會直接在頁面上顯示錯誤資訊。
這個功能個人感覺還挺好用。不過可能有些人更喜歡使用控制檯檢視錯誤資訊,也就是dev.stats屬性。
historyApiFallback
此屬性代表在使用 HTML5 API 時是否將所有 無效路由(404) 都跳轉到指定頁面。
類似於專案中將所有 無效路由(404) 轉到 指定404頁面
webpack-dev-server內部使用的是connect-history-api-fallback中介軟體來做處理,預設跳轉的頁面是index.html。
總結
???
- webpack-dev-server是為了方便開發而提供的一種功能, 利用WebSocket與伺服器建立長連結。
- webpack@4.X版本對程式碼結構進行了大範圍更改,導致與webpack-dev-server@3.X使用
webpack-dev-server
命令會報錯。- webpack-dev-server@4.X版本對devServer屬性根據功能進行了更好的彙總。
本文參考
本文依賴
package.json
{
"name": "my-cli",
"version": "1.0.0",
"main": "index.js",
"author": "mowenjinzhao<yanzhangshuai@126.com>",
"license": "MIT",
"devDependencies": {
"@babel/core": "7.13.1",
"@babel/plugin-transform-runtime": "7.13.7",
"@babel/preset-env": "7.13.5",
"@babel/preset-react": "7.12.13",
"@babel/runtime-corejs3": "7.13.7",
"babel-loader": "8.2.2",
"clean-webpack-plugin": "3.0.0",
"html-webpack-plugin": "5.2.0",
"webpack": "5.24.0",
"webpack-cli": "4.5.0",
"webpack-dev-server": "4.0.0-beta.0",
"webpack-merge": "5.7.3"
},
"dependencies": {
"react": "17.0.1",
"react-dom": "17.0.1"
},
"scripts": {
"start:dev": "webpack-dev-server --config build/webpack.dev.js",
"start": "webpack serve --config build/webpack.dev.js",
"build": "webpack --config build/webpack.pro.js",
},
"browserslist": {
"development": [
"chrome > 75"
],
"production": [
"ie 9"
]
}
}