在webpack-dev-server內添加mock server

在開發基於api交互、先後端分離的網頁應用時,常常會遇到幾個問題:前端

  • 前端頁面已經編排好了,可是後臺接口還沒準備好,或者是忽然出現Bug,這樣沒辦法進行對接測試。
  • 咱們但願服務器返回特定類型的數據,以測試某頁面在特定條件下是否存在問題,但做爲前端咱們通常不會接觸到後端代碼和數據庫,每次都找後端添加模擬數據又很麻煩。

爲解決這兩個問題,最簡單的解決辦法就是搭建一個mock server,專門返回須要的模擬數據。vue

webpack-dev-server是咱們開發vue、react時必備的工具,經過webpack-dev-serverbefore鉤子,能夠在webpack-dev-server上添加咱們須要的mock server功能,而不須要另行搭建服務器。react

在一通搜索後,我找到了這篇文章和這個webpack中間件webpack-api-mocker,只須要少量修改就能webpack-dev-server當作mock server來用,而且對同一URL下的GETPOSTPATCH等不一樣的HTTP METHOD作分別處理,支持熱切換。webpack

使用方法很簡單,在webpack.dev.conf.jsdevServer中添加新鉤子before,將全部請求交由apiMocker處理,而後當須要使用模擬數據時,只須要將請求的URL改成webpack服務器上既可。ios

npm install webpack-api-mocker --save-dev
複製代碼
const apiMocker = require('webpack-api-mocker')
config = {
  ...
  devServer: {
    before(app) { 
      apiMocker(app, path.resolve('mock/api.js'))
    }
  }
  ...
}
複製代碼

api.jsgit

const fs = require('fs');

function fromJSONFile(filename) {
    return (req, res) => {
        const data = fs.readFileSync(`mock/data/${filename}.json`).toString();
        const json = JSON.parse(data);
        return res.json(json);
    };
}
const proxy = {
    'GET /app/user/profile': fromJSONFile('profile'),
};
module.exports = proxy;
複製代碼

修改URLgithub

axios.get('user/info').then(...)
// 修改URL,加上前綴
axios.get('http://127.0.0.1:8080/' + 'user/info').then(...)
複製代碼

更進一步

通過上面的步驟,mock server已經基本能運行了,但仍是有一些不友好。每次須要使用模擬數據時,都要修改項目源碼,改寫請求的URL,在測試完畢後還得再改回來,若是該請求在源碼內有多處地方使用,那改動的地方就多了,比較麻煩。咱們能夠再進行一些改進。web

改進的思路就是開啓mock server後,將全部對api服務器的請求都發送到webpack server上,webpack server攔截並處理全部已定義有模擬數據的接口請求,而未定義的接口請求則轉發到api服務器上。數據庫

上面說的那個項目做者已經合併了個人PR,下面這段能夠不用理了,繼續用上面那個webpack-api-mockernpm

首先,咱們要對前面用到的那個中間件webpack-api-mocker進行改進,修改後的代碼在個人github上,插件主要就一個文件index.js,複製下來直接使用便可。修改了那些內容能夠看commit log

而後添加一個新的npm命令dev-mock,定義一個環境變量MOCK來控制是否開啓mock server:

"script": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
+ "dev-mock": "MOCK=true webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
}
複製代碼

webpack config中當MOCK變量存在時纔開啓mock server

config = {
  ...
  devServer: {
    if (process.env.MOCK) {
        before(app) {
          apiMocker(app, path.resolve('mock/api.js'), {
            proxy: {
              '/app//*': 'http://api.leaderlegend.com',
            }
          });
        }
    }
  }
  ...
}
複製代碼

爲了在代碼中使用環境變量MOCK,咱們要在webpack config內傳遞該值。如何傳值參考StackOverflow上的這個回答Passing environment-dependent variables in webpack

config = {
    ...
    devServer: ...
    plugins: [
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: process.env.NODE_ENV,
                MOCK: process.env.MOCK,
            }
        }),
        ...
    ]
    ...
}
複製代碼

經過判斷環境變量MOCK來肯定api服務器地址,這裏最好保持第一個path相同以更方便轉發

const BASE_URL = process.env.MOCK ? 'http://127.0.0.1:8080/app/' : 'http://api.harlanluo.com/app/';
複製代碼

到此爲止已經所有完成,須要使用模擬數據時,使用npm run dev-mock命令來運行,,不須要時則使用npm run dev,無需對項目源碼對作任何修改。

相關文章
相關標籤/搜索