webpack-dev-server 其實並不難

老臘肉學長發表於2019-03-03

原文連結

概述

我們都知道webpack是一個構建工具,但是在開發測試過程中,我們會經常修改程式碼後,然後頻繁重新整理頁面檢視效果,可惜我們就是厭舊重複工作的物種。

剛好webpack這個工具,提供了另外一個工具——webpack-dev-server,它可以幫我們從中解脫。

初試——監聽入口的JS檔案

我們可以監聽入口檔案和其它被它引用(匯入)的檔案,並在檔案更新的時候,通知瀏覽器重新整理網頁。

使用webpack-dev-server的方式很簡單:

  1. 安裝:npm install --save-dev webpack-dev-server
  2. 然後設定伺服器的根目錄,預設為專案的根目錄:
devServer: {
  contentBase: `./dist`,
}
複製程式碼
  1. 然後使用指令webpack-dev-server --open就可以了。也可以把這個指令放在package.js檔案裡的scripts欄位裡。

基本原理

其實就是藉助Express開啟一個伺服器,然後設定兩個路由出口:

  1. 靜態資源出口:可以通過devServer的欄位contentBase設定靜態資源目錄
  2. webpack output的出口:預設是/,可以通過devServer的欄位publicPath設定

所以,我可以看出,webpack output其實就是Express的一個router物件,webpack根據入口檔案觀察相關的檔案,並在它們發生變化的時候,重新編譯打包,並輸出到router物件上,這樣我們就可以訪問該router拿到最新的資源,不過這個資源是放在記憶體上的,並不是檔案系統上。

網頁和webpack-dev-server是通過websocket協議互聯的。當監聽到檔案變化的時候,會通過websocket通知網頁呼叫reload介面重新整理頁面。

晉級——監聽靜態HTML檔案

監聽靜態檔案的變化並更新。

步驟:

  1. 安裝html-webpack-plugin:npm i -D html-webpack-plugin
  2. 安裝raw-loader:npm i -D raw-loader
  3. 在配置檔案裡配置plugin和loader:
module.exports = {
  mode: `development`,
  entry: `./index.js`,
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      template: "./dist/index.html" // 指定HTML模板的路徑
    })
  ],
  module: {
    rules: [
      {
        test: /.html$/,
        use: `raw-loader`
      }
    ]
  }
}
複製程式碼
  1. 然後在入口檔案index.js裡引用這個HTML模板:require(`./dist/index.html`)
  2. 開啟服務:webpack-dev-server,更新這個index.html就可以看到重新整理了

目前為止,監聽檔案變更後,都是通過通知瀏覽器重新整理的方式重新訪問伺服器獲取新的資源。

缺陷:
每個靜態的HTML檔案都需要在配置檔案裡配置一個HtmlWebpackPlugin

使用gulp監聽靜態檔案

假如我們只想簡單監聽靜態檔案變更,然後讓瀏覽器重新整理的話,使用gulp也是不錯的選擇。

  1. 安裝必要外掛:npm i -D gulp browser-sync run-sequence
  2. 然後在gulpfile.js裡指定監聽檔案:
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);
});
複製程式碼

說明一下上面的主要兩個欄位:server.baseDir用於指定專案的根目錄,gulp.watch()的第一個引數指的是監聽檔案路徑,使用的時候需要根據自己的情況來改變。

  1. 最後執行gulp便可。如果終端提示找不到指令的話,可以通過安裝全域性的gulp,或者加個字首.
    ode_modules.bingulp
    ,或者在package.js裡新增一條指令碼"gulp": "gulp"然後使用指令npm run gulp

高階——模組熱替換

熱替換功能其實也沒有那麼神奇。

用一句話描述就是,通過webpack提供的API監聽一個檔案,並替換已經存在的模組——這需要開發者自己提供替換的邏輯。

步驟:

  1. 開啟熱替換功能:devServer: true
  2. 註冊兩個外掛:new webpack.NamedModulesPlugin()new webpack.HotModuleReplacementPlugin()
  3. 在需要監聽的檔案裡,用邏輯設定需要熱替換的條件,並提供熱替換的邏輯。

代理功能

如果你有單獨的後端開發伺服器 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。
複製程式碼

參考

webpack-dev-server使用方法,看完還不會的來找我~
開發中 Server(devServer)
Extra – Make your HTML hot reload
gulp+browser-sync 監聽檔案實現瀏覽器自動重新整理

相關文章