點燈坊

失くすものさえない今が強くなるチャンスよ

使用 MSW 建立 Mock API (Vite)

Sam Xiao's Avatar 2021-05-17

建立假 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。

msw000

毫無意外執行後會 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_ENVmock 時啟動 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

msw001

Console 顯示 Mocking enabled 表示 MSW 已經成功啟動,順利從 API 取得資料並顯示。

Conclusion

  • MSW 讓我們可以在不用修改 codebase 前提下,動態切換 Mock API 與真實 API

Reference

Andy Li, Mock Service Worker: API Mocking for Vue.js Developing & Testing