🤗

インフラエンジニアがNext.jsに入門してみた#1

2024/01/12に公開

はじめに

筆者は3年目のインフラエンジニアです。
ふとした気まぐれでNext.jsを触ってみたくなり、Vercel公式のチュートリアルから入門してみました。
https://nextjs.org/learn

同様のチュートリアルは他にも書籍・ウェブに数多くありますが、Vercel公式が出しているという点で情報の信頼性と新鮮さに大きな強みがあります。
当然最新のNext.js 14とNextAuth 5に対応しています。
また、古いルーティング機能であるPage Routerではなく、Next.js 13から実装されたApp Routerが使われています。

復習も兼ねて、このチュートリアルで学んだ内容とその時の気付きを書いていきます。

チュートリアルの全容

公式チュートリアルは以下の17個の章で構成されています(2024/1/11時点)。
すべて完了するのに10時間かからない程度のボリュームです。

  1. イントロダクション (Getting Started)
  2. スタイリングの方法 (CSS Styling)
  3. フォントと画像の最適化 (Optimizing Fonts and Images)
  4. layout.tsxとpage.tsxの作成 (Creating Layouts and Pages)
  5. ページ間のナビゲーション (Navigating Between Pages)
  6. データベースのセットアップ (Setting Up Your Database)
  7. 外部データの取得 (Fetching Data)
  8. 静的レンダリングと動的レンダリング (Static and Dynamic Rendering)
  9. ストリーミング (Streaming)
  10. 部分的な事前レンダリング(Partial Prerendering)
  11. 検索ボックスとページネーション(Adding Search and Pagination)
  12. データ操作(Mutating Data)
  13. エラーハンドリング(Handling Errors)
  14. アクセシビリティの向上(Improving Accessibility)
  15. 認証機能の追加(Adding Authentication)
  16. メタデータの追加(Adding Metadata)
  17. 次のステップ(Next Steps)

https://nextjs.org/learn

章ごとの内容紹介

1. イントロダクション (Getting Started)

https://nextjs.org/learn/dashboard-app/getting-started
厳密には0章(Introduction)と1章(Getting Started)ですが、まとめて紹介します。
このチュートリアル自体の紹介とプロジェクトのセットアップ方法が書かれています。

どういうウェブアプリを作るのか

このチュートリアルでは以下の特徴を持つウェブアプリを作ります。

  • 全世界に公開されている
  • ログインページと認証機能を持つ
  • 認証機能によって保護された、顧客情報と請求情報の管理ページを持つ
  • 管理ページから顧客と請求情報を追加・編集・削除できる機能を持つ

何を学べるのか

このチュートリアルでは以下の機能(関連ライブラリまたはNext.jsの機能)を学習できます。

  • スタイリング(TailwindCSS)
  • 最適化(TailwindCSS)
  • ルーティング(App Router)
  • データベースとの連携(Vercel Postgres)
  • 検索とページネーション(Pagination)
  • データ操作(Server Actions)
  • エラーハンドリング(App Router)
  • バリデーション(Zod)
  • アクセシビリティ
  • 認証(NextAuth)
  • メタデータ(App Router)

必要環境

  • Node.js 18.17.0以上
  • Windows, Mac, またはLinux
  • GitHubアカウント
  • Vercelアカウント

また、ReactとJavaScriptを十分に理解していることが前提です。
Vercelのサンプルリポジトリからプロジェクトをセットアップしてこの章は終わりです。

2. スタイリングの方法 (CSS Styling)

https://nextjs.org/learn/dashboard-app/css-styling
この章では色々なスタイリングの方法が紹介されています。
これらのいずれかを個別に、または組み合わせて利用できます。
サンプルコードではそれぞれの方法でシンプルなボタンコンポーネントをスタイリングしてみます。
button.gif
レンダリング後のボタン

Global Styles

グローバル(アプリ全体)に適用したいスタイリングルールを一つのファイルに記載します。
Next.jsのApp Routerの場合、ファイル名とパスは/app/layout.tsxで読み込む時に指定するだけなのでどこでもいいですが、このチュートリアルでは/app/ui/global.cssに置いています。

/app/ui/global.css
.button {
  background-color: #4299e1;
  color: white;
  font-weight: bold;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  padding-left: 1rem;
  padding-right: 1rem;
  border-radius: 0.25rem;
  transition: background-color 0.2s;
}

.button:hover {
  background-color: #63b3ed;
}

後述するTailwindCSSと合わせて使うならglobal.cssの先頭に以下を記載します。

/app/ui/global.css
@tailwind base;
@tailwind components;
@tailwind utilities;

TailwindCSS

個人的に好きなやつです。
TailwindCSS特有の魔法の呪文(クラス名)をclassNameプロパティに記載してスタイルを適用します。
長所はとにかく簡単に書けることでしょうか(細かいプロパティと数字をちまちま書かなくていいので)。

