😇

Next.js 13.5.6でMSWを使う際のハマりどころと解決法

2024/03/15に公開

はじめに

以前勤めていた会社では、Next.js 13.5.6 を用いて開発しており、モックサーバには MSW 1.3.2を利用しています。
今回は、この MSW を動かすのに1日ほど時間を溶かしてしまったので、備忘録も兼ねて解決法を残します!

開発環境

  • nextjs@13.5.6
  • msw@1.3.2
  • @mswjs/interceptors@0.17.10
  • node-fetch@2.7.0

ハマりどころ

Next.js 13 と MSW を利用しているエンジニアにとってはご存じの方も多いかもしれませんが、この2つは相性が良くありません・・・
具体的に言うと、SSRを用いて MSW で用意したAPIを叩いてもmsw/interceptorが動作しないので、結果を取得することができません😭
issueの情報を参考に、藁にもすがる思いでmsw/interceptorを最新にアップデートしたり、MSW v2に更新したりしましたが解決には至りませんでした・・・

※ この辺りの問題は、開発者側も既知であり、Next.js 14では諸々対応されるようです。
https://github.com/mswjs/msw/issues/1743

解決法

色々試しているうちに、undiciに対して割り込みが動作していないことが分かったので、弊社ではfetchをラップした関数を用意する方法で解決しました!
こうすることで、CSRでもSSRでも問題無くmsw/interceptorが動作します。

export function wrappedFetch(url: string, options?: RequestInit): Promise<any> {
  if (!isBrowser()) {
    const fetch = require('node-fetch');

    return fetch(url, options);
  }

  return fetch(url, options);
}

※1 mswjs/http-middlewareを用いることも考えましたが、準備が面倒なのでやめました
※2 上記のコードであれば、cross-fetchisomorphic-unfetchを用いれば良いはずなのですが、何故か動作が不安定だったので以下のようにしています・・・謎すぎる・・・

まとめ

MSW v1は、Next.js 13のSSRをサポートしていないので、このような小細工を弄することで動かすことに成功しました・・・
色々なissueを調べてみると、msw/interceptorをアップデートしたら動いたよ!と言っている方もおられたので、パッケージの依存関係のバージョンでも左右されるのかもしれません。
MSW v2以降では、Next.js 14以上に対してSSRをサポートすると明言されているので、今後はこちらに期待していきたいと思います!

Discussion