Next.js で MSW をセットアップする方法
この記事では、Next.js で MSW (Mock Service Worker) をセットアップする方法を備忘録を兼ねて解説します。Next.js はブラウザとサーバーサイドの両方で実行されるため、それぞれの環境でセットアップが必要です。セットアップ方法はvercelのサンプル[1]を参考にしています。
MSWのためディレクトリ作成
設定に入る前にMSW で必要なコード群のためのディレクトリを作成します。
$ mkdir src/mocks
ハンドラーの用意
ハンドラーはモックAPIのエンドポイントに対するリクエストを処理するための関数です。
ハンドラーの設定方法はここでは割愛します。公式のドキュメント[2]を参照してください。
import { rest } from 'msw'
export const handlers = [
// ...
]
ブラウザとサーバーのインスタンス作成
次に、ブラウザとサーバーそれぞれの環境用にインスタンスを作成します。
まずブラウザ環境ではではワーカーインスタンスが必要なので、setupWorker
関数を用いて用意したハンドラーでインスタンスを作成します。
import { setupWorker } from 'msw'
import { handlers } from './handlers'
export const worker = setupWorker(...handlers)
サーバー環境ではsetupServer
関数を用いてサーバーインスタンスを作成します。
import { setupServer } from 'msw/node'
import { handlers } from './handlers'
export const server = setupServer(...handlers)
インスタンスの呼び出し
作成したインスタンスを呼び出す関数を作成します。
実行環境に必要なインスタンス以外を呼び出すとエラーが発生するため、実行環境の判定をtypeof window === 'undefined'
で行い、dynamic importにより適切なインスタンスだけが呼び出されるように実装します。
async function initMocks() {
if (typeof window === 'undefined') {
const { server } = await import('./server')
server.listen()
} else {
const { worker } = await import('./browser')
worker.start()
}
}
initMocks()
export {}
_app.tsx
でモックを起動
_app.tsx
でモックを呼び出す処理を追加します。基本的にモッキングは開発環境や試験環境でのみ行うため、環境変数でモックの有効・無効を制御するのが一般的です。
以下ではNEXT_PUBLIC_API_MOCKING という環境変数が用意されている前提でモッキングを制御します。
import { AppProps } from 'next/app'
if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') {
require('../mocks')
}
export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
単純に、 process.env.NODE_ENV === 'development' などで判定してもよいかと思います。
Service Workerの登録
最後に、ブラウザ環境ではService Workerの登録が必要なためMSW登録用のファイルを自動生成します。
$ npx msw init public/ --save
Discussion