0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Next.jsでSSR中にファイルを触ってはいけない

Posted at

Next.jsでSSR中にfsを触ったらエラーが起きたので整理しておきます。

Next.jsのレンダリングの方法

Next.jsがサーバーサイドでページをレンダリングする方法にはSSG (Static Site Generation), SSR (Server Side Rendering), ISR (Incremental Static Regeneration), SSG (fallback)などがあります。

SSG

ビルド時にサーバーサイドでページをレンダリングします。動的パスの場合はgetStaticPathsでパスを指定します。

SSR

リクエストがあったときにサーバーサイドでページをレンダリングします。

ISR

getStaticPathsrevalidateを指定すると適用されます。リクエストがあったときは静的なページを返しますが、revalidateで指定した期間が過ぎていたら裏で再度レンダリングします。

SSG (fallback)

getStaticPathsfallback: trueを指定すると適用されます。ビルドされていないページのパスにリクエストが来たら、その場でページをレンダリングします。

Next.jsのサーバーサイド環境は2つある

ビルド環境

next dev, next build, next startなどが動いている環境です。getStaticPathsで指定されたページのレンダリングは常にこちらで行われます。

ここではプロジェクトに含まれるすべてのファイルにアクセスできます。

自前のサーバーやコンテナ、Herokuなどでnext startで動かしている場合は常にビルド環境になります。

サーバーレスモード

next.config.jstarget: 'serverless'が指定されていると、ビルド時にページごとに単一のjsファイル (lambda) が生成されます。SSR, ISR, SSG (fallback)など、リクエスト時のレンダリングはこのlambdaを動かすことで行われます。

Vercelのドキュメントに書かれているように、原則としてlambdaからはファイルシステムにアクセスできません。webpackの設定をいじればできないことはないですが、基本的にハックの範疇なので将来的に動かなくなる可能性があります。pages/api/の下にあるAPI Routesについても、同じくファイルシステムは触ってはいけません。

サーバーレスモードはVercelやNetlifyで適用されます。

ビルド環境かサーバーレスモードかを判定するには

Vercelの場合は環境変数にCI=1が設定されていればビルド環境、されていなければサーバーレスモードです。Netlifyについては把握していませんが、少なくとも自前で環境変数をセットしておけば判定できると思います。

サーバーレスモードからファイルにアクセスするには

まずはSSRでなくSSGで対応できないか、リソースをlambdaに含められないかを検討しましょう。JSONを読みたい場合はfsから読まずにimportするなどの方法があります。

どうしてもSSR中にファイルを読みたい場合はネットワークからフェッチする必要があります。public/かS3などのストレージに置きましょう。

まとめ

VercelやNetlifyにデプロイされているNext.jsアプリケーションで、ビルド中以外にファイルシステムを触ってはいけない。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?