以下のサンプルコードではclassNameプロパティにTailwindクラスをハードコーディングしてスタイルを適用しています。

/app/ui/button.tsx
import React from 'react';

const Button = () => {
  return (
    <button
      className="bg-blue-500 hover:bg-blue-400 text-white font-bold py-2 px-4 rounded"
    >
      {"button"}
    </button>
  );
};

export default Button;

CSS Modules

コンポーネントごとに個別でCSSファイルを作る方法です。
プロジェクトが育ってファイルが増えて複雑化しても、名前空間の衝突を避けられて整合性を保てるのが強みです。
小さいプロジェクトならコンパクトなTailwindCSSかCSS-in-JSを使えばよくて、この方法を使うメリットはないかもしれません。

/app/ui/button.module.css
.button {
  background-color: #4299e1;
  color: white;
  font-weight: bold;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  padding-left: 1rem;
  padding-right: 1rem;
  border-radius: 0.25rem;
  transition: background-color 0.2s;
}

.button:hover {
  background-color: #63b3ed;
}
/app/ui/button.tsx
import React from 'react';
import styles from './button.module.css';

const Button = () => {
  return (
    <button className={styles.button}>
      {"button"}
    </button>
  );
};

export default Button;

CSS-in-JS

styled-componentsやemotionに代表されるスタイリング方法です。
JavaScript(またはTypeScript)内にスタイル変数を定義して、その変数をJSX内の要素に渡す形でスタイリングします。
CSS Modulesと同様にコンポーネントごとにスタイルを定義できるので、グローバルな衝突を避けることができます。

以下はemotionを使ったスタイリング例です。

/app/ui/button.tsx
import React from 'react';
import { css } from '@emotion/react';

const buttonStyle = css`
  background-color: #4299e1;
  color: white;
  font-weight: bold;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  padding-left: 1rem;
  padding-right: 1rem;
  border-radius: 0.25rem;
  transition: background-color 0.2s;

  &:hover {
    background-color: #63b3ed;
  }
`;

const Button = () => {
  return (
    <button css={buttonStyle}>
      {"button"}
    </button>
  );
};

export default Button;

https://github.com/styled-components/styled-components
https://github.com/emotion-js/emotion

clsx

ちょっとジャンルが変わりますが、スタイリング方法のひとつとして紹介されています。
classNameを条件で切り替えたい場合に使うライブラリです。

以下のサンプルではTailwindCSSと併用し、親コンポーネントから渡されたstateによって表示/非表示を切り替えられるようにしています。

/app/ui/button.tsx
import React from 'react';
import clsx from 'clsx';

const Button = ({ state }) => {
  return (
    <button
      className={clsx(
        "bg-blue-500 hover:bg-blue-400 text-white font-bold py-2 px-4 rounded",
        { hidden: state } // stateがtrueの場合、"hidden"クラスが適用される
      )}
    >
      {"button"}
    </button>
  );
};

export default Button;

https://github.com/lukeed/clsx

Sass

Sass(Syntactically Awesome Style Sheets)はCSSの拡張版です。
Sassによるスタイリングルールは.sassファイルで定義します。

Sassでは通常のCSSに以下の機能が追加されています。

  • 変数
  • ネスト
  • 再利用
  • 継承
  • 演算

Sassと類似の方法としてSCSS, Less, Stylusがありますが、Sassほどポピュラーではないようです。
Developer surveys, 2017 & 2018
出典: https://soshace.com/sass-vs-less-which-css-preprocessor-to-choose-in-2019/

3. フォントと画像の最適化 (Optimizing Fonts and Images)

🚧工事中🚧

4. layout.tsxとpage.tsxの作成 (Creating Layouts and Pages)

🚧工事中🚧

5. ページ間のナビゲーション (Navigating Between Pages)

🚧工事中🚧

6. データベースのセットアップ (Setting Up Your Database)

🚧工事中🚧

7. 外部データの取得 (Fetching Data)

🚧工事中🚧

8. 静的レンダリングと動的レンダリング (Static and Dynamic Rendering)

🚧工事中🚧

9. ストリーミング (Streaming)

🚧工事中🚧

10. 部分的な事前レンダリング(Partial Prerendering)

🚧工事中🚧

11. 検索ボックスとページネーション(Adding Search and Pagination)

🚧工事中🚧

12. データ操作(Mutating Data)

🚧工事中🚧

13. エラーハンドリング(Handling Errors)

🚧工事中🚧

14. アクセシビリティの向上(Improving Accessibility)

🚧工事中🚧

15. 認証機能の追加(Adding Authentication)

🚧工事中🚧

16. メタデータの追加(Adding Metadata)

🚧工事中🚧

17. 次のステップ(Next Steps)

🚧工事中🚧

Discussion