記一次駕輕就熟的前端代理落地方案

背景

前端開發在調試 api 階段,或者在 fix bug 時, 常常會遇到須要不斷切換代理環境的問題, 很讓人頭大。因此一個靈活的代理邏輯能讓你省去好幾支菸的功夫。javascript

下面記錄一次項目中代理的進化方案。前端

初始代理方案

經過環境變量來肯定代理方向環境,java

const getEndpoint = () => {
  switch (process.env.EP) {
    case 'qa':
      return 'https://qa.xxx.cn';

    case 'online':
      return 'https://xxx.cn';

    case 'dev':
      return 'https://test.xxx.cn';

    default:
      return 'http://dev2.xxx.cn';
  }
};

module.exports = {
  '/api': {
    target: endpoint,
    changeOrigin: true,
    headers: {
      Host: new URL(endpoint).hostname
    }
  }
};

react-scripts 默認生效的代理文件 /src/setupProxy.js:react

module.exports = function(app) {
  Object.entries(apiProxyConfig).forEach(([key, value]) => {
    app.use(key, proxy(value));
  });
};

這種方式,在開發環境啓動的過程當中就肯定了代理環境,且啓動後沒法改變代理環境, 除非修改環境變量,重啓服務。當業務模塊不斷增長,開發環境啓動的時間也愈來愈長,每次須要頻繁切換環境驗證 bug 時, 就會很耗時間。api

因此須要進化一下,幫咱們省一支菸的時間。瀏覽器

進化後代理方案

介紹 modheaderapp

Chrome 瀏覽器擴展,主要用來 添加/修改/刪除請求和響應頭根據URL Pattern來只對特定網站生效,等等用法。以下圖,詳見modheader網站

image-20200811131639316

原理url

經過瀏覽器對請求信息的劫持再編輯,經過讀取請求頭自定義添加的值來肯定代理的環境, 這樣就把代理環境的作成動態的,可經過瀏覽器插件自定義切換代理環境了。spa

module.exports = function (app) {
  const map = new Map();

  Object.entries(apiProxyConfig).forEach(([key, value]) => {
    app.use(key, (req, res, next) => {
      const endpoint = req.headers['x-api-endpoint'];

      if (endpoint && /^https?:\/\//.test(endpoint)) {
        let handler = null;

        if (map.has(endpoint)) {
          handler = map.get(endpoint);
        } else {
          handler = createProxyMiddleware({
            target: endpoint,
            changeOrigin: true,
            headers: {
              Host: new URL(endpoint).hostname
            },
            pathRewrite: '^/api'
          });
          map.set(endpoint, handler);
        }

        const path = req.url;
        const prefix = '/api';
        // eslint-disable-next-line no-console
        console.log(`[Proxy] /api${path} => ${endpoint}${prefix}${path}`);

        return handler(req, res, next);
      }

      return next();
    });
  });
};

多人協做

爲避免不一樣開發者重複配置 modheader ,須要將 modheader 配置推廣之,剛好modheader支持導出和導入,如圖:

image-20200811132951612

因此只需一人配置,分享連接給其餘人導入便可使用。

本地 mock 數據

本地 mock 和代理環境並存。

module.exports = function (app) {
  const mockFile = resolve(__dirname, '../mock/mock.js');

  if (existsSync(mockFile)) {
    apiMocker(app, mockFile);
  }

  const map = new Map();

  Object.entries(apiProxyConfig).forEach(([key, value]) => {
    // ...
  })
}

後記

以上方案目前徹底能知足開發需求,且方便易用。

歡迎你們評論大家業務中的前端環境代理。


更復雜的代理,推薦文章以下:

一文搞定前端代理騷操做!不再怕線上bug啦!

相關文章
相關標籤/搜索