Next.js の App Router へ乗り換える


2023/5/5 に Next.js 13.4 がリリースされ、App Router が Stable になった。

https://nextjs.org/docs


今後は Pages Router ではなく App Router が主流になりそうな予感があるため、個人制作アプリの AwAs を移行させる。

https://github.com/yoshikouki/AwAs


ドキュメント

ドキュメントも新しくなった。正確には、beta 版だった App Router のドキュメントが統合された

The Next.js beta documentation, which has been used to explain the App Router and re-written from the ground up, is now merged back into the stable Next.js documentation. You can now easily toggle between the App or Pages Router.

Blog - Next.js 13.4 | Next.js (nextjs.org)

React Essentials (React の基礎知識)

以前から存在していたのか定かではないが、React Essentials という Next.js を扱う上で重要な知識がまとまっているドキュメントを見つけたのでメモしていく


Upgrading: Codemods | Next.js (nextjs.org)

Codemods are transformations that run on your codebase programmatically. This allows a large number of changes to be programmatically applied without having to manually go through every file.

Next.js provides Codemod transformations to help upgrade your Next.js codebase when an API is updated or deprecated.

Codemodsは、コードベース上でプログラム的に実行される変換です。これにより、すべてのファイルを手動で確認することなく、多数の変更をプログラムで適用することができます。

Next.jsは、APIが更新されたり、非推奨になったりしたときに、Next.jsのコードベースをアップグレードするのに役立つCodemod変換を提供します。

https://nextjs.org/docs/app/building-your-application/upgrading/codemods

以下のコマンドで移行ができる

npx @next/codemod <transform> <path>


ただ Pages Router → App Router への移行機能は用意されていない様子

# @next/codemod@13.4.2 で実行
$ npx @next/codemod
? On which files or directory should the codemods be applied? .
? Which transform would you like to apply? 
  name-default-component: Transforms anonymous components into named components to make sure they work with Fast Refresh 
  add-missing-react-import: Transforms files that do not import `React` to include the import in order for the new React JSX transform 
  withamp-to-config: Transforms the withAmp HOC into Next.js 9 page configuration 
  url-to-withrouter: Transforms the deprecated automatically injected url property on top level pages to using withRouter 
  cra-to-next (experimental): automatically migrates a Create React App project to Next.js 
  new-link: Ensures your <Link> usage is backwards compatible. Used in combination with experimental newNextLinkBehavior 
  next-image-to-legacy-image: safely migrate Next.js 10, 11, 12 applications importing `next/image` to the renamed `next/legacy/image` import in Next.js 13 
  next-image-experimental (experimental): dangerously migrates from `next/legacy/image` to the new `next/image` by adding inline styles and removing unused props 
❯ built-in-next-font: Uninstall `@next/font` and transform imports to `next/font` 


Upgrading: App Router Migration | Next.js (nextjs.org)

上から順にやっていけば移行できる

私の場合、


ライブラリの移行

個人制作アプリの AwAs では認証ライブラリの NextAuth、APIライブラリの rRPC を活用している。元は create-t3-app で導入したものだが、t3-app では関連するライブラリが安定対応するまでは App Router の対応 (または移行ドキュメントの作成) はしない方針だった
feat: experimental appDir option and migration guide · Issue #1364 · t3-oss/create-t3-app (github.com)


また横道に逸れる話だが、create-t3-app で作成後のアプリケーションに対してアップデートする機能を考えているようであった。AwAs が 7.4.0 で作られていて、現在が 7.13.0 なので差分が結構生まれていそう。楽しみ
feat: Add upgrade capabilities · Issue #1353 · t3-oss/create-t3-app (github.com)

(ちなみにバージョンによる差分を取れるサービスも公開されている。執筆時点では壊れているが)


NextAuth と tRPC は App Router の対応を完了しておらず、実験的に対応している Issue がいくつか立っていたりドキュメントが作られている

NextAuth

ドキュメント (APIのみ)

Issue

サンプル


以下のコミットで対応した

やったことといえば、認証用のAPIを /pages 配下から /app 配下に移動させ、 SessionProvider の引数 session を「削除した」。


意外だったのが SessionProvider を不要にする方向性が示されていたことだった

Client 側で認証が必要な操作は限定的 limited use case であるという考え方なんだろう。確かに getServerSession だけで事足りることも多いだろうが、例えばログイン状況に依ってUIを変更する場合 (例えばヘッダーのログインボタンなど) は Client Component で認証した方が直感的かつ責務が閉じているので良さそうに思える。私は必要だと判断したので構築した。


tRPC

Issue

サンプル


いくつかIssueやドキュメントを漁り、ゼロから構築を試みてみたが大変だった。結論、まだ試行錯誤中で完了していない。

そもそも SSR するのであれば tRPC を介する必要はない。AwAs の API は実質的にリクエスト検証と Service レイヤーの公開を担っているだけなので、GET リクエスト程度であれば、 SSR (RSC: React Server Component) で Service を直接呼び出す形で事足りる (リクエスト1回分を省略できるので早くもなるはず)

なので tRPC の移行が必要なのは CSR と Mutation (フォームなど) になる。

ただ Client / Server で使用する関数が異なる (内部の処理を変えている様子) ので、ここに合わせたセットアップが必要になる


#experimental_createTRPCNextAppDirClient や #experimental_createTRPCNextAppDirServer の命名から分かるとおり「実験的 experimental」な機能なので、今後破壊的な変更が加えられる可能性はある。

サンプルもいくつか出ているため、そちらを参考にセットアップしていきたいと思う (tRPC の利用を止めるという手段も考えたが、型安全なAPIを楽に実装できるメリットとのトレードオフを考えると、実験的であっても tRPC の利用を継続する方が良いと判断した)


今日はここまで

この記事が気に入ったらサポートをしてみませんか?