モード変更


    言語

[NextJS13] Layout RFC発のアップデート機能紹介!

2022/12/08

10 月 25 日に第 6 回 Next.js カンファレンスが開催され、Rust ベースのバンドラーであるTurbopack、Server component を実装した app ディレクトリ、既存コンポーネントのアップデート等が紹介されました!

Next.js conference

今回の大型アップデートの一つである app ディレクトリは数年前から議論がなされてきたLayout RFCの一つであり、 Layout RFC には app ディレクトリやそれに合わせて今回のアップデートで紹介された機能が含まれております。 本記事ではそのいくつかを紹介いたします。

app ディレクトリは beta 版ではありますが Layout RFC で議論されてきた内容が反映されており、 割と大きな変更であるため本記事を見てまず概要を抑えていただければと思います。

NOTE

  • この記事は Next.js を触ったことがある方向けです。
  • Layout RFC の中で特に大きく変更のあるものについて書いてます、全てではありません。

そもそも Layout RFC って?

Next.js の共同開発者である Tim Nuekens 氏により 2016 年からGithub discussionで話し合いがされている RFC(Request for comments)です。

2022 年 5 月にこちらで概要が発表されています。

それでは早速中身を見てみましょう!

ルーティング

新たなルートとして appディレクトリが追加されました。

大きな違いとして、従来の page ディレクトリでは、ファイル名からパスが生成されていましたが、app ディレクトリではディレクトリ名をもとにパスが生成されるようになります。

従来パターン

ルート:pages

pages/index.js → /

pages/dashboard/index.js → /dashboard

pages/dashboard/settings.js → /dashboard/settings

スクリーンショット 2022-10-11 22.19.55.webp

app ディレクトリパターン

ルート:app

app/page.js → /

app/dashboard → /dashboard

app/dashboard/settings → /dashboard/settings

スクリーンショット 2022-10-11 22.19.55.webp

この通り、フォルダ内がそのままルートパスになります。

かなり大きな変更ではありますが、app ディレクトリは pages ディレクトリと並行して利用できるため、今回の RFC が実装されたとしても、従来の方法で使用されている pages ディレクトリには大きく影響がないと思われます。

命名規約に沿ったファイルの作成

上の appディレクトリの場合に疑問に思った方もいらっしゃると思いますが、ディレクトリ名でパスが決まるのであればファイル名はどうしたら良いのでしょうか?

RFC によると各ディレクトリ下のファイルはその名前によって機能が定義されてます。

RFC では以下のファイル名が定義の対象とされてます。

  • page.js
    • ディレクトリパスが呼ばれた際に読み込まれるページコンポーネント
  • layout.js
    • ディレクトリパスが呼ばれた際にディレクトリ下で有効なレイアウトコンポーネント
  • loading.js
    • ディレクトリパスが呼ばれた際のフォールバック用コンポーネント
  • error.js
    • エラーが返された場合に遷移されるコンポーネント

page.jsやlayout.jsについてもう少し詳しく見てみましょう。

page.js

page.js は従来の Next.js において各ページディレクトリで定義されていたindex.js に近い分類ですが、大きく違う点は page.js ではReact18 で新たに実装された、server component がデフォルトで適応される点です。(下記で紹介しています。)

従来パターン

indexjs.webp

RFC パターン

pagejs.webp

layout.js

layout.js も元々存在している layout コンポーネントですが、今回の実装でネスト化されたルート内のみにレイアウトを適応することが可能となりました。

従来のレイアウトコンポーネント

layout_component_1.webp

ネスト化されたレイアウトコンポーネント

nested_layout.webp

React server component がデフォルトで実装

app ディレクトリ下で使用されるpage.js では React18 で新たに実装された server component がデフォルトで適応されます。

これによりpage.js で定義されたコンポーネントはサーバー側で server component としてレンダーされるようになります。

React server component についてはこちらの記事で詳しく説明されています。(日本語)

React 公式サイトでデモも紹介されています。(英語)

React18 では.server.js , .client.js と拡張子によって各機能を定義するようにしており、Next.js ではpage.jsに .client を追加することで client component として使用可能です。


page.js → server component (e.g. dashboard/page.js)

