$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

Next.jsのpages/ディレクトリ以下にはページ用のファイル以外は置いてはならない

Next.jsではpages/ディレクトリ以下にページ用の実装ファイルを置く規約となっているが、それに追加して、このディレクトリ以下にはページ用以外のファイルは置いてはならないということが分かった。ページ用以外のファイルとは、例えばテストのファイルや共通ロジックのための実装などである。

ファイルを置くことで起こる問題と起こる理由

例えば日記サービスを考えたとして、pages/diaries.tsxのような日記一覧のページを実装するファイルがあったとする。この時、テストファイルはJestの流儀にしたがって、pages/tests/diaries.test.tsxもしくはpages/diaries.test.tsxに置きたくなる。

しかし、この時、次の問題が起こってしまう

  • Next.jsはテストファイルもページ用の実装とみなし、next build時に成果物に含めてしまう
    • .next/server/static/jfklanfkealknl/pages/diaries.test.js のようなファイルができる
  • ルーティングも機能してしまい、例えば/diaries.testのようなURLにアクセスできてしまう。ページの実装がないのでISEが返る

このようになる理由はNext.jsがpages/以下の全てのファイルをentrypointとしてwebpackでビルドしてしまうためである(このへんこのへんを参照)。webpackのentrypointとして指定されているので、next.config.jsのwebpackの設定でIgnorePluginなどを入れたとしても解決しない。

解決策

https://github.com/zeit/next.js/issues/3728 で色々と議論されている。少なくともpagesGlobPatternのような設定や、excludePatternのようなものは提供しない方向となっていそう。

解決策としては例えば以下のようなパターンがありえる。

いろいろ検討したけど、テストのために本番用のコード側を変えすぎるのは避けたい(本番用のロジックでsymlink作ったりしたくない)と考え、__pages_tests__ディレクトリを別で切ってテストを配置することにした。__pages_tests__というディレクトリ名にしたのは、pages/以下のテストしか置かないということを明示したかったためである。

最終形

pages/diaries.tsx
__pages_tests__/diaries.test.tsx