👾

【Mock Service Worker】Vue.jsでモックAPIを試す

2021/11/23に公開

Mock Service Worker(msw)は、Service Workerを利用したAPIのモックライブラリです。

Mock Service Workerは、主にバックエンドと切り離してフロントエンドだけを開発したい時に使えます。バックエンドのAPIの実装を待たなくても、フロントエンドだけで先に実装をすすめることが出来ます。

APIのモックライブラリはJSON Serverが有名ですが、JSON Serverと比較するとMock Service Workerは、RESTだけでなくGraphQLをサポートしていたり、HTTPサーバーの起動・停止の手順が不要なため、開発効率を上げることが出来ます。

今回はVue.jsのアプリに、Mock Service Workerを導入して試してみます。

Service Workerとは

Mock Service Workerの実装の前に、Service Workerについても軽く触れておきます。

Service Workerとは、メインのブラウザスレッドの外側で実行される特殊なJavaScriptファイルのことです。ブラウザとネットワークの間に立って、以下のような機能を実行します。

例えば、

  • ネットワークリクエストの処理
  • プッシュ通知
  • バックグラウンド同期

などです。

詳しくは、Service Workerがもつ圧倒的な力。SEO担当者は変化に適応が必要 | Moz - SEOとインバウンドマーケティングの実践情報 | Web担当者Forumが分かりやすかったです。

有名なサービスではタウンワークでも使われています。

Vue.jsのインストール

プロジェクトのディレクトリ名は「vue-msw-sample」にしました。

❯ yarn create vite

✔ Project name: … vue-msw-sample
✔ Select a framework: › vue
✔ Select a variant: › vue-ts
❯ cd vue-msw-sample
❯ yarn

Mock Service Workerのインストール

❯ yarn add -D msw

モック関連のモジュールを1つのディレクトリにまとめておきたいため、mocksディレクトリを作成します。

❯ mkdir src/mocks

リクエストハンドラーを格納するモジュールを作成します。

❯ touch src/mocks/handlers.ts

HTTPのGETメソッド/helloで、メッセージ「Hello World!」を返すようコードを書きます。

src/mocks/handlers.ts
import { rest } from 'msw'

export const handlers = [
  rest.get('/hello', (_req, res, ctx) => {
    return res(
      ctx.status(200),
      ctx.json({
        message: 'Hello World!',
      })
    )
  }),
]

Mock Service Workerは、Service WorkerでAPIリクエストをインターセプトします。そのService Workerのコードをプロジェクトの公開ディレクトリに追加します。

次のコマンドを実行し、public/mockServiceWorker.jsを生成します。

❯ npx msw init public/ --save

Vue.jsの場合、基本的にはpublicディレクトリを指定しておけば良いです。
参考: Where is my "public" directory?

Service Workerを設定・起動するためのファイルを作成します。

❯ touch src/mocks/browser.ts
src/mocks/browser.ts
import { setupWorker } from 'msw'
import { handlers } from './handlers'

export const worker = setupWorker(...handlers)

モックをランタイム中に実行するためには、アプリケーションのコードにインポートする必要があります。Vue.jsの場合はsrc/main.tsに置きます。

そしてモックの実行は開発環境のみに限定したいため、以下のように設定します。

src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { worker } from './mocks/browser'

if (process.env.NODE_ENV === 'development') {
  worker.start()
}

createApp(App).mount('#app')

次にApp.vueを編集し、メッセージ「Hello World!」を出力するようにコードを書きます。

src/App.vue
<template>
  <div>
    {{ hello.message }}
  </div>
</template>

<script lang="ts">
import { reactive, defineComponent, onMounted } from 'vue'

export default defineComponent({
  name: 'App',
  setup() {
    const hello = reactive({ message: '' })

    onMounted(async () => {
      const res = await fetch('/hello')
      hello.message = await res.json()
    })

    return { hello }
  },
})
</script>

アプリの起動

❯ yarn dev

http://localhost:3000/にアクセスします。そして、メッセージ「Hello World!」が画面に出力される事を確認できました。

Chromeの場合、ディベロッパーツールのアプリケーションタブから、Service Workerの利用を確認出来ます。

参考

https://mswjs.io/
https://developer.mozilla.org/ja/docs/Web/API/Service_Worker_API

Discussion