React Router v7のブラウザ開発環境でMSWを利用する方法

こんにちは、サイオステクノロジーの遠藤です。

今回は、React Route v7のブラウザ開発環境でMSWを利用する方法について自分で導入するときに少しハマったので、備忘録的な形でまとめておこうと思います。

では始めていきましょう。

React Routerアプリを作成

まずは、React Routeのアプリを作成します。v7からviteで作成できるようになったのでviteを利用して作成しました。

❯ npm create vite@latest
Need to install the following packages:
create-vite@6.3.0
Ok to proceed? (y)

> npx
> create-vite

│
◇  Project name:
│  msw-blog
│
◇  Select a framework:
│  React
│
◇  Select a variant:
│  React Router v7 ↗

   git   Initialize a new git repository?
         Yes

  deps   Install dependencies with npm?
         Yes

作成が完了したら、ディレクトリを移動します。

cd msw-blog

MSWをインストール

MSWのインストールを行いましょう。

npm install msw@latest --save-dev

ワーカースクリプトをpublicディレクトリにコピー

MSWでは、worker scriptをアプリケーションのpulbicディレクトリに配置することでクライアント上でリクエストをキャッチできるようになります。こちらは以下の形でMSWのCLIを利用することで自分のディレクトリにコピーすることができます。

npx msw init ./public

また、以下のようにsaveフラグを付けるとpackage.jsonにpublicディレクトリのパスが記録されるようになり、mswパッケージをインストールするたびにversionに合わせたワーカースクリプトがコピーされるようになるのでおすすめです。

npx msw init ./public --save

// package.json
{
  "name": "my-app",
  "msw": {
    "workerDirectory": "./public"
  }
}

公式 : https://mswjs.io/docs/cli/init

Request handlersでモックを定義

Request handlers 関数を利用することで、モックの定義を行うことができます。まずは、mockを格納するためのディレクトリを作成しましょう。React Route v7では、呼び出し先の関係上app以下で定義しておくのが良さそうなので、app/mocksディレクトリを作成して、配置します。

mkdir app/mocks

ディレクトリを作成したら、handlers.tsを作成します。

// app/mocks/handlers.ts
import { http, HttpResponse } from 'msw'
 
export const handlers = [
  // Intercept "GET <https://example.com/user>" requests...
  http.get('<https://example.com/user>', () => {
    // ...and respond to them using this JSON response.
    return HttpResponse.json({
      id: 'c7b3d8e0-5e0b-4b0f-8b3a-3b9f4b3d3b3d',
      firstName: 'John',
      lastName: 'Maverick',
    })
  }),
]

Integrate する

ちょっと良いタイトルが思い浮かばなかったので、公式の言葉をそのまま持ってきました。要は、MSWは環境レベルで適用されるため、あらゆるフレームワーク、リクエスト ライブラリ、その他のツールと統合できるということみたいです。ブラウザで使用するか、Node.js プロセスで使用するか (またはその両方) を決めて、対応する統合モジュールを作成してアプリケーションに統合することで、どんな環境でも作成したモックを使うことができるとチュートリアルには書いてありました。今回は、ブラウザ用の統合モジュールを作成していきます。

app/mocksにbrowser.tsを作成します。

// app/mocks/browser.ts
import { setupWorker } from "msw/browser";
import { handlers } from "./handlers";

export const worker = setupWorker(...handlers);


app/entry.client.tsxを記述する

本日の本題です。React Router v7にはSpecial Filesというものがありまして、これらのファイルを利用することでアプリケーションの動きを調整することができます。

公式サイト : https://reactrouter.com/explanation/special-files#entryclienttsx

entry.client.tsxはブラウザで最初に実行されるコードを制御できるものになっており、これに先程のブラウザ用の統合モジュールを利用することでMSWを動かすことが可能になります。それではapp/entry.client.tsxに以下のコードを追記します。

// app/entry.client.tsx
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
import { HydratedRouter } from "react-router/dom";

async function enableApiMocking() {
  if (process.env.NODE_ENV !== "development") {
    return;
  }

  const { worker } = await import("~/mocks/browser");

  console.info("Starting MSW service worker...");
  return worker.start();
}

enableApiMocking().then(() => {
  startTransition(() => {
    hydrateRoot(
      document,
      <StrictMode>
        <HydratedRouter />
      </StrictMode>
    );
  });
});


そうしたら、アプリを起動して動作を確認してみましょう。

npm run dev

開発者ツールで [MSW] Mocking enabled. の文字が見えたらモックが動くようになっています。お疲れ様でした。

まとめ

今回は、React Route v7のブラウザ開発環境でMSWを利用する方法についてまとめました。React Route触りたてというのもあり、entry.client.tsxの存在に気づくまで時間がかかりましたが、この記事が誰かの助けになれば幸いです。

ではまた~

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です