前后端分離的架構(gòu)下,前端開發(fā)不全部依賴于后端的接口,當(dāng)后端服務(wù)器不可用時(shí),可以自己mock數(shù)據(jù)。

主要針對異步的ajax請求,通過把對后端服務(wù)器的請求換成對mock server的請求來實(shí)現(xiàn)。這個(gè)操作可以在3個(gè)層次來做。
1. 項(xiàng)目中的httpProxy
前端項(xiàng)目一般都會封裝一個(gè)httpProxy,進(jìn)行一些ajax的通用配置和請求、響應(yīng)的通用處理。我們可以通過切換請求域名的配置來實(shí)現(xiàn)mock server 和真實(shí)后端服務(wù)器的切換。
比如axios里,通過修改baseUrl的配置:
axios.config({
baseUrl: 'http://xxxxx.com/'
})
手動(dòng)切換成
axios.config({
baseUrl: 'http://localhost:3000/'
})
就可以把所有的請求都換成對mock server的請求了。
2.構(gòu)建時(shí)的環(huán)境變量
手動(dòng)切換的方式太過繁瑣,我們可以結(jié)合構(gòu)建時(shí)的環(huán)境變量來實(shí)現(xiàn)自動(dòng)切換。
比如,在axios的配置中這樣寫:
axios.config({
baseUrl: process.env.USE_MOCK ? 'http://xxxx.com' : ''
})
然后在啟動(dòng)的時(shí)候通過判斷命令行參數(shù),或者通過選擇的方式來切換,
inquirer.prompt({
type: 'list',
name: 'isMock',
message: '是否使用mock數(shù)據(jù)?',
choices: [
'是',
'否'
],
filter(val) {
return val === '是' ? 1 : 0;
}
}).then(answer => {
if (answer.isMock === 1) {
console.log(chalk.green('使用mock數(shù)據(jù)'));
process.env.USE_MOCK = true;
} else {
console.log(chalk.green('不使用mock數(shù)據(jù)'));
}
});
這種通過命令行參數(shù)或者手動(dòng)選擇的方式,比手動(dòng)修改代碼方便了很多,也是比較常用的方式。
3.修改hosts
除了可以修改請求的域名外,還可以通過hosts來修改域名和ip的對應(yīng)關(guān)系,不改動(dòng)代碼,只要把域名切換成后端服務(wù)器的ip或者mock server的ip就可以了。這種方式也很常用。
# localhost http://xxx.com
59.151.115.115 http://xxx.com
項(xiàng)目級別、工程級別、系統(tǒng)級別的方案都可以實(shí)現(xiàn)目標(biāo)服務(wù)器的切換。除了直接請求目標(biāo)服務(wù)器,也可以通過webpack的devServer來做轉(zhuǎn)發(fā),它支持一些url的重寫之類的功能。
如把 /aaa/bbb 轉(zhuǎn)向 /api/xxx的配置
devServer: {
proxy:{
'/aaa/bbb/': {
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: {
'^/api/xxx': ''
}
}
}
}
以上是3種mock數(shù)據(jù)的方式,最常用的還是在工程級別也就是構(gòu)建的時(shí)候做處理,而且還可以做到檢測mock server狀態(tài)并且自動(dòng)啟動(dòng)mock server。
自動(dòng)啟動(dòng)mock server
檢測mock server狀態(tài)可以通過 檢測端口占用情況
exec('netstat -ano | findstr "3000"', (err, result) => {
if(result.indexOf('LISTENING') != -1){
console.log(chalk.green('檢測到mock服務(wù)器已經(jīng)啟動(dòng)'));
}else{
console.log(chalk.blue('未啟動(dòng)mock服務(wù)器,正在啟動(dòng)中'));
startMockServer( () => {
console.log(chalk.green('mock服務(wù)器啟動(dòng)成功'));
});
}
});
而啟動(dòng)MockServer只需要執(zhí)行對應(yīng)的命令。不過MockServer啟動(dòng)后就一直阻塞在哪里,沒有返回的信息,只能通過主動(dòng)去請求的方式來判斷是否啟動(dòng)成功。
function startMockServer(callback) {
exec('npm run mock', (err, stdout) => {
if (err) {
console.log(chalk.red('mock服務(wù)器啟動(dòng)失敗'));
}
});
setTimeout(() => {
http.get({
hostname: 'localhost',
port: 3000,
path: '/'
}, (res) => {
callback();
});
}, 3000);
}
最終效果如下:


上面的文字是用的cfonts和隨機(jī)生成的配置
function generateRandomCFontsConfig() {
const fontArr = ['console', 'block', 'simpleBlock', 'simple', '3d', 'simple3d', 'chrome', 'huge'];
const font = fontArr[_.random(0,fontArr.length)];
const colorArr = ['system','black','red','green','yellow','blue','magenta','cyan','white','gray','redBright','greenBright','yellowBright','blueBright','magentaBright','cyanBright','whiteBright','candy']
const color1 = colorArr[_.random(0,colorArr.length-1)]
const color2 = colorArr[_.random(0,colorArr.length-1)]
const color3 = colorArr[_.random(0,colorArr.length-1)]
return {
colors: [color1,color2,color3],
font: font
}
}
say('ITS',{
...generateRandomCFontsConfig(),
space: false
})
總結(jié)
切換mock 服務(wù)器和真實(shí)的后端服務(wù)器,可以通過修改請求的域名或者通過修改hosts修改域名對應(yīng)的ip的方式,修改域名的方式可以結(jié)合工程構(gòu)建過程中的環(huán)境變量來實(shí)現(xiàn)自動(dòng)切換,同時(shí)webpackDevServer也支持一些請求的轉(zhuǎn)發(fā)。
工程構(gòu)建過程中可以通過檢測端口占用請求和http請求的方式 做到檢測mock server狀態(tài)和自動(dòng)啟動(dòng)mock server,使得mock 數(shù)據(jù)變得更加簡單。