為了更好的分工合作战得,讓前端能在不依賴后端環(huán)境的情況下進行開發(fā),其中一種手段就是為前端開發(fā)者提供一個web容器,這個本地環(huán)境就是 mock-server。
數(shù)據(jù)mock可以有兩種思路:
- 在 client 端mock
- 在 server 端mock
第一種方式攔截了請求的發(fā)出媒抠,直接返回 mock 的數(shù)據(jù),而第二種方式請求則真實地發(fā)出咏花,只是在 server 端進行 route 攔截趴生。然而身為一名有“尊嚴”的前端怎么能去求后端呢?所以我們毫不猶豫的選擇第一種方式昏翰。
目前很多前端 mock 數(shù)據(jù)的方案的基本流程都是使用 node.js 來模擬 http 請求苍匆,配置 router 返回 mock 數(shù)據(jù)。
讓我們設(shè)想一下一個比較好的 mock-server 該有的能力:
- 與線上環(huán)境一致的接口地址棚菊,每次構(gòu)建前端代碼時不需要修改調(diào)用接口的代碼
- 所改即所得锉桑,具有熱更新的能力,每次增加/修改 mock 接口時不需要重啟 mock 服務(wù)窍株,更不用重啟前端構(gòu)建服務(wù)
- 能配合 Webpack
- mock 數(shù)據(jù)可以由工具生成不需要自己手動寫
- 能模擬 POST民轴、GET 請求
- 簡單(包括:文件結(jié)構(gòu)簡單、編寫代碼簡單)
所以接下來給大家介紹一下我自己總結(jié)下來一套使用起來比較舒服的 mock-server 解決方案球订,其中也用到了許多工具和框架后裸,在整個搭建過程中自己同時也學(xué)習(xí)了很多。
大致的主要思路:以 json-server 作為 mock 服務(wù)器冒滩, mock.js 生成 mock 數(shù)據(jù)微驶,利用 gulp + nodemon + browser-sync 監(jiān)聽 mock 文件的改動重啟 node 服務(wù),刷新瀏覽器开睡,以此達到一種相對完美的 mock-server 要求因苹。
json-server搭配mock.js
這里以 Webpack 的前端工程為例:
npm install json-server mockjs --save
在項目根目錄新建 mock 文件夾,新建 mock/db.js
作為 mock 數(shù)據(jù)源篇恒,mock/server.js
作為 mock 服務(wù)扶檐,mock/routes.js
重寫路由表。
// db.js
var Mock = require('mockjs');
module.exports = {
getComment: Mock.mock({
"error": 0,
"message": "success",
"result|40": [{
"author": "@name",
"comment": "@cparagraph",
"date": "@datetime"
}]
}),
addComment: Mock.mock({
"error": 0,
"message": "success",
"result": []
})
};
這里我們利用 mock.js 生成 mock 數(shù)據(jù)胁艰,可以盡可能的還原真實數(shù)據(jù)款筑,還可以減少數(shù)據(jù)構(gòu)造的復(fù)雜度。
// routes.js
module.exports = {
"/comment/get.action": "/getComment",
"/comment/add.action": "/addComment"
}
我們可以通過路由表的配置實現(xiàn)復(fù)雜的路由配置腾么,詳細配置規(guī)則
// server.js
const jsonServer = require('json-server')
const db = require('./db.js')
const routes = require('./routes.js')
const port = 3000;
const server = jsonServer.create()
const router = jsonServer.router(db)
const middlewares = jsonServer.defaults()
const rewriter = jsonServer.rewriter(routes)
server.use(middlewares)
// 將 POST 請求轉(zhuǎn)為 GET
server.use((request, res, next) => {
request.method = 'GET';
next();
})
server.use(rewriter) // 注意:rewriter 的設(shè)置一定要在 router 設(shè)置之前
server.use(router)
server.listen(port, () => {
console.log('open mock server at localhost:' + port)
})
現(xiàn)在打開 terminal 輸入命令
$ node mock/server.js
打開 http://localhost:3000/comment/get.action 即可查看到我們想要的數(shù)據(jù):
是不是這樣就算搭建完了我們的 mock-server 奈梳?不,并沒有解虱。我們可以嘗試修改一下 db.js 的文件內(nèi)容攘须,刷新瀏覽器發(fā)現(xiàn) mock 數(shù)據(jù)并沒有像我們想象的那樣修改。那也就是說每次當(dāng)我們需要添加/修改 mock 數(shù)據(jù)使都需要重啟一次 mock 服務(wù)殴泰。What 于宙??艰匙?
除此之外我們還需要進行端口代理限煞,以至于不與 Webpack 的構(gòu)建端口產(chǎn)生跨域。
端口代理
通過 Webpack 配置 proxy 代理:
module.exports = {
...
devServer: {
//其實很簡單的员凝,只要配置這個參數(shù)就可以了
proxy: {
'/api/': {
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
接著在代碼里進行 ajax 請求就可以寫成署驻,這里以 axios 為例子:
function getComments () {
axios.get('api/comment/get.action', {}).then((res) => {
console.log(res.data)
})
}
文件改動自動刷新
我們希望更改 mock 文件能和 webpack 熱更新一樣,所改即所得健霹。這里我使用了 nodemon旺上,利用 gulp 建立自動執(zhí)行的任務(wù)。
npm install gulp gulp-nodemon browser-sync --save
gulpfile.js 的代碼如下:
const path = require('path');
const gulp = require('gulp');
const nodemon = require('gulp-nodemon');
const browserSync = require('browser-sync').create();
const server = path.resolve(__dirname, 'mock');
// browser-sync配置糖埋,配置里啟動nodemon任務(wù)
gulp.task('browser-sync', ['nodemon'], function() {
browserSync.init(null, {
proxy: "http://localhost:8080", // 這里的端口和webpack的端口一致
port: 8081
});
});
// browser-sync 監(jiān)聽文件
gulp.task('mock', ['browser-sync'], function() {
gulp.watch(['./mock/db.js', './mock/**'], ['bs-delay']);
});
// 延時刷新
gulp.task('bs-delay', function() {
setTimeout(function() {
browserSync.reload();
}, 1000);
});
// 服務(wù)器重啟
gulp.task('nodemon', function(cb) {
// 設(shè)個變量來防止重復(fù)重啟
var started = false;
var stream = nodemon({
script: './mock/server.js',
// 監(jiān)聽文件的后綴
ext: "js",
env: {
'NODE_ENV': 'development'
},
// 監(jiān)聽的路徑
watch: [
server
]
});
stream.on('start', function() {
if (!started) {
cb();
started = true;
}
}).on('crash', function() {
console.error('application has crashed!\n')
stream.emit('restart', 10)
})
});
這樣以后我們在構(gòu)建我們 Webpack 工程時只需要先執(zhí)行
$ npm run dev
之后新建 terminal 執(zhí)行
$ gulp mock
就可以搭建一個隨改隨變的 mock-server 環(huán)境宣吱,再也不用看后臺的臉色啦~
如果有任何問題歡迎留言
個人的 vue-starter-kit 項目也采用了這種 mock 方案,如果有需要也可以參考瞳别,歡迎 star