在開發基於api交互、先後端分離的網頁應用時,常常會遇到幾個問題:前端
爲解決這兩個問題,最簡單的解決辦法就是搭建一個mock server,專門返回須要的模擬數據。vue
webpack-dev-server
是咱們開發vue、react時必備的工具,經過webpack-dev-server
的before
鉤子,能夠在webpack-dev-server
上添加咱們須要的mock server功能,而不須要另行搭建服務器。react
在一通搜索後,我找到了這篇文章和這個webpack中間件webpack-api-mocker,只須要少量修改就能webpack-dev-server
當作mock server來用,而且對同一URL下的GET
、POST
、PATCH
等不一樣的HTTP METHOD
作分別處理,支持熱切換。webpack
使用方法很簡單,在webpack.dev.conf.js
的devServer
中添加新鉤子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
,無需對項目源碼對作任何修改。