Webpack5 - 開發伺服器 webpack-dev-server

xuanwuziyou發表於2020-12-27

一. Webpack5 - 開發伺服器的作用

webpack-dev-server 可以提供用於開發的 HTTP Server(開發伺服器),它已整合了自動編譯和自動重新整理頁面的功能。

二. Webpack5 - 開發伺服器安裝和使用

1. 安裝

cnpm install webpack-dev-server --save-dev

2. 啟動

yarn webpack serve

看命令輸出,訪問 http://localhost:8080/ 即是開發中的頁面。

嘗試修改樣式檔案-可發現頁面會自動重新整理更新;

嘗試修改js指令碼檔案-可發現頁面會自動重新整理更新;

嘗試修改index.html模板檔案-可發現頁面會自動重新整理更新(發現如果開啟 devServer.hot 為true,則模板檔案更新後不會自動重新整理,需手動重新整理...)。

3. 說明

webpack-dev-server 自動編譯專案,並把編譯結果放入快取中,並不輸出到輸出目錄。

檔案修改後,頁面會重新整理,則會丟失可能的除錯狀態,但是由於邏輯多種多樣,webpack 無法處理,所以只好重新整理頁面。後續可以手動實現webpack的模組熱替換(HMR Hot Module Replacement)來自定義模組的更新邏輯。

三. 開發伺服器配置

1. 設定不必參與打包的靜態資源訪問路徑

webpack.config.js:

module.exports = {
  // 設定開發伺服器
  devServer: {
    // 開發時可直接訪問到 ./public 下的靜態資源,這些資源在開發中不必打包
    contentBase: './public',
  }
}

2. 設定代理API服務

webpack.config.js:

module.exports = {
  // 設定開發伺服器
  devServer: {
    // 配置 API訪問代理
    // http://localhost:8080/api/users/octocat/orgs
    proxy: {
      '/api': {
          // http://localhost:8080/api/users ->             
          // https://api.github.com/api/users
        target: 'https://api.github.com',

          // http://localhost:8080/api/users -> 
          // https://api.githu.com/users
        pathRewrite: {
          '^/api': '' // 替換 /api 開頭 為 ''
        },

        // 不能使用 localhost:8080 作為請求 Github 的主機名
        changeOrigin: true,
      }
    },
  }
}

3. 開啟 HMR (Hot Module Replacement)

模組熱更新(替換),是指在應用的執行過程中實時替換某個模組資源,而執行不用終止。

開啟 webpack HMR,webpack.config.js:

const webpack = require('webpack')
module.exports = {
    devServer: {
        hot: true, // 開啟webpack HRM(模組熱替換)
    },
    plugins: [
      new webpack.HotModuleReplacementPlugin(),
    ]
}

開啟後,可發現:

修改樣式檔案-頁面會自動載入新樣式而不重新整理頁面(因為 style-loader 對樣式模組熱更新邏輯做了處理);而

而修改指令碼檔案-頁面仍然會自動重新整理以更新(而指令碼檔案複雜多樣,webpack不知如何處理)。

4. 手寫邏輯處理指令碼模組的 HMR 邏輯

可在入口js檔案中,處理引入模組的更新邏輯,如:

index.js :

// 應用入口檔案
import './index.css';
import add from './tool.js';
import background from './img.jpeg';

console.log(add(6, 6));

var imgEle = new Image()
imgEle.src = background;
document.body.append(imgEle);


/* 使用 webpack HMR 的 API 來處理模組更新邏輯 避免頁面重新整理
module.hot.accept 可註冊一個模組(路徑)的更新邏輯 */ 
if(module.hot) { // 如果開啟了webpack模組熱更新
  // 處理 tool.js 模組的熱更新
  module.hot.accept('./tool.js', () => {
    console.log('tool 模組更新啦...')
    console.log(add(6, 6));
  })

  // 處理 img.jpeg 圖片檔案 的熱更新
  module.hot.accept('./src/img.jpeg', () => {
    imgEle.src = background;
  })
}

5. 注意事項 - 手寫邏輯處理指令碼模組的 HMR 邏輯

a. 處理 HMR 的程式碼報錯會導致自動重新整理,解決方式是用 hotOnly 替換 hot:

devServer: {
  hotOnly: true,
},

b. 應判斷 module.hot 是否存在

c. 打包後的程式碼不會包含 對 HMR 模組替換邏輯的程式碼

本文 完。

相關文章