從零學腳手架(七)---webpack-dev-server使用

莫問今朝·發表於2021-03-16

如果此篇對您有所幫助,在此求一個star。專案地址: OrcasTeam/my-cli

webpack-dev-server使用

什麼是webpack-dev-server

使用vue-clireact-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庫,想深入的介紹下。

在此分為兩篇來介紹:

  1. 介紹webpack-dev-server屬性配置,並且介紹部分屬性原始碼中的設定
  2. 稍微介紹webpack-dev-server流程和原理。

webpack-dev-server 安裝

webpack-cli/bin/config-yargs 的問題

截至到寫此篇時,webpack-dev-server最新版本3.11.2

從零學腳手架(七)---webpack-dev-server使用

有使用過此版本的朋友會知道,webpack-dev-server@3.11.2webpack@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命令

從零學腳手架(七)---webpack-dev-server使用

一般都會將yarn start命令設定為:webpack-dev-server

? 在這裡將yarn start:dev 命令設定為:webpack-dev-server。主要是為了這個錯誤

從零學腳手架(七)---webpack-dev-server使用

此時,如果不出意外的話, 執行yarn start:dev 就可以執行webpack-dev-server

但是,執行就會碰到那個錯誤:

從零學腳手架(七)---webpack-dev-server使用

錯誤提示是找不到webpack-cli庫中的config.yargs模組。感覺會有不少剛學習webpack並且搜尋能力稍微弱一些的朋友會卡在這。

? 配置使用的webpack-cli@4.5.0webpack@5.24.0

這個錯誤其實很簡單,直接在issues就可以找到答案。

從零學腳手架(七)---webpack-dev-server使用

原來是使用了新的執行命令了:webpack serve。現在將新命令進行配置

從零學腳手架(七)---webpack-dev-server使用

此時使用yarn start執行就可以成功執行。預設啟動的是8080埠

從零學腳手架(七)---webpack-dev-server使用

那麼這到底怎麼回事呢?通過檢視原始碼和測試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命令執行的檔案模組

從零學腳手架(七)---webpack-dev-server使用

/bin/webpack-dev-server.js 檔案模組中載入了webpack-cli庫中的 /bin/ [config/] config-yargs/bin/ [utils/] convert-argv

但是在版本 程式碼結構進行了巨大的改變,已經去掉了這兩個檔案模組,所以也就導致了報錯。

從零學腳手架(七)---webpack-dev-server使用

這個問題就是目前處於迭代期的原因。

在之前使用webpack@4.X版本時,使用的webpack-cli@3.Xwebpack-dev-server@3.X

現在更新到了webpack@5.Xwebpack-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使用

webpack-dev-server@4.0.0beta.0程式碼可以看到 /bin/webpack-dev-server.js 檔案模組中沒有了上面兩段程式碼。

從零學腳手架(七)---webpack-dev-server使用

webpack-dev-server@4.0.0beta.0文件中的命令改為了webpack serve。不過webpack-dev-server依然可以使用。

從零學腳手架(七)---webpack-dev-server使用

??? webpack-cli@4.X版本開始,webpack團隊將dev-server的命令改為了webpack servewebpackwebpack-cli都進行了大版本的更新。webpack-dev-server目前新版本還沒有開發完成。所以暫時就出了這麼一個問題

webpack serve命令在 webpack-cli@4.0.0版本文件中可以找到。

從零學腳手架(七)---webpack-dev-server使用
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-dev-server使用

?? webpackwebpack-cliwebpack-dev-server跨庫呼叫都是根據模組路徑呼叫。所以只要某個庫檔案結構稍微改動,就會像webpack-dev-server命令這樣直接報錯。 不過在新版本程式碼進行了優化,通過約定名稱進行跨庫呼叫。儘可能降低了耦合度。

? @webpack-cliwebpack-cli@4.X依賴的一個庫。

webpack-dev-server@3.X 和webpack@5.X WebSocket問題

執行yarn start後,會開啟一個8080埠的伺服器。

