建立假 API 不難,但若要在 API Function 不修改前提下建立 Mock API,等 API 建立好後無痛接上就有挑戰性,Mock Service Worker 讓我們可以在不修改 Codebase 前提下無痛切換 Mock API。
Version
Vue 3.0.11
MSW 0.28.2
Vue Project
$ yarn create @vitejs/app vue3-msw --template vue
使用 Vite 直接建立 Vue。
API Function
api/getBook.js
import axios from 'axios'
export default id => axios.get(`/book/${id}`)
如同往常一樣呼叫 API,並沒有特意回傳 JSON。
Component
App.vue
<template lang='pug'>
div
button(@click='onClick') Get Book
div {{ title }}
</template>
<script setup>
import { ref } from 'vue'
import { write } from 'vue3-fp'
import { pipe, andThen as then, path, otherwise, thunkify } from 'ramda'
import { error } from 'wink-fp'
import getBook from '/src/api/getBook'
let title = ref('')
let onClick = pipe(
thunkify(getBook)(1),
then(path(['data', 'title'])),
then(write(title)),
otherwise(error)
)
</script>
16 行
let onClick = pipe(
thunkify(getBook)(1),
then(path(['data', 'title'])),
then(write(title)),
otherwise(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/:id', (req, res, ctx) => 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 { createApp } from 'vue'
import worker from '/src/mock'
import App from './App.vue'
if (process.env.NODE_ENV === 'mock')
worker.start()
createApp(App).mount('#app')
在 main.js
引用 service worker,當 NODE_ENV
為 mock
時啟動 MSW。
NPM Script
package.json
{
"name": "vue3-msw",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"mock": "vite --mode mock"
},
"dependencies": {
"axios": "^0.21.1",
"pug": "^3.0.2",
"ramda": "^0.27.1",
"vue": "^3.0.5",
"vue3-fp": "^0.2.8",
"wink-fp": "^1.27.3"
},
"devDependencies": {
"@vitejs/plugin-vue": "^1.2.2",
"@vue/compiler-sfc": "^3.0.5",
"msw": "^0.28.2",
"util": "^0.12.3",
"vite": "^2.3.0"
},
"msw": {
"workerDirectory": "public"
}
}
第 8 行
"mock": "vite --mode mock"
以 NODE_ENV=mock
啟動 Vite。
Init File
$ npx msw init public/
在 public
目錄下建立 service worker 啟動檔。
Run MSW
$ yarn mock
啟動 Vite 與 MSW。
當執行
yarn dev
時將如往常直接呼叫 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