Webpack.devServer 設定項如何使用?附devServer完整範例

2023-11-19 15:00:24

前言: 我們在平常本地開發時,可能經常需要與後端進行聯調,或者呼叫一些api,但是由於瀏覽器跨域的限制、開發與生產環境的差異、http與https等問題經常讓聯調的過程不夠順暢。所以本文介紹一下webpack的devServer中的proxy設定項。接下來讓我們先看一下這個設定項的基本使用:


基本使用

  1. 基本代理設定:如果你有一個在localhost:3000上的後端,你可以通過簡單的設定將/api路由代理到這個後端伺服器。webpack會對所有本地發出的字首為/api的請求,轉發到localhost:3000
   proxy: {
     '/api': 'http://localhost:3000',
   }
  // 範例
  // 假設你原生的前端服務跑在8080埠
  axios.get('/api/user/info') // 會被轉發到 -> localhost:3000/api/user/info
  axios.get('/user/info') // 不會被轉發, localhost:8080/user/info
  1. 路徑重寫:如果你不希望在代理請求時傳遞原始路徑(例如/api),可以使用pathRewrite來重寫它。這裡的^/api: ''的意思是匹配介面路徑中的/api,並將其替換為空字串
  • 在這個例子中,任何以 /api 開頭的請求路徑在轉發之前都會將 /api 部分替換為空字串。例如,如果你發起一個請求到 /api/users,那麼實際傳送到後端伺服器的請求路徑將是 /users。
  • ^:匹配字串的開始部分。
  • target 是後端的地址
  • 最後的請求路徑會是:http://localhost:3000/users
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '^/api': '' },
      },
    }
    
  1. 處理HTTPS和無效證書:預設情況下,代理不會接受執行在HTTPS上且證書無效的後端伺服器。要允許這樣的設定,可以將secure選項設定為false

    proxy: {
      '/api': {
        target: 'https://other-server.example.com',
        secure: false,
      },
    }
    
  2. 條件代理:通過一個函數判斷是否需要代理。例如,對於瀏覽器請求,你可能希望提供一個HTML頁面,而對於API請求,則希望代理它。

    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        bypass: function (req, res, proxyOptions) {
          if (req.headers.accept.indexOf('html') !== -1) {
            console.log('Skipping proxy for browser request.');
            return '/index.html';
          }
        },
      },
    }
    
  3. 多路徑代理:如果你想將多個特定路徑代理到同一個目標,可以使用具有context屬性的物件陣列。

    proxy: [
      {
        context: ['/auth', '/api'],
        target: 'http://localhost:3000',
      },
    ]
    
  4. 改變原始主機頭:代理預設保持原始的主機頭。如果需要,可以通過設定changeOrigintrue來改變這個行為。

    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
      },
    }
    

devServer設定範例

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    // 入口檔案設定
    entry: './src/index.js',

    // 輸出檔案設定
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },

    // 開發伺服器設定
    devServer: {
        contentBase: path.join(__dirname, 'dist'),
        compress: true,
        port: 9000,
        proxy: {
            // 設定代理規則 '/api'
            '/api': {
                target: 'http://localhost:3000', // 目標伺服器地址
                pathRewrite: { '^/api': '' }, // 路徑重寫,將 '/api' 替換為 ''
                secure: false, // 如果是 https 介面,需要設定為 true
                changeOrigin: true // 需要虛擬託管站點
            },
            // 你可以在這裡繼續新增更多的代理規則
        }
    },

    // 外掛設定
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ],

    // 模組設定
    module: {
        rules: [
            // 在這裡新增 loader
        ]
    }
};

在這個設定中:

  1. entryoutput 分別設定了入口和輸出檔案。

  2. devServer 是開發伺服器的設定:

    • contentBase 指定了靜態檔案的位置。
    • compress 開啟 gzip 壓縮。
    • port 設定開發伺服器的埠為 9000。
  3. devServer.proxy 是重要的代理設定部分:

    • 針對任何以 /api 開始的請求,代理規則會將請求轉發到 http://localhost:3000 上。
    • pathRewrite 將路徑中的 /api 替換為空字串,這意味著例如 /api/user 會被轉發為 http://localhost:3000/user
    • secure: false 表示接受對 https 的代理,這在目標伺服器使用自簽名證書時很有用。
    • changeOrigin: true 用於控制 Host 頭的值。如果為 trueHost 頭會被修改為目標 URL 的主機名。
  4. pluginsmodule 分別用於設定 Webpack 外掛和模組載入器。