Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Next.js 研修 2024

Avatar for Recruit Recruit
August 09, 2024

Next.js 研修 2024

2024年度リクルート エンジニアコース新人研修の講義資料です

Avatar for Recruit

Recruit

August 09, 2024
Tweet

More Decks by Recruit

Other Decks in Technology

Transcript

  1. Time Table ▪【第1章】フロントエンド開発と SPA フレームワーク(15m) ▪【第2章】Next.js の SPA(30m) ▪【第3章】Next.js の

    BFF(60m) ▪【第4章】Next.js とパフォーマンス(15m )  → 昼休憩(12:00 〜 13:00) ▪【第5章】簡単なアプリを作ってみよう( 120m )  → 後半 App Router 編(15:00 〜 18:00)
  2. 開発環境の確認 ▪ 最新の Node.js ▪ リポジトリをクローンしたら、 node_moduels をインストールしておきましょう  → $ npm

    i ✏ 研修用 GitHub リポジトリのクローンをお願いします https://github.com/recruit-tech/bootcamp-2024-nextjs
  3. 第1章 フロントエンド開発と SPA フレームワーク JSX(TSX)は、 UI コンポーネント(View)を関数で実装します ▪ 入力(Props)を与えると、出力(HTML)を得る ▪ 要素一覧、ボタン、フォームなど

    ▪ 小さい UI コンポーネントを組み上げる  → ページ相当の UI コンポーネントが出来る  → 先日の React 研修のとおり UI コンポーネント単位の開発
  4. 第1章 フロントエンド開発と SPA フレームワーク React は UI ライブラリ ▪ UI コンポーネント実装・レンダリングに特化

    ▪ ページとして提供する方法は、別途必要になる  → Web アプリケーションサーバーとしての機能は持たない UI コンポーネント単位の開発
  5. 第1章 フロントエンド開発と SPA フレームワーク MPA はリクエストごとに HTML を表示 ▪ MPA は

    SPA との対比で使用される用語  → Multi Page Application / Single Page Application ▪ 複数 の HTML ページで構成される  → サーバーが HTML をレスポンス  → 状態の復元は Cookie などを頼りに SPA・MPA の違い 画面遷移毎に「ページのリクエスト」が発生するもの HTML 画面遷移 HTML HTML 画面遷移
  6. 第1章 フロントエンド開発と SPA フレームワーク SPA は DOM を適宜書き換えることで、画面遷移 ▪ 初回レスポンスは、単一 HTML

    ▪ URL 変更(History API)に応じて JSON を非同期で取得 ▪ JSON を HTML コンテンツとして書き換え  → 仮想 DOM を更新・実 DOM に反映  → ブラウザ上で動的に HTML に反映 SPA・MPA の違い 画面遷移毎に「コンテンツの書き換え」が発生するもの HTML 画面遷移 画面遷移 JSON JSON
  7. 第1章 フロントエンド開発と SPA フレームワーク ✅ SPA/MPA の違いは「画面遷移」である ▪ SPA は画面遷移しても、ブラウザの状態が破棄されない  → 一度取得したデータ、ユーザーの状態を維持できる

    ▪ 非同期で必要なコンテンツのみをダウンロードする  → データソースアクセスが必要最小限に  → 画面遷移が高速 SPA・MPA の違い HTML 画面遷移 画面遷移 JSON JSON React は SPA のためとは限らない
  8. 第1章 フロントエンド開発と SPA フレームワーク 単一の HTML で SPA 展開するもの ▪ 典型的な

    SPA(古典的な SPA) ▪ 初期描画では不要な JavaScript バンドルのロードが発生  → FID ※1 の低下に直結 ▪ 最適化にはチューニングが必要 フレームワークを採用する利点 HTML 画面遷移 画面遷移 JSON JSON 初回ロードで大量の JavaScript バンドルファイルを取得する必要 大量のJavaScript 課題 ※1 FID(First Input Delay)コアウェブバイタルの指標の 1つ。初回入力までの遅延時間。
  9. 第1章 フロントエンド開発と SPA フレームワーク React 公式がフレームワーク使用を推奨 ※1 している ▪ 新しいアプリを作る場合になぜ推奨されるのか?  → アプリの肥大化に応じて

    FID が遅くなりがち(バンドルサイズの肥大化)  → データ取得のニーズが多様化(データ取得の然るべきタイミングと頻度)  → React に限らず、他フロントエンド実装でも同様のチューニングが必要 フレームワークを採用する利点 主にパフォーマンス観点で、フレームワークが欠かせなくなっている ※1 Can I use React without a framework? :https://react.dev/learn/start-a-new-react-project#can-i-use-react-without-a-framework
  10. 第1章 フロントエンド開発と SPA フレームワーク 複数の HTML で SPA 展開するもの ▪ Next.js、Remix、Sveltekit、Nuxt、...etc

    ▪ バンドラーを含み、ページ毎のレスポンス(ダウンロードファイル)が最適化 ▪ ページによって、動的・静的にレスポンスを選択する フレームワークを採用する利点 HTML 画面遷移 画面遷移 JSON JSON 具体的にどのようなアプローチが採用されるのか、1日の研修を通して解説します SPA フレームワーク 解決 ?
  11. 第2章 Next.js の SPA create next app を実行してみよう ▪ create next

    app とは?  → Next.js プロジェクトの雛形生成ツール ▪ $ npx create-next-app@latest 【実技】Next.js プロジェクトを作ってみよう (消す前提なので)まずは適当なディレクトリで試してみましょう
  12. 第2章 Next.js の SPA # プロジェクト名称は? ✔ What is your project

    named? … my-app # TypeScript 使う? ✔ Would you like to use TypeScript with this project? … No / Yes # ESLint(コーディング規約)使う? ✔ Would you like to use ESLint with this project? … No / Yes # Tailwind CSS(CSS フレームワーク)使う? ✔ Would you like to use Tailwind CSS with this project? … No / Yes # 「src」ディレクトリ使う? ✔ Would you like to use `src/` directory with this project? … No / Yes # 「App Router」使う? ✔ Would you like to use App Router? (recommended) No / Yes # import エイリアスは? ? What import alias would you like configured? › @/* 【実技】Next.js プロジェクトを作ってみよう
  13. 第2章 Next.js の SPA Next.js 開発サーバーを起動してみよう ▪ $ cd my-app ▪

    $ npm run dev ▪ http://localhost:3000/ を確認してみよう ▪ 「Ctrl + C」で開発サーバーを終了 【実技】Next.js プロジェクトを作ってみよう ✅ Next.js プロジェクトの準備はこれで完了!
  14. 第2章 Next.js の SPA 研修リポジトリの「lesson-1」を使用します ▪ カレントディレクトリを移動して  → $ cd lesson-1 ▪

    開発サーバーを起動して  → $ npm run dev 【実技】pages ルーティングを体験してみよう 研修リポジトリのサンプルは、 create next app で作成しました
  15. 第2章 Next.js の SPA ファイルシステムベースのルーティング ▪ フォルダ構成と命名規則で、ルーティングが決まる lesson-1/src/pages ├── about.tsx ├──

    blog │ └── [slug].tsx └── index.tsx 【実技】pages ルーティングを体験してみよう ← http://localhost:3000/about ← http://localhost:3000/blog/{slug} ← http://localhost:3000
  16. 第2章 Next.js の SPA ファイルシステムベースのルーティング ▪ 「pages」 というディレクトリに「 Page ファイル」を配備する  → pages

    ディレクトリに配備するだけで、ルーティング対象となる  → ページ相当の UI コンポーネントを export default(📌:1-1) 【実技】pages ルーティングを体験してみよう
  17. 第2章 Next.js の SPA Link コンポーネントを使用した SPA ナビゲーション ▪ import Link

    from "next/link";  → a要素のように使用。href 属性を指定する(📌:1-2) 【実技】pages ルーティングを体験してみよう
  18. 第2章 Next.js の SPA Router を使用した SPA ナビゲーション・参照 ▪ import {

    useRouter } from "next/router";  → router.push を使用すると、SPA ナビゲーションできる( 📌:1-3)  → router.query を参照すると、path パラメーターが参照できる( 📌:1-4)  → router.query を参照すると、query パラメーターが参照できる( 📌:1-5) 【実技】pages ルーティングを体験してみよう
  19. 第2章 Next.js の SPA ファイルシステムの命名規則と、 Router の使い方が基本 ▪ Link コンポーネントや Router

    を使用すると、SPA ナビゲーションができる ▪ ページルーティングは、ファイルを配置するだけ ▪ 命名規則によってリクエストパラメーターを取得できる ✅ 単純な SPA サイトなら、すぐに実装できる
  20. 第2章 Next.js の SPA 開発サーバー・本番サーバーは別物 ▪ Next.js アプリ 開発サーバーの起動  → ▪

    Next.js アプリ(本番サーバー)のビルド  → ▪ Next.js アプリ(本番サーバー)の起動  → 【実技】npm script を試してみよう
  21. 第2章 Next.js の SPA 開発サーバー・本番サーバーは別物 ▪ Next.js アプリ 開発サーバーの起動  → $ npm

    run dev ▪ Next.js アプリ(本番サーバー)のビルド  → $ npm run build ▪ Next.js アプリ(本番サーバー)の起動  → $ npm start 【実技】npm script を試してみよう 研修後半、使い分けるため注意
  22. 第2章 Next.js の SPA TypeScript の型互換エラーがある状況でビルドしてみよう ▪ const value: string =

    0; を適当に追加 ▪ $ npm run build  → 【実技】npm script を試してみよう
  23. 第2章 Next.js の SPA TypeScript の型互換エラーがある状況でビルドしてみよう ▪ const value: string =

    0; を適当に追加 ▪ $ npm run build  → Type error: Type 'number' is not assignable to type 'string'. 【実技】npm script を試してみよう 型互換エラーがあるとビルドに失敗する
  24. ESLint コーディング規約違反がある状況でビルドしてみよう ▪ (📌:1-6)の行を削除 ▪ $ npm run build  → 

    ▪ $ npm run lint eslint の実行(コーディング規約違反チェック)  →  第2章 Next.js の SPA 【実技】npm script を試してみよう
  25. ESLint コーディング規約違反がある状況でビルドしてみよう ▪ (📌:1-6)の行を削除 ▪ $ npm run build  → Type

    error: Property 'alt' is missing in type ▪ $ npm run lint eslint の実行(コーディング規約違反チェック)  → Warning: Image elements must have an alt prop 第2章 Next.js の SPA 【実技】npm script を試してみよう ESLint コーディング規約違反があるとビルドに失敗する
  26. 第3章 Next.js の BFF Web アプリケーションサーバーとしての機能 ▪ SSR(Server Side Rendering)機能  → データ取得

     → リクエスト単位の検証(認証認可)  → 正常系以外のレスポンス(リダイレクト、エラー表示) Next.js の BFF とは SSR は SEO 観点でも必要になることがある
  27. 第3章 Next.js の BFF Web アプリケーションサーバーとしての機能 ▪ Web API 機能  → データ取得・更新

     → リクエスト単位の検証(認証認可)  → クレデンシャル情報を扱う外部連携 Next.js の BFF とは 静的サイトとの大きな違い
  28. 第3章 Next.js の BFF 外部サーバー(サブシステム)との中継役を担い、永続層と接続する ▪ VPC ネットワーク内の外部サーバー(サブシステム)と疎通  → バックエンド API サーバーと疎通

     → API サーバーから取得したデータの集約(アグリゲーション) ▪ DB サーバーと疎通  → Prisma など ORM 経由で Next.js の BFF とは システム構成によって使い分けることができる
  29. 第3章 Next.js の BFF 基本 Node.js サーバーとして稼働 ▪ ランタイムは Node.js 以外も選べる(次世代の話)

     → Edge Runtime  → 今日の研修では触れません Next.js の BFF とは システム構成によって使い分けることができる
  30. 第3章 Next.js の BFF ✅ Next.js は Web アプリケーションサーバーとして利用できる ▪ 単一

    Next.js プロジェクトコードで、フロント・ BFF 実装ができる ▪ 完全に静的なサイトジェネレーターとしても利用できる Next.js の BFF とは
  31. 第3章 Next.js の BFF 動的パラメーターの取得 ▪ gSSP の引数 ctx.query から query・path

    パラメーターが参照できる( 📌:2-2) ▪ gSSP が定義されている場合、 useRouter の挙動が変わる(📌:2-3) 【実技】SSR を試してみよう getServerSideProps あり getServerSideProps なし
  32. Cookie の参照 ▪ gSSP では Cookie の読み書きができる( 📌:2-4)  → nookies(Next.js で

    Cookie を扱いやすくするライブラリ) ▪ Cookie にセットした sessionID から、session 値を参照  → session 値を使用した外部リクエストなど 第3章 Next.js の BFF 【実技】SSR を試してみよう
  33. 第3章 Next.js の BFF ✅ gSSP はページのレンダリングだけでなく、リクエスト検証が行える ▪ ログインユーザーに紐づいた情報の取得 ▪ VPC

    内のバックエンド API サーバー(サブシステム)との連携に ▪ サーバーで実行されるため、クレデンシャル情報を扱える 【実技】SSR を試してみよう
  34. 第3章 Next.js の BFF SSR では環境変数が参照できる( 📌:2-6) ▪ gSSP で取得した環境変数は、 props

    を経由すると…  → フロントでも参照できてしまう  → やってはダメ 󰢃 【実技】環境変数を参照してみよう
  35. 第3章 Next.js の BFF コンポーネントから直参照するとどうなる?( 📌:2-7) ▪ NEXT_PUBLIC_ 接頭辞を持つ環境変数は、 client JavaScript

    のバンドルに含まれる ▪ NEXT_PUBLIC_ 接頭辞を持たない環境変数の直参照は、 Hydration エラーが発生 ▪ Hydration とは?  → 1. Server で生成した DOM を HTML 文字列化(SSR/SSG)  → 2. Client で HTML 文字列を DOM に復元する処理(イベントハンドラのアタッチ)  → 1・2の DOM に差があると、エラーが起こる( Hydration エラー) 【実技】環境変数を参照してみよう
  36. 第3章 Next.js の BFF .env には種類がある ▪ .env.production というファイルを用意すると、 production モードでのみ適用

     → $ npm run build && npm start  → http://localhost:3000/check_env_in_component ▪ .env*.local という名前でファイル作成すると、優先適用  → $ echo NEXT_PUBLIC_VAR=override_public_local > .env.local  → $ npm run dev  → .gitignore にあらかじめ設定されている  → .env は git 管理されてしまうので、クレデンシャル情報は含めないこと 【実技】環境変数を参照してみよう
  37. 第3章 Next.js の BFF ✅ 環境変数定義の方法が豊富 ▪ .env ファイルを使用することで、環境変数が定義できる ▪ サーバーランタイムだけでなく、ブラウザランタイムでも参照できる

     → 「NEXT_PUBLIC_」接頭辞をつける  → 露出して問題ない定数か注意する ▪ ビルドモードによって設定を細かく指定できる ▪ 環境変数はビルドタイムで決まる  → ランタイムで決める方法もある  → https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration 【実技】環境変数を参照してみよう
  38. 第3章 Next.js の BFF API Routes とは? ▪ Next.js が提供する Web

    API の構築方法 ▪ getServerSideProps と同様にサーバーサイドの処理ができる ▪ SPA で必要になる Web API が実装できる 【実技】Web API を試してみよう
  39. 第3章 Next.js の BFF Cookie を使用した counter 実装(📌:2-8) ▪ http://localhost:3000/api/counter/memory ▪

    リクエストを送るごとにインクリメント ▪ カウントは共有される 【実技】Web API を試してみよう トップレベル変数はサーバーメモリに(実際はこんな実装はほぼしない)
  40. 第3章 Next.js の BFF Cookie を使用した counter 実装(📌:2-9) ▪ http://localhost:3000/api/counter/cookie ▪

    リクエストを送るごとにインクリメント ▪ カウントは共有されない 【実技】Web API を試してみよう getServerSideProps と同様に Cookie を扱える
  41. 第3章 Next.js の BFF ✅ API Routes はリクエスト検証付きの Web API 実装ができる

    ▪ 基本、ブラウザに表示された UI コンポーネントから利用される Web API  → 値をフォームに入力・ボタンを押下  → 値を送信する先が、 API Routes(Web API) ▪ ログインユーザーに紐づいた情報の取得 ▪ VPC 内のバックエンド API サーバー(サブシステム)との連携に ▪ サーバーで実行されるため、クレデンシャル情報を扱える 【実技】Web API を試してみよう
  42. 第3章 Next.js の BFF Next.js が Fullstack フレームワークと呼ばれる所以 ▪ SSR(getServerSideProps) ▪

    Web API(API Routes) ▪ middleware 機能もある ✅ SPA と BFF を同時に構築できる Next.js は SPA フレームワークであり、 Web アプリケーションサーバーとして利用できる
  43. チャンクファイルとは? ▪ 一塊の JavaScript バンドルファイル ▪ ビルド時に確認できる  → ページ毎の First Load

    第4章 Next.js と パフォーマンス チャンクファイルの分割 First Load JS 量がグリーンのページはバンドルサイズが十分小さく、良好なページ
  44. チャンクファイルが分割されないとどうなるのか? ▪ どのエントリーポイント(ページのリクエスト)でも、全ページ分の取得 Web サーバー 第4章 Next.js と パフォーマンス チャンクファイルの分割 画面遷移

    画面遷移 HTML 単一の HTML ファイル・JavaScript バンドルをレスポンス(古典的な SPA ) 大量のJavaScript 課題 JSON JSON /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト
  45. チャンクファイルが分割されないとどうなるのか? ▪ どのエントリーポイント(ページのリクエスト)でも、全ページ分の取得 Web サーバー 第4章 Next.js と パフォーマンス チャンクファイルの分割 画面遷移

    画面遷移 HTML つまり、ページが増えるほどアプリの起動が遅くなる 大量のJavaScript 課題 JSON JSON /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト
  46. 第4章 Next.js と パフォーマンス Next.js に限らず、SPA メタフレームワークは Web サーバーも含む ▪ リクエストに応じて、対応するページを返却

    チャンクファイルの分割 必要最低限のJavaScript 必要最低限のJavaScript 必要最低限のJavaScript /page-a /page-b /page-c /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト Web サーバー(Next.js) 分割 分割 分割
  47. 第4章 Next.js と パフォーマンス 静的ファイルだけで構成される時(静的サイトの場合)も分割される ▪ 動的ルートページを含む場合、 Web サーバー(Nginx 等)でルーティングが必要            → 分割されるため、静的サイトでも

    Next.js 採用にメリット チャンクファイルの分割 必要最低限のJavaScript 必要最低限のJavaScript 必要最低限のJavaScript /page-a /page-b /page-c /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト Web サーバー(Nginx 等) 分割 分割 分割
  48. 第4章 Next.js と パフォーマンス ✅ ブラウザに送信する JavaScript バンドルサイズはパフォーマンスに直結する ▪ Next.js に限った話ではない。

    JavaScript バンドルサイズ削減が求められる ▪ フレームワーク・ライブラリは JavaScript バンドルサイズを減らす工夫を続けている  → granular chunking  → https://web.dev/granular-chunking-nextjs/ ▪ 最新の React 19(18) で追加された Server Components は、バンドルサイズの削減に繋がる チャンクファイルの分割 午後の「App Router 編」で Server Components に触れます
  49. 第5章 簡単なアプリを作ってみよう 簡単なブログアプリのサンプルを用意しました。 まずターミナルで、ブログデータを管理する Web API サーバーを起動しましょう。 ▪ $ cd api

    ▪ $ npm start 次に別ターミナルで、ブログアプリ(Next.js)サーバーを起動しましょう。 ▪ $ cd blog-pages-router-scaffold ▪ $ npm run dev 【実技】簡単なアプリを作ってみよう Web API サーバーはDBを使用していません。 投稿記事はメモリに保持されます(再起動すると初期化される)
  50. 第5章 簡単なアプリを作ってみよう 以下のピンを検索し「記事一覧」ページを完成させましょう。 ▪ 📌:5-1 データ取得関数(@/fetchers/server)から、getPosts を import して使ってみよう ▪ 📌:5-2

    getServersideProps で取得したデータが、ターミナルにログ出力されているか確認しよう ▪ 📌:5-3 各記事へのリンクリストをレンダリングしてみよう 【実技】「記事一覧」ページを完成させよう http://localhost:3000/posts が該当 URL です
  51. 第5章 簡単なアプリを作ってみよう 以下のピンを検索し「記事詳細」ページを完成させましょう。 ▪ 📌:5-4 "as string" を消して、不正なリクエスト時にはエラーを throw するようにしてみましょう ▪

    📌:5-5 データ取得関数(@/fetchers/server)から、getPost を import して以下を書き換えてみましょう ▪ 📌:5-6 ページタイトル(title)、記事ID(slug)、本文(body)を表示してみよう ▪ 📌:5-7 「記事一覧に戻る」ボタンを追加してみよう ▪ 📌:5-8 「記事を編集する」ボタンを追加してみよう。パスは /posts/[slug]/edit です ▪ 📌:5-9 「記事を削除する」ボタンを追加してみよう ▪ 📌:5-10 データ取得関数(@/fetchers/server/deletePost)を使用して、記事を削除する処理を実装してみましょ う ▪ 📌:5-11 削除後は、記事一覧ページにリダイレクトするようにしてください 【実技】「記事詳細」ページを完成させよう http://localhost:3000/posts/example-post が該当 URL です
  52. 第5章 簡単なアプリを作ってみよう 以下のピンを検索し「記事作成」ページを完成させましょう。 ▪ 📌:5-12 「記事ID」が入力できるようにしてみよう ▪ 📌:5-13 「タイトル」が入力できるようにしてみよう ▪ 📌:5-14

    「本文」が入力できるようにしてみよう ▪ 📌:5-15 「記事一覧に戻る」ボタンを追加してみよう ▪ 📌:5-16 「新規作成」ボタンを追加してみよう ▪ 📌:5-17 「新規作成」ボタンクリック時に form がサブミットされるようにしてください 【実技】「記事作成」ページを完成させよう http://localhost:3000/posts/new が該当 URL です
  53. 第5章 簡単なアプリを作ってみよう 以下のピンを検索し「記事編集」ページを完成させましょう。 ▪ 📌:5-18 "as string" を消して、不正なリクエスト時にはエラーを throw するようにしてみましょう ▪

    📌:5-19 データ取得関数(@/fetchers/server)から、getPost をimport して以下を書き換えてみましょう ▪ 📌:5-20 「記事ID」が入力できるようにしてみよう ▪ 📌:5-21 「タイトル」が入力できるようにしてみよう ▪ 📌:5-22 「本文」が入力できるようにしてみよう ▪ 📌:5-23 「記事一覧に戻る」ボタンを追加してみよう ▪ 📌:5-24 「記事を更新」ボタンを追加してみよう ▪ 📌:5-25 「記事を更新」ボタンクリック時に form がサブミットされるようにしてください 【実技】「記事編集」ページを完成させよう http://localhost:3000/posts/example-post/edit が該当 URL です