page.client.js → client component(e.g. dashboard/page.client.js)


ちなみに、従来の page ディレクト下では server component を使用することはできません。

server component を使用したい場合は新たに appディレクトリを作成する必要があります。

https://nextjs.org/blog/layouts-rfc#server-components-as-the-default

Data fetching

従来のpages ディレクト下ではページ単体で制限されていた Data fetching が今回のアップデートでlayout.js でも呼び出しが可能となりました。

以下のようなフォルダ構成の場合、blog/layout.js でカテゴリーを Fetch し、サイドバーとして Render させ、blog/[slug]/page.js で blog データを Fetch、Render するような形が可能となります。

app
|_blog
 |_layout.js // カテゴリーデータをフェッチし、サイドバーがレンダーされる
 |_[slug]
  |_page.js; // ブログデータをフェッチし,コンテンツがレンダーされる
// app/blog/layout.js
export async function getStaticProps(){
  const categories = await getCategoriesFromCMS();

  return {
    props: { categories };
  }
}

export default function BlogLayout({ categories, children }){
  return (
    <>
      <BlogSidebar categories={categories} />
      {children}
    </>
  )
}
// app/blog/[slug]/page.js
export async function getStaticPaths() {
  const posts = await getPostSlugsFromCMS();

  return {
    paths: posts.map(post => ({
      params: { slug: post.slug },
    })),
  };
}

export async function getStaticProps({ params }) {
  const post = await getPostFromCMS(params.slug);

  return {
    props: { post },
  };
}

export default function BlogPostPage({ post }){
  return <Post post={post>
}

また、上記の場合app/blog/[slug]全体のルートが React server component としてビルド時に静的に生成され、クライアント側では server component で生成された静的なスナップショットを読み込むだけとなるためクライアント側で実行される JavaScript の量が更に少なくなりより早くページがインタラクティブな状態となります。

最後に

以上大まかではありますが、今回のアップデートで紹介された Layout RFC の機能をいくつか紹介させていただきました。

Layout RFC では上記以外にもルートのグループ化やエッジケースに対応したルートパターンなど紹介されていますので一読されることをお勧めします。

今回紹介させていただいた機能は NextJS13 のアップデートの一部であり、 Turbopack 等の紹介は割愛しておりますのでアップデートの詳細等は下記公式サイトからご確認ください。

参考

NextJS13:

https://nextjs.org/blog/next-13

NextJS13 へアップグレードしたい方

Upgrade guide

出典

Photo source:

NextJS Layout RFC

frontendnextjsreact

Author

Go Nakano

Go Nakano

Frontend engineer

Engineer/ ex-overseas sales(non-IT)

その他おすすめ記事

2024/11/05

エンタープライズデータ基盤における dbt の活用戦略

近年、データ駆動型の意思決定が企業の競争力を左右する重要な要素となっており、大規模かつ複雑なデータ基盤の構築が不可欠となっています。この潮流の中で、dbt(data build tool)は、エンタープライズレベルのデータ変換とモデリングを効率化する強力なツールとして注目を集めています。 dbt は、SQL を使用してデータ変換を定義し、バージョン管理、テスト、ドキュメンテーションを統合的に行うことができるオープンソースツールです。特に以下の点で、エンタープライズデータ基盤の構築に大きな価値をもたらします...

Yoshiaki Sano

Yoshiaki Sano

Architecture

2024/11/04

データエンジニアリング初心者でも分かる!dbtの魅力と基本

データ駆動型ビジネスが当たり前となった今日、多くの企業がデータ分析の課題に直面しています。複雑な SQL クエリの管理、データの整合性確保、分析プロセスの再現性など、様々な問題が山積みです。そんな中で注目を集めているのが「dbt(data build tool)」です。 本記事では、データエンジニアリングの深い知識がなくても理解できるよう、dbt の基本と魅力について解説します。 dbt とは? dbt は、SQL を中心としたデータ変換ワークフローを管理するためのオープンソースツールです。従来の SQL...

Yoshiaki Sano

Yoshiaki Sano

Architecture

サービス開発実績会社情報
採用情報インサイトお問い合わせ
© 2022 Monstarlab
情報セキュリティ基本方針個人情報の取り扱いについて個人情報保護方針