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

Next.js 研修 2024

Recruit
August 09, 2024

Next.js 研修 2024

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

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 です