但是webpack@5.Xwebpack-dev-server@3.X一起使用時WebSocket還有問題

上面簡單說過WebSocket是與瀏覽器建立長連結,通過WebSocket向瀏覽器推送資訊進行改變瀏覽器狀態。

下面來做一個測試,執行yarn start後,使用瀏覽器訪問。

從零學腳手架(七)---webpack-dev-server使用

此時如果將程式碼更新,會發現瀏覽器並沒有同步更新,並且瀏覽器WS視窗沒有推送資料

? WS“:WebSocket資料顯示視窗

從零學腳手架(七)---webpack-dev-server使用 從零學腳手架(七)---webpack-dev-server使用

後來我對原始碼進行了除錯,發現根本就沒有連線WebSocket Server

最後在github中找到了答案。

原因是package.json檔案中的browserslist屬性,將此屬性去掉就可以進行推送。

從零學腳手架(七)---webpack-dev-server使用

這是webpack-dev-server@3.X的一個問題。但是按照官方給出的解釋好像只會在webpack-dev-server@4.X中修復這個問題。

從零學腳手架(七)---webpack-dev-server使用

我也使用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.0webpack-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:啟動伺服器後是否自動開啟瀏覽器,

    屬性可設定為:StringBoolean

    屬性值為Boolean:是否開啟預設瀏覽器

    屬性值為String:設定開啟指定的瀏覽器,例如:chrome

    預設值:false

  • openPage:自動開啟瀏覽器時的路由地址。

    屬性可設定為:StringArray

    屬性值為String:開啟指定的地址

    屬性值為Array:開啟陣列中的所有地址。

    預設值:index.html

  • compress:是否啟動gzip壓縮資料。

    使用的compression中介軟體進行壓縮。

    預設值:false

  • hot:是否啟動熱更新(HMR)

    熱更新(HMR)技術是程式碼更新後,瀏覽器只載入需要更新的資料。熱更新(HMR)屬性是必備屬性之一。

    熱更新(HMR)真正執行的是webpackHotModuleReplacementPlugin

    預設值:false

  • firewall:是否啟用防火牆

    屬性可設定為:BooleanArray

    屬性值為Boolean:是否啟用防火牆,為true,則不允許其它任意主機訪問;為false,則允許其它主機訪問

    屬性值為Array:設定可以訪問的IP地址。 相當於 webpack-dev-server@3.XallowedHosts

    預設值:true

    ? 此屬性就是webpack-dev-server@3.XallowedHosts屬性

  • https:是否使用HTTPS安全連線方式。

    屬性可設定為:BooleanObject

    屬性值為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:對靜態檔案屬性的配置

    屬性可設定為:ObjectArray

    屬性值為Object:配置靜態檔案屬性

    屬性值為Array:配置多個靜態檔案屬性

    webpack-dev-server@3.X不具有此屬性。此屬性只是將webpack-dev-server@3.X中關於靜態檔案配置的屬性進行彙總封裝

    • directory:設定伺服器掛在靜態檔案的 本地目錄

      例如設定為 /assets 後, 會載入使用本地 /assets 目錄下的靜態檔案到伺服器

      屬性可設定為:String

      預設值:/ package.json檔案所在地址。

      ? 此屬性就是webpack-dev-server@3.XcontentBase屬性

    • publicPath:靜態檔案掛載到伺服器中的虛擬地址

      例如設定為 /static 後, 那麼使用靜態檔案時必須加入 /static 字首

      屬性可設定為:String

      預設值:/

      ? 此屬性就是webpack-dev-server@3.XcontentBasePublicPath屬性

    • 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.XserveIndex屬性

    • watch:是否使用輪詢方式檢查檔案變化。

      webpack預設使用的是檔案系統的變化通知。但是在特殊情況下(例如網路檔案系統)時訊息通知會失效

      所以可以使用輪詢方式進行檢查檔案變化。使用的chokidar來做輪詢檢測

      屬性可設定為:BooleanObject

      屬性值為Boolean:是否開啟輪詢檢測

      屬性值為Object:配置輪詢引數,例如配置輪詢時間等

      預設值:false

      ? 此屬性就是webpack-dev-server@3.XwatchOptions屬性

    • clientWebSocket客戶端屬性的設定。

      屬性可設定為:Object

      webpack-dev-server@3.X不具有此屬性。此屬性只是將webpack-dev-server@3.X中關於WebSocket客戶端配置屬性的彙總封裝

      • loggingWebSocket客戶端在瀏覽器控制檯中輸出日誌級別。

        屬性可設定為:"none" | "error" | "warn" | "info" | "log" | "verbose"

        預設值:info

        例如設定為verbose 便會將所有日誌輸出在瀏覽器控制檯;none則不會輸出任何日誌

        ?此屬性就是webpack-dev-server@3.XclientLogLevel屬性

      • progress:是否將打包進度輸出在瀏覽器控制檯中(瀏覽器控制檯是否顯示打包進度)

        屬性可設定為:Boolean

        預設值:false

        ?此屬性就是webpack-dev-server@3.Xprogress屬性

    • 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.XdevServer.headers在兩個地方使用到了。而webpack-dev-server@4.X進行了拆分,此屬性只負責webpack-dev-middleware中介軟體。只不過最後結果都一致。

        屬性可設定為:Object

      • mimeTypes:設定webpack-dev-middleware mimeTypes屬性,具體請參考webpack-dev-middleware文件

        ?此屬性就是webpack-dev-server@3.XmimeTypes屬性

      • writeToDisk:是否將打包編譯檔案寫入磁碟

        webpack-dev-middleware預設會將打包編譯檔案寫入到記憶體流,以達到更快的訪問速度。

        屬性可設定為:Boolean

        預設值:false

        ?此屬性就是webpack-dev-server@3.XwriteToDisk屬性

      • publicPath:設定打包編譯檔案存放的目錄地址

        例如設定為 /public ,那麼在訪問打包編譯生成的檔案資源時都需要新增 /public 字首

        屬性可設定為:String

        預設值:/

        ?? static.publicPathdev.publicPath屬性設定不一樣, static.publicPath

        static.publicPath 代表靜態檔案在伺服器中儲存的地址,程式碼使用靜態檔案時需要新增目錄字首

        dev.publicPath 代表將程式碼編譯打包的目錄地址,瀏覽器訪問時需要新增目錄字首

        ? 此屬性就是的publicPath屬性

      • index:根目錄所指向的檔案。

        此屬性就是能夠在瀏覽器訪問根目錄指向index.html的原因。

        屬性可設定為:String

        預設值:index.html

        ? 此屬性就是webpack-dev-server@3.Xindex屬性

      • stats:設定打包檔案時日誌輸出級別。

        啟動dev-server時會在控制檯中看到好多打包資訊:檔案大小、檔名稱等資訊,就是使用此屬性進行控制。

        屬性可設定為:“none" | "summary" | "errors-only" | "errors-warnings" | "minimal" | "normal" | "detailed" | "verbose" | boolean | object { … }

        預設值:normal

        ? 此屬性就是webpack-dev-server@3.Xstats屬性

      • outputFileSystem:控制打包檔案的輸出流。

        預設輸出流是記憶體流,之將檔案編譯打包至記憶體中,此屬性可以更改輸出流。

  • overlay:打包編譯時出現錯誤/警告時,是否直接顯示在頁面。

    此屬性在webpack-dev-server@4.0.0beta.0具有bug。

    屬性可設定為:BooleanObject

    屬性值為Boolean:為false時不顯示;為true時,當編譯出現錯誤時,顯示在頁面中

    屬性值為Object:自定義配置警告和錯誤狀態。

  • injectClient:是否注入WebSocket

    屬性可設定為:Booleanfunction (compilerConfig) => boolean

    預設值:true

  • injectHot:是否注入熱更新(HMR)

    此屬性是相當於injectClient屬性的一個子集,只控制熱更新(HMR)

    屬性可設定為:Booleanfunction (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頁面

    屬性可設定為:BooleanObject

    屬性值為Boolean:是否啟用此功能

    屬性值為Object:設定connect-history-api-fallback庫的引數

    預設值:false

  • useLocalIp:是否使用本地區域網啟用伺服器

    屬性可設定為:Boolean

    預設值:false

  • stdin:是否監聽Node.jsstdin.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庫:wssockjs。可以進行使用,並且可以自定義WebSocket ServerWebSocket Client。具體請參考官網

    ?

    webpack-dev-server@4.0.0beta.0預設使用:ws

    webpack-dev-server@3.X預設使用:sockjs

    • onBeforeSetupMiddleware:自定義鉤子中介軟體函式,此中介軟體會優先其它中介軟體執行。

      ?此屬性就是webpack-dev-server@3.Xbefore屬性

    • onAfterSetupMiddleware:自定義鉤子中介軟體函式,此中介軟體會在所有中介軟體之後執行。

      ?此屬性就是webpack-dev-server@3.Xafter屬性

    • onListening:設定webpack-dev-server伺服器啟動後執行的鉤子函式。

以上便是webpack-dev-server@4.0.0beta.0中部分配置屬性。

相對於webpack-dev-server@3.Xwebpack-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() 就是啟動伺服器函式。

從零學腳手架(七)---webpack-dev-server使用

listen()的呼叫是在@webpack-cli庫的serve/lib/startDevServer.js

從零學腳手架(七)---webpack-dev-server使用

可以看到在serve/lib/startDevServer.js中使用了options.portoptions.host屬性值來啟動伺服器。

這兩個屬性就是來自webpack配置中的devServer

至於預設8080埠號的提供是在findPort()

從零學腳手架(七)---webpack-dev-server使用 從零學腳手架(七)---webpack-dev-server使用

?? 原始碼是基於webpack-dev-server@4.0.0beta.0。?raw=true

open、 openPath

這兩個屬性在伺服器啟動後判斷是否啟動瀏覽器。

Server.listen() 回撥函式呼叫了showStatus()

隨後呼叫了 /lib/util/runOpen.js模組啟動瀏覽器

從零學腳手架(七)---webpack-dev-server使用

可以看到,openopenPath屬性都做了型別判斷。

open屬性支援設定字串開啟指定瀏覽器;

openPath可以配置為陣列開啟多個頁籤。最後使用了open庫來開啟瀏覽器

hot、lveReload

Server.listen() 回撥函式中使用 hot屬性做了判斷 ,當設定了hotliveReload屬性時,就會建立WebSocket· Server

也就是隻有設定了hot或者liveReload時,才會使用WebSocket 與瀏覽器進行長連結

從零學腳手架(七)---webpack-dev-server使用
static

static屬性剛才說了,是webpack-dev-server@4.X對關於靜態檔案屬性的封裝:訪問路徑、檔案監聽等。

在這裡只是詳細介紹下部分屬性。

directory、publicPath、staticOptions

這三個屬性是express伺服器設定靜態檔案使用的屬性。

Server.setupStaticFeature(),使用了express伺服器掛載了靜態檔案中介軟體(express.static)

將中介軟體掛載到伺服器上的訪問地址是:static.publicPath

而掛載的本地靜態檔案地址是:static.directory

從零學腳手架(七)---webpack-dev-server使用

可以看到,express伺服器掛載了其訪問目錄為publicPath。而要掛載本地靜態檔案目錄為directory

靜態檔案中介軟體使用的引數是:static.staticOptions

例如

static.directory屬性設定為: path.join(config.root, 'assets')static.publicPath屬性設定為:/static

在訪問 /assets/images/yj.png 圖片時就應該使用 /static/images/yj.png

從零學腳手架(七)---webpack-dev-server使用 從零學腳手架(七)---webpack-dev-server使用 從零學腳手架(七)---webpack-dev-server使用

?? static.publicPathstatic.directory屬性一般不會自定義,如需自定義,需要注意將目錄地址設定好,避免在production找不到

? 原始碼中staticstatic.publicPath屬性都是Array。所以配置屬性時可以配置為Array

? 在此只是以圖片做一個例子,並不涉及到檔案打包。

serveIndex

此屬性是設定能否在瀏覽器中檢視靜態檔案。webpack-dev-server內部使用的是serve-index

從零學腳手架(七)---webpack-dev-server使用

如果將static.serverIndex屬性設定為false,那麼在瀏覽器中檢視靜態檔案路徑,會直接是404

從零學腳手架(七)---webpack-dev-server使用 從零學腳手架(七)---webpack-dev-server使用

如果static.serverIndex屬性為true,那就可以在瀏覽器中檢視靜態檔案

從零學腳手架(七)---webpack-dev-server使用 從零學腳手架(七)---webpack-dev-server使用
dev

此屬性是webpack-dev-middleware庫使用的一系列屬性彙總。

index

此屬性是設定根目錄所指向的檔案,程式碼在webpack-dev-middleware庫中 /dist/utils/getFilenameFromUrl.js 檔案

從零學腳手架(七)---webpack-dev-server使用

可以看到,在處理static.index屬性時做了型別判斷。

並且其預設值為index.html

由於html-webpack-plugin庫中的filename屬性預設值也是index.html

也就可以在不做配置情況下預設就可以在根目錄下訪問程式碼。

當然也可以更改此屬性。不過在更改程式碼時也要將html-webpack-plugin庫的filename屬性進行更改。否則訪問時會404

從零學腳手架(七)---webpack-dev-server使用 從零學腳手架(七)---webpack-dev-server使用

??? 約定大於配置,編寫程式碼時儘量做到使用統一約定。

stats

此屬性是控制打包日誌輸出等級的。在預設情況的執行webpack-dev-server。總是能在控制檯輸出好多日誌資訊。這些日誌資訊就是由此屬性控制的。

從零學腳手架(七)---webpack-dev-server使用

程式碼是在webpack-dev-middleware庫中 /dist/utils/setupHook.js 模組。

程式碼中 stats 欄位是內部提供的一個狀態物件,根據 statsOptions(dev.stats) 屬性獲取指定的狀態資訊。

從零學腳手架(七)---webpack-dev-server使用

如果將dev.stats設定為errors-only,控制檯就不會有這麼多日誌,errors-only屬性值代表只有在程式碼打包錯誤時才輸出日誌。

從零學腳手架(七)---webpack-dev-server使用

而如果設定為none,那麼連錯誤日誌都不會再輸出。.

overlay

此屬性是控制程式碼打包編譯時出現警告和錯誤時,是否在頁面上顯示錯誤資訊。

此屬性在webpack-dev-server@4.0.0beta.0版本具有bug。

在下面Server.js檔案中可以看到使用了clientOverlay屬性,但是在dev物件中並沒有此屬性。

所需在測試時需要改動一下原始碼。將clientOverlay改為overlay

從零學腳手架(七)---webpack-dev-server使用

所以在測試時需要改動一下原始碼。將clientOverlay改為overlay

從零學腳手架(七)---webpack-dev-server使用

overlay屬性值為true時,如果程式碼出現編譯錯誤,會直接在頁面上顯示錯誤資訊。

從零學腳手架(七)---webpack-dev-server使用

這個功能個人感覺還挺好用。不過可能有些人更喜歡使用控制檯檢視錯誤資訊,也就是dev.stats屬性。

historyApiFallback

此屬性代表在使用 HTML5 API 時是否將所有 無效路由(404) 都跳轉到指定頁面。

類似於專案中將所有 無效路由(404) 轉到 指定404頁面

webpack-dev-server內部使用的是connect-history-api-fallback中介軟體來做處理,預設跳轉的頁面是index.html

從零學腳手架(七)---webpack-dev-server使用 從零學腳手架(七)---webpack-dev-server使用

總結

???

  • 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"
    ]
  }
}


相關文章