🔖

Next.js(App Router)でimport先が複数ある理由

2024/03/07に公開

環境

Next.js 14.1 App Routerでのお話です

時間がない方へ

App Routerを使ってるならnext/コンポーネント名をimportしておけばOK
next/dist/client/components/コンポーネント名はただのエイリアス

import先が複数ある

Next.jsを学習している際、useRouterをimportしようとしてimport先の候補が4つ存在していて、これは理解しておかないと気持ち悪いな、、、と思ったので調べてみました。

import先として示されたのは下記の4つです

// navigation
import { useRouter } from "next/navigation";
import { useRouter } from "next/dist/client/components/navigation";

// router
import { useRouter } from "next/router";
import { useRouter } from "next/dist/client/router";

「next/コンポーネント名」と「next/dist/client/components/コンポーネント名」の違い

ぷちサマリ

  • next/コンポーネント名はエイリアス
  • importするときは基本的にエイリアスを使用するべき

まず気づくのがnext/next/dist/client/componentsというディレクトリの違いです。

結論からいうと前者は後者のエイリアス(別名)となっています。
言い換えるとnext/navigationの参照先がnext/dist/client/components/navigationとなっているということです。

(以後、ちょいちょいDNSを例にしますが)IPアドレスとドメイン名の対応のように、使用者側が参照するための名前が設定されていると、参照先の具体的な格納先や実装について考慮しなくて良いというメリットがあります。
また、参照する名前に簡潔な表現を用いることで、使用者側(参照側)に認知不可が下がりより使いやすくなるというメリットもあります。

確認したいという方はVSCodeなどでimportしてみて、{ userRouter }の”useRouter”に対して定義先を確認するということをすると、具体的な実装がnext/dist/client/components/配下でなされていることが確認できます。

どちらをimportするべきか

どっちをimportしたらいいんだい?という疑問が湧いてくるかもしれません。
答えは「エイリアスであるnext/コンポーネント名の方をimoprtするようにしましょう」です。

具体的な実装を行っているnext/dist/client/components/コンポーネント名をimportするということは、Webサイトにアクセスする際にIPアドレス直打ちでアクセスするようなものです。
WebサイトをホストするサーバーのIPアドレスが変われば、また別のアドレスに変える必要があります。このような手間を回避するためにDNSという仕組みがあり、IPアドレスのエイリアスとも言えるドメイン名を使用して、利用者側はWebサイトにアクセスを行うということをします。

// アクセス可能だがユーザーフレンドリーでない
https://WebサイトをホストしているサーバーのグローバルIPアドレス/

// ドメイン名というエイリアス(別名)を使用することで人間が認識しやすい
// WebサイトをホストしているサーバーのIPアドレスが変わってもアクセスする側は気にしなくて良い
https://example.com/

将来的にNext.jsに変更が入り、具体的な実装を行っているディレクトリ構成や内容に変更が生じるかもしれません。そのような変更が生じるときにNext.jsの運営側はエイリアスの参照元だけを変更するということができ、利用者側に何らかのコードの書き換えを強制せずに済むということが実現できます。

利用者目線でみたら、Next.jsのバージョンを上げるたびに「このコンポーネントが実装されている場所に変更はないよな?」ということを気にしなくて良いというわけです。

next/navigationとnext/routerの違い

ぷちサマリ

  • next/navigationは新しいやつ、こちらが推奨
  • next/routerはPages Router用、App Routerでは使えない

これは知っている方も多そうです。
Next.jsのv12以降、ルーティングのためのコンポーネントとしてnext/navigationが推奨となりnext/routerは非推奨となりました。非推奨と表現すると使えるかも?と思うかもしれませんが、next/routerの方はそもそもApp Routerのディレクトリ構成には対応しておらず、Pages Routerのディレクトリ構成でのみ動作します。

このことは実際にApp Routerのプロジェクトでnext/routerをimportしてみると、エラーとなってしまうことで確認することができます。

import next/route error

next/router:
It's older package used in nextjs version prior to 13 and it only support pages directory. It does not contains the advanced feature offered by next/navigation

next/navigation

This is new package introduced in Nextjs 13 and it works with app directory. It provides a more modern and flexible navigation solution and it's more recommended option.

https://stackoverflow.com/questions/76285831/whats-the-difference-between-next-router-and-next-navigation

まとめ

import先はnext/コンポーネント名、それが複数あるときはPages RouterとApp Routerの違いの可能性があるので確認しよう。

Discussion