建立假 API 不難,但若要在 API Function 不修改前提下建立 Mock API,等 API 建立好後無痛接上就有挑戰性,Mock Service Worker 讓我們可以在不修改 Codebase 前提下無痛切換 Mock API。
Version
Vue 2.6.11
MSW 0.28.2
Vue Project
$ vue create vue2-msw
使用 Vue CLI 建立 Vue。
API Function
api/getBook.js
import axios from 'axios'
export default id => axios.get(`/book/${id}`)
如同往常一樣呼叫 API,並沒有特意回傳 JSON。
Component
App.vue
<template>
<div>
<div>
<button @click='onClick'>Get Book</button>
</div>
<div>
{{ title }}
</div>
</div>
</template>
<script>
import getBook from '@/api/getBook'
let onClick = function() {
getBook(1)
.then(x => x.data)
.then(x => this.title = x.title)
.catch(console.error)
}
export default {
name: 'App',
data: () => ({
title: ''
}),
methods: {
onClick
}
}
</script>
15 行
let onClick = function() {
getBook(1)
.then(x => x.data)
.then(x => this.title = x.title)
.catch(console.error)
}
如同往常在 Vue 呼叫 API function。
毫無意外執行後會 404
error,因為 API 根本不存在。
MSW
$ yarn add --dev msw
使用 Yarn 安裝 Mock Service Worker。
Mock API
mock/getBook.js
import { rest } from 'msw'
export default rest.get('/book/1', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
'title': 'FP in JavaScript',
})
)
})
- 建立
mock
目錄,與 API function 名稱一樣也叫getBook.js
- 使用 MSW 的
rest.get()
建立 RESTFul GET API
mock/index.js
import { setupWorker } from 'msw'
import getBook from './getBook'
export default setupWorker(getBook)
在 mock
目錄下建立 index.js
,MSW 將 Mock API 交給 service worker 處理。
Main
main.js
import Vue from 'vue'
import worker from './mock'
import App from './App.vue'
Vue.config.productionTip = false
if (process.env.NODE_ENV === 'mock')
worker.start()
new Vue({
render: h => h(App),
}).$mount('#app')
在 main.js
引用 service worker,當 NODE_ENV
為 mock
時啟動 MSW。
NPM Script
package.json
{
"name": "vue2-msw",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"mock": "NODE_ENV=mock vue-cli-service serve"
},
"dependencies": {
"axios": "^0.21.1",
"core-js": "^3.6.5",
"vue": "^2.6.11"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"msw": "^0.28.2",
"vue-template-compiler": "^2.6.11"
},
"msw": {
"workerDirectory": "public"
}
}
第 9 行
"mock": "NODE_ENV=mock vue-cli-service serve"
以 NODE_ENV=mock
啟動 Vite。
Init File
$ npx msw init public/
在 public
目錄下建立 service worker 啟動檔。
Run MSW
$ yarn mock
啟動 Vite 與 MSW。
當執行
yarn serve
時將如往常直接呼叫 API,只有yarn mock
會啟動 MSW 攔截 API
Console 顯示 Mocking enabled
表示 MSW 已經成功啟動,順利從 API 取得資料並顯示。
Conclusion
- MSW 讓我們可以在不用修改 codebase 前提下,動態切換 Mock API 與真實 API
Reference
Andy Li, Mock Service Worker: API Mocking for Vue.js Developing & Testing