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

Next.js

Recruit
PRO
September 09, 2022

 Next.js

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

Recruit
PRO

September 09, 2022
Tweet

More Decks by Recruit

Other Decks in Technology

Transcript

  1. Next.js 研修
    2022年4月18日
    リクルート63期新人BC_エンジニアコース

    View Slide

  2. 講師の自己紹介
    吉井 健文
    @Takepepe / フロントエンド関連の記事書いたり
    所属:横断エンジニアリング部 ASG
    2020年10月入社、Next.js を採用したプロジェクトの
    開発支援を中心に、横断従事

    View Slide

  3. Time Table
    ■【1】MPA と SPA(30m)
    ■【2】React ハンズオン(75m)
    ■ 昼休憩(12:00 〜 13:00)
    ■【3】Next.js の基礎と概念(30m)
    ■【4】静的生成 ハンズオン(60m)
    ■ 休憩(14:30 〜 15:00)
    ■【5】動的生成 ハンズオン(30m)
    ■【6】簡単な CRUD アプリを開発(60m)
    ■ 休憩(16:30 〜 17:00)
    ■【7】現場での使われ方と最新動向(
    45m)
    【受講者の想定】TypeScript をある程度かけるが、 React を触るのは初めて
    ※ かなり詰め込んでいるので、全体的に駆け足気味の構成です

    View Slide

  4. Time Table
    ■【1】MPA と SPA(30m)
    ■【2】React ハンズオン(75m)
    ■ 昼休憩(12:00 〜 13:00)
    ■【3】Next.js の基礎と概念(30m)
    ■【4】静的生成 ハンズオン(60m)
    ■ 休憩(14:30 〜 15:00)
    ■【5】動的生成 ハンズオン(30m)
    ■【6】簡単な CRUD アプリを開発(60m)
    ■ 休憩(16:30 〜 17:00)
    ■【7】現場での使われ方と最新動向(
    45m)
    ✏ より理解しやすいよう、解説途中に手を動かすことが多いです

    View Slide

  5. Time Table
    ■【1】MPA と SPA(30m)
    ■【2】React ハンズオン(75m)
    ■ 昼休憩(12:00 〜 13:00)
    ■【3】Next.js の基礎と概念(30m)
    ■【4】静的生成 ハンズオン(60m)
    ■ 休憩(14:30 〜 15:00)
    【スライド中に出るアイコン】
    ■ <- 話を聞いて ✏ <- 手を動かして ✅ <- 理解に自信がなければ質問して
    ■【5】動的生成 ハンズオン(30m)
    ■【6】簡単な CRUD アプリを開発(60m)
    ■ 休憩(16:30 〜 17:00)
    ■【7】現場での使われ方と最新動向(
    45m)

    View Slide

  6. MPA と SPA の比較と、なぜ SPA を
    採用する機会が増えてきているのか説明します。
    第1章 MPA と SPA

    View Slide

  7. 第1章 MPA と SPA
    WEB 3層構造。WEB アプリケーション構築における標準的なシステム構成。
    ■ WEB サーバー
    ■ APP サーバー
    ■ DB サーバー

    View Slide

  8. 第1章 MPA と SPA
    WEB 3層構造。WEB アプリケーション構築における標準的なシステム構成。
    ■ WEB サーバー
    ■ APP サーバー
    ■ DB サーバー
    APP サーバー構築にむけ、様々な言語のフレームワークが存在しますが、
    近年、フロントエンド SPA(Single Page Application) 構築を兼ねる
    フレームワークが注目を集めています。

    View Slide

  9. 第1章 MPA と SPA
    WEB 3層構造。WEB アプリケーション構築における標準的なシステム構成。
    ■ WEB サーバー
    ■ APP サーバー
    ■ DB サーバー
    本日の題材である「Next.js」が、そのひとつです。
    TypeScript(JavaScript)でコードを書き、Node.js で稼働します。

    View Slide

  10. 第1章 MPA と SPA
    MPA(Multi Page Application)とは?
    ■ 書き換えの粒度が「ページ単位」
    ■ ページリクエストに応じ、サーバーが HTML ページをレスポンス
    ■ 複数のページで構成され、リクエストとページが1体1の関係
    SPA の対義語として用いられることが多く、
    本日の研修でも対義語として用います。

    View Slide

  11. 第1章 MPA と SPA
    MPA(Multi Page Application)とは?
    ■ 書き換えの粒度が「ページ単位」
    ■ ページリクエストに応じ、サーバーが HTML ページをレスポンス
    ■ 複数のページで構成され、リクエストとページが1体1の関係
    オリジンサーバーで処理をするとき、
    データ取得完了までレスポンス待ちになる。

    View Slide

  12. 第1章 MPA と SPA
    SPA(Single Page Application)とは?
    ■ 書き換えの粒度が「UIコンポーネント単位」
    ■ 骨格となる HTML ページを受け取るところまでは MPA と同じ
    ■ JavaScript で動的に UIコンポーネント や URL を書き換える
    ページは表示されたまま「部分的に書き換える」ため、
    データ取得中も何かしらの情報を提供できる。

    View Slide

  13. 第1章 MPA と SPA
    SPA を採用するメリット
    ■ ユーザー体験が良い:より良い体験が、サービス価値最大化に貢献
    ■ オーバーヘッドが少ない:必要に応じて、必要なデータだけを取得
    ■ 責務の分離:モノリスな MPA からの脱却

    View Slide

  14. 第1章 MPA と SPA
    SPA を採用するメリット
    ■ ユーザー体験が良い:より良い体験が、サービス価値最大化に貢献
    ■ オーバーヘッドが少ない:必要に応じて、必要なデータだけを取得
    ■ 責務の分離:モノリスな MPA からの脱却
    ✅ サービス価値最大化貢献と、システム全体最適化貢献が SPA 採用のメリット。
    🎥 参考動画 Google I/O:Core Web Vitals によるビジネス インパクト

    View Slide

  15. 第1章 MPA と SPA
    SPA を採用するメリット
    ■ ユーザー体験が良い:より良い体験が、サービス価値最大化に貢献
    ■ オーバーヘッドが少ない:必要に応じて、必要なデータだけを取得
    ■ 責務の分離:モノリスな MPA からの脱却
    「Next.js」は APP サーバーを兼ねることが可能な、 SPA 構築フレームワークです。
    コンポーネントライブラリの「 React」をベースとしています。

    View Slide

  16. UIコンポーネントライブラリの「
    React」について、
    基本的な概略を説明、実際に触れていきます。
    第2章 React ハンズオン

    View Slide

  17. 第2章 React ハンズオン
    UIコンポーネントライブラリの「 React」について
    ■ UIコンポーネントとは、ブラウザで情報を表示・操作するもの( HTML)
    ■ UIコンポーネントは、JSX で記述する
    ■ JSX は JavaScript の拡張構文で、HTML のようなタグ構文に倣っている
    ■ JavaScript -> JSX、TypeScript -> TSX
    MPA フレームワークで View を担っていた、テンプレートエンジンと責務は近い。
    Next.js 研修に最低限の理解は必要なので、手取り早く試して概念を掴みましょう

    View Slide

  18. 第2章 React ハンズオン
    【実技】CodeSandbox で試してみよう
    ✏ https://codesandbox.io/ にアクセス
     ・GitHub または Google アカウントでサインイン
     ・「Create Sandbox」を押下
     ・「React Typescript」をテンプレートから選択
    CodeSandbox は、環境構築不要・ブラウザだけで、すぐに動くコードを試せます。

    View Slide

  19. 第2章 React ハンズオン
    はじめに表示される「 App.tsx」のなかに、コードを書いていきます。
    真ん中がエディタ、右がコンパイル結果です。

    View Slide

  20. 第2章 React ハンズオン
    ✏ 「Hello Codesandbox」の文字列を編集してみよう
    ✏ 好きな HTML タグを書き、中括弧に式を書いてみよう

    View Slide

  21. 第2章 React ハンズオン
    ✏ タグを書いて、 onClick イベントのハンドラー関数を渡してみよう
    ✏ onClick ハンドラー関数に、console.log(‘hello’) を仕込んでみよう

    View Slide

  22. 第2章 React ハンズオン
    ✏ 書いた タグを Button 関数(コンポーネント)に切り出してみよう
    ✏ コンポーネントを 3つ並べてみよう

    View Slide

  23. 第2章 React ハンズオン
    ✏ コンポーネントに Props(引数){ value: number } を型注釈してみよう
    ✏ コンポーネント 3つに、異なる value を渡してみよう

    View Slide

  24. ✏ 配列を作り、コンポーネント内で出力してみよう(
    map 関数を使用)
    ✏ コンポーネント 3つを、map 関数出力に書き換えてみよう
    第2章 React ハンズオン

    View Slide

  25. ✏ コンポーネントを コンポーネントにリネームしよう
    ✏ コンポーネントに状態を保持し、カウントアップ機能を作り込んでみよう
    第2章 React ハンズオン

    View Slide

  26. ✏ を押下して、ニュースデータを取得、コンポーネントに表示してみよう
    https://hacker-news.firebaseio.com/v0/item/31000386.json
    第2章 React ハンズオン

    View Slide

  27. React ベースのフレームワークである Next.js の基礎を解説、
    いくつかの抑えておきたい概念を説明します。
    第3章 Next.js の基礎と概念

    View Slide

  28. 第3章 Next.js の基礎と概念
    Next.js は、React ベースのフレームワーク
    ✅ 簡単に SPA 開発が始められる
    ✅ 素早く SPA 開発が進められる
    ✅ 高品質な SPA を作れる

    View Slide

  29. 第3章 Next.js の基礎と概念
    ✅ 簡単に SPA 開発が始められる
    ■ Node.js がインストールされていれば、 CLI 一つでプロジェクト作成可能
    ■ 過去、整備が大変だった開発環境も、デフォルトで整備済み
     ・Webpack:バンドラー設定
     ・TypeScript:トランスパイラ設定
     ・ESLint:コードリンター設定

    View Slide

  30. 第3章 Next.js の基礎と概念
    ✅ 簡単に SPA 開発が始められる
    ■ Node.js がインストールされていれば、 CLI 一つでプロジェクト作成可能
    ■ 過去、整備が大変だった開発環境も、デフォルトで整備済み
     ・Webpack:バンドラー設定
     ・TypeScript:トランスパイラ設定
     ・ESLint:コードリンター設定
    【実技】create-next-app でプロジェクトを作ってみよう(黄色プロジェクト名は任意)
    ✏ $ npx create-next-app nextjs-sandbox --typescript --use-npm
    ✏ $ cd nextjs-sandbox && npm run dev

    View Slide

  31. 第3章 Next.js の基礎と概念
    ✅ 素早く SPA 開発が進められる
    ■ ファイルシステムベースのルーティング
     ・フォルダ構成が、そのままページルーティングになる

    View Slide

  32. 第3章 Next.js の基礎と概念
    ✅ 素早く SPA 開発が進められる
    ■ ファイルシステムベースのルーティング
     ・フォルダ構成が、そのままページルーティングになる
    ■ 規定の関数 を export すれば、フレームワークのレールに乗れる
     ・特定ページの表示(レンダリング)方法など

    View Slide

  33. 第3章 Next.js の基礎と概念
    ✅ 素早く SPA 開発が進められる
    ■ ファイルシステムベースのルーティング
     ・フォルダ構成が、そのままページルーティングになる
    ■ 規定の関数 を export すれば、フレームワークのレールに乗れる
     ・特定ページの表示(レンダリング)方法など
    【実技】ページを増やしてみよう
    ✏ $ cp pages/index.tsx pages/hello.tsx

    View Slide

  34. 第3章 Next.js の基礎と概念
    ✅ 高品質な SPA を作れる
    ■ SPA はバンドルサイズの肥大化が課題
     ・SPA はクライアントサイドの再描画が基本
     ・初回ロードするファイルが多いほど、ユーザーを待たせてしまう

    View Slide

  35. 第3章 Next.js の基礎と概念
    ✅ 高品質な SPA を作れる
    ■ SPA はバンドルサイズの肥大化が課題
     ・SPA はクライアントサイドの再描画が基本
     ・初回ロードするファイルが多いほど、ユーザーを待たせてしまう
    ■ Next.js はバンドルサイズの肥大化を避けられる
     ・ページ単位で、チャンク分割される
     ・遷移先ページで必要なファイルが、必要なタイミングで読み込まれる
    Next.js は、サイズ肥大化をあまり意識する必要がない

    View Slide

  36. 第3章 Next.js の基礎と概念
    ✅ 高品質な SPA を作れる
    ■ APP サーバーへの負荷低減
     ・ページの性質に応じて、最適な提供方法を選択できる
     ・可能なページは、事前に HTML を生成しておく、など
    重要なポイントであり、研修のメインテーマです

    View Slide

  37. 第3章 Next.js の基礎と概念
    抑えておきたい、3つの両極
    ■ 開発サーバー / 本番サーバー
    ■ ビルドタイム / ランタイム
    ■ クライアントサイド・レンダリング / サーバーサイド・レンダリング
    Next.js は、クライアント(ブラウザ)で実行されるコードだけでなく、
    サーバーで実行されるコードも含みます。

    View Slide

  38. 第3章 Next.js の基礎と概念
    開発サーバー / 本番サーバー
    ■ 開発サーバー
     ・Next.js に備わっている、開発モードのサーバー( npm run dev)
    ■ 本番サーバー
     ・Next.js プロジェクトをビルド( npm run build)
     ・ビルド後、起動した本番サーバー( npm start)

    View Slide

  39. 第3章 Next.js の基礎と概念
    ビルドタイム / ランタイム
    ■ ビルドタイム
     ・Next.js プロジェクトを、ビルドする時
    ■ ランタイム
     ・アプリの稼働中、コードが実行される時

    View Slide

  40. 第3章 Next.js の基礎と概念
    クライアントサイド・レンダリング / サーバーサイド・レンダリング
    ■ クライアントサイド・レンダリング
     ・React コードを「ブラウザ」で HTML 化、ページを書き換える
    ■ サーバーサイド・レンダリング
     ・React コードを「サーバー」で HTML 化、ブラウザに送る

    View Slide

  41. 第3章 Next.js の基礎と概念
    3種類のレンダリング( HTML生成)
    ■ CSR:クライアントサイド・レンダリング( Client-Side Rendering)
    ■ SSR:サーバーサイド・レンダリング( Server-Side Rendering)
    ■ SSG:静的サイトの生成( Static Site Generation)
    ページ単位・コンポーネント単位で、選ぶことができます。
    なぜ、これほど種類があるのでしょうか?

    View Slide

  42. 3種類のレンダリング( HTML生成)
    ✅ 表示するデータに応じて、使い分ける必要があるから
     ・ページに表示するデータは、他人と共有できるものか?
     ・ページに表示するデータは、更新頻度がどれほどか?
     ・ ページは、どの様なデータで構成されているか?
    第3章 Next.js の基礎と概念

    View Slide

  43. 第3章 Next.js の基礎と概念
    レイアウトが全く同じでも、
    サイトが提供するデータによって、
    最適なレンダリングは異なります。
    右の様なレイアウトを例えに、
    いくつかのページを見てみましょう。

    View Slide

  44. 例)ニュースサイト・TOPページの場合
    ■ A)ヘッドライン
    ■ B)カテゴリ一覧
    ■ C)トピック一覧のリンク
    全てパブリックデータであり、
    他人と共有できるものです。
    B
    A
    C
    第3章 Next.js の基礎と概念

    View Slide

  45. 例)ニュースサイト・TOPページの場合
    ■ A)ヘッドライン
    ■ B)カテゴリ一覧
    ■ C)トピック一覧のリンク
    配信経路上のキャッシュサーバー ※で
    キャッシュすることが出来ます。
    この様なページは SSG が適しています。
    ※ CDN・nginx など
    B
    A
    C
    第3章 Next.js の基礎と概念

    View Slide

  46. 例)SaaS・ダッシュボードの場合
    ■ A)プロジェクトのメトリクス
    ■ B)サブプロジェクト一覧
    ■ C)ユーザーの行動履歴
    全てパーソナルデータであり、
    他人と共有することはできません。
    B
    A
    C
    第3章 Next.js の基礎と概念

    View Slide

  47. 例)SaaS・ダッシュボードの場合
    ■ A)プロジェクトのメトリクス
    ■ B)サブプロジェクト一覧
    ■ C)ユーザーの行動履歴
    配信経路上にキャッシュできないので、
    オリジンサーバーが応答します。
    この様なページは SSR が適しています。
    B
    A
    C
    第3章 Next.js の基礎と概念

    View Slide

  48. 例)旅行・宿泊予約サイトの場合
    ■ A)キャンペーンへのリンク
    ■ B)特集ページへのリンク
    ■ C)ログインユーザー情報
    大部分はパブリックデータですが、
    一部、パーソナルデータです。
    B
    A
    C
    第3章 Next.js の基礎と概念

    View Slide

  49. 例)旅行・宿泊予約サイトの場合
    ■ A)キャンペーンへのリンク
    ■ B)特集ページへのリンク
    ■ C)ログインユーザー情報
    青い部分だけをキャッシュで返し、
    緑の部分だけを後から書き換えます。
    この様なエリアは CSR が対応します。
    B
    A
    C
    第3章 Next.js の基礎と概念

    View Slide

  50. 紹介したようにレイアウトが全く同じでも、
    プロジェクトによって最適なレンダリングが
    異なることが分かります。
    さらには、同じプロジェクトでも
    「このページはコレ・あのページはアレ」という
    見極めが必要、ということです。
    第3章 Next.js の基礎と概念

    View Slide

  51. 配信経路上のキャッシュを活用すると、
    高速・低負荷でページを提供できます。
    しかし、キャッシュできるデータは限られます。
    どの様にレンダリングするか?という判断は、
    共有キャッシュ化の判断、とも言い換えられます。
    第3章 Next.js の基礎と概念

    View Slide

  52. 「ページ単位・エリア単位」でレンダリングを選択出来れば、
    配信を最適化することができます。
    これこそが Next.js の強みであり、
    WEB サイト・アプリケーション配信のベストプラクティスです。
    第3章 Next.js の基礎と概念

    View Slide

  53. Next.js の重要な機能のうちのひとつ、
    静的生成について、手を動かしながら理解を深めます。
    第4章 静的生成 ハンズオン

    View Slide

  54. 第4章 静的生成 ハンズオン
    ページには「データ取得関数」を定義することができます
    ■ データ取得関数とは?
     ・Next.js 特有の、規程関数
     ・ページに必要なデータを、予め取得する関数
     ・pages フォルダに含まれる「ページファイル」で使う関数
      ・pages フォルダ内の .tsx ファイルは基本的に「ページファイル」扱い
    ✅ データ取得関数は、決まった名前で export する

    View Slide

  55. 第4章 静的生成 ハンズオン
    ページを静的生成するためには「 getStaticProps 関数」を使います
    ■ getStaticProps 関数とは?
     ・静的生成に必要なデータを、予め取得する関数
     ・関数はブラウザで実行されることはなく、 Node.js プロセスで実行される
    ✅ getStaticProps 関数の有無で「静的生成ページか?」を、 Next.js が自動判断

    View Slide

  56. 第4章 静的生成 ハンズオン
    【実技】getStaticProps でレンダリングしよう
    ✏ getStaticProps 関数で時刻を表示しよう
     ・getStaticProps 関数内で console.log(new Date().toISOString())
     ・npm run devでは、リクエストの度に html レスポンスが変わる
     ・npm run build && npm startでは、html レスポンスが固定
    ✅ 開発サーバー・本番サーバーでは、挙動が異なる
    ✅ 以降基本的に「本番サーバーで作業するもの 」として研修を進めます

    View Slide

  57. 第4章 静的生成 ハンズオン
    【実技】getStaticProps でレンダリングしよう
    ✏ getStaticProps 関数でデータを取得しよう
     ・hacker-news で記事タイトルを取得
     ・npm run devでは、リクエストの度に取得
     ・npm run build && npm startでは、ビルド時に取得
    ✅ 本番サーバーでは、データ取得の回数が少ない(必要な時のみ)
    ✅ 結果、ページリクエスト時にデータ取得しなくてよい -> レスポンスが速い
    ✅ 結果、APIサーバーへの負荷が少ない
    ❌ データが生成時のものに固定され、固定内容が配信される

    View Slide

  58. 第4章 静的生成 ハンズオン
    【実技】ISR を体験しよう
    ✏ revalidate オプションで「秒」を指定してみよう
     ・指定時間経過前:予め生成された HTML(キャッシュ)が返却される
     ・指定時間経過後:予め生成された HTML(キャッシュ)が返却される
      ・直後は、古い内容が返る
      ・裏側で「再生成」が試行される
      ・再生成が完了すると、次回以降リクエストは新しい内容が返る
    ✅ ページ生成後、指定経過時間を超過すると「再生成」が試行される

    View Slide

  59. 第4章 静的生成 ハンズオン
    【実技】ISR を体験しよう
    ✏ revalidate オプションを付与すると ISR(Incremental Static Regeneration)となる
     ・一定期間、古いデータ配信を許容する変わり、パフォーマンスが高まる
     ・ビルドタイムで HTML が事前生成される場合もある
     ・オンデマンドで再生成される場合もある
    ✅ revalidate オプションがあると、本番サーバーでもデータ取得が発生する
    ✅ revalidate は「一定時間古いデータを返すことを許容」できる要件に適合
    ❌ 一定期間古いデータを返すことが許容できない場合、 SSG はそもそも不向き

    View Slide

  60. 第4章 静的生成 ハンズオン
    【実技】動的ルートを参照してみよう
    ■ 動的ルートとは?
     ・path param が参照できる(url path に含まれる変数)ルート
     ・例えば /users/1 というルートは、ユーザー IDに相当する「1」が参照できる
    ✏ pages/users/[id].tsx を作ってみよう
     ・getStaticProps関数に、GetStaticProps型注釈をしてみよう
     ・引数のctx から、ctx.params.idを参照、console.log しよう

    View Slide

  61. 第4章 静的生成 ハンズオン
    【実技】getStaticPaths を使ってみよう
    ■ getStaticPaths とは?
     ・動的ルートを参照する、 getStaticProps と一緒に利用するもの
     ・ビルドタイムに「生成する・しない」 ページの数を決めるもの
     ・オンデマンドで「生成する・しない」 ページの振る舞いを決めるもの
    https://nextjs.org/docs/basic-features/data-fetching/get-static-paths

    View Slide

  62. 第4章 静的生成 ハンズオン
    【実技】getStaticPaths を使ってみよう
    ■ fallback: false とは?
     ・「オンデマンドで生成しない」指定
     ・「paths」に含まれる要素の数だけ、ビルドタイムにページ生成
     ・「paths」に含まれない path 相当ページは「404」

    View Slide

  63. 第4章 静的生成 ハンズオン
    【実技】getStaticPaths を使ってみよう
    ■ fallback: true とは?
     ・「オンデマンドで生成する」指定
     ・「paths」に含まれる要素の数だけ、ビルドタイムにページ生成
     ・「paths」に含まれない path 相当ページは「オンデマンド生成」を試行する

    View Slide

  64. 第4章 静的生成 ハンズオン
    【実技】getStaticPaths を使ってみよう
    ✏ fallback: false を試してみよう
     ・npm run build && npm startを実行、ビルドログを見てみて
     ・.next/server/pages/users/に生成されている HTML を見てみて
     ・http://localhost:3000/users/4にアクセスしてみて
    ✅ paths に対応するページが、ビルドタイムに生成されている
    ✅ paths に対応しないページは、 404 が返される

    View Slide

  65. 第4章 静的生成 ハンズオン
    【実技】getStaticPaths を使ってみよう
    ✏ fallback: true を試してみよう
     ・npm run build && npm startを実行、ビルドログを見てみて
     ・.next/server/pages/users/に生成されている HTML を見てみて
     ・http://localhost:3000/users/4にアクセスしてみて
    ✅ paths に対応するページが、ビルドタイムに生成されている
    ✅ paths に対応しないページは、 アクセスすることで生成される
    ※ ページ表示時に必要な XXX.html と、ナビゲーションに必要な XXX.json が同時に生成される

    View Slide

  66. 第4章 静的生成 ハンズオン
    【実技】静的生成まとめ
    ■ データはパブリックに共有できるものに限られる
    ■ リクエストに応じて「オンデマンドで HTML を静的生成」することが Next.js の特徴
     ・再生成契機となる、経過時間の指定ができる
     ・動的ルートも、オンデマンド生成があるため対応できる
     ・事前にすべて生成することもできる
    ✅ ビルドタイムに全ページ生成する必要がないので、ビルドが速い
    ✅ 配信データが、少し古くても良いか否かに応じて、細かく制御ができる

    View Slide

  67. Next.js の重要な機能のうちのひとつ、
    動的生成について、手を動かしながら理解を深めます。
    第5章 動的生成 ハンズオン

    View Slide

  68. 第5章 動的生成 ハンズオン
    Next.js 最大の強みは「ページ単位で」レンダリング(事前生成)を選べることです
    ■ SSG で、ビルドタイムに事前生成( getStaticProps)
    ■ ISR で、オンデマンドに事前生成 (getStaticProps)
    ■ SSR で、リアルタイムに事前生成( getServerSideProps)
    ✅ getStaticProps (SSG,ISR) / getServerSideProps (SSR) のいずれか
    🗒 SSRは Next.js に限らず、React 単体 + 簡易サーバーでも提供可能な、普遍的機能

    View Slide

  69. 第5章 動的生成 ハンズオン
    【実技】getServerSideProps を使ってみよう
    ✏ getServerSideProps でリクエスト毎の実行を確認
     ・関数内に console.log(new Date().toISOString()) を記述
     ・ブラウザから該当ページへアクセス
     ・アクセス時刻が出力されることを確認
     ・返却内容を Network タブ、Preview/Response 内訳を確認して
    ✅ リクエストのたび、生成内容が異なる
    ✅ export されているデータ取得関数で、ページのレンダリング方法が決定される

    View Slide

  70. 第5章 動的生成 ハンズオン
    【実技】getServerSideProps を使ってみよう
    ✏ getServerSideProps で header の中を確認
     ・getServerSideProps関数にGetServerSideProps型を注釈
     ・引数ctxを、console.log で出力してみて
    ✅ リクエストの内訳が、確認できる

    View Slide

  71. 第5章 動的生成 ハンズオン
    【実技】getServerSideProps を使ってみよう
    ✏ nookies で cookie の値を読み書きしよう
     ・Next.js で cookie を扱いやすくするライブラリ
     ・npm i nookiesを実行、インストール
     ・setCookie、parseCookies で値の読み書きを確認
     ・cookie 内容を Network タブ、Cookies で確認して
    ✅ クライアントに紐づいた Cookie の内容が、読み書きできる
    https://www.npmjs.com/package/nookies

    View Slide

  72. 第5章 動的生成 ハンズオン
    【実技】API Routes を使ってみよう
    ■ API Routes とは?
     ・pages/api に定義することで、Web API 定義ができる
     ・ページ出力(HTML)ではなく、JSON を返すことが一般的
     ・GET 以外に POST / PUT / DELETE などのメソッドにも対応
     ・pages と同様、ファイルシステムに則ったルーティング

    View Slide

  73. 第5章 動的生成 ハンズオン
    【実技】API Routes を使ってみよう
    ✏ JSON を返してみよう
     ・pages/api/hello.ts のファイルを確認
     ・res.status(200).json({ }) の内容を書き換えてみて
    ✏ nookies で cookie の値を読み書きしよう
     ・getServierSideProps でセットした値を読み書きしてみて
    ✅ getServerSideProps と同じように、req / res を扱える

    View Slide

  74. ORM ライブラリの Prisma を利用し DB 接続、
    簡単な記事投稿 CRUD アプリ開発を体験します。
    第6章 簡単な CRUD アプリを開発

    View Slide

  75. 第6章 簡単な CRUD アプリを開発
    【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう
    ✏ 以下のリポジトリをクローン
     ・https://github.com/recruit-tech/bootcamp-2022-nextjs
     ・docker-compose up -d で、コンテナを立ち上げる
     ・PostgreSQL が立ち上がっていることを確認

    View Slide

  76. 第6章 簡単な CRUD アプリを開発
    【実技】ORM ライブラリの Prisma を使います
    ■ Prisma ざっくり概要
     ・Prisma Schema Language(PSL)でスキーマを書く
     ・スキーマから、各言語向けの Client が生成できる
     ・スキーマから、マイグレーションファイルが生成できる
     ・TypeScript との親和性が高い
    今日の研修では Prisma 詳説はしません。予め用意したスキーマで開発を進めます。
    ※ バリデーション・脆弱性対策に関しては、本日は SKIP

    View Slide

  77. 第6章 簡単な CRUD アプリを開発
    【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう
    ✏ Prisma をセットアップしよう
     ・npm run db:migrate でマイグレーション、 seeding を実行
    ✅ リセットは npm run db:migrate:reset で

    View Slide

  78. 第6章 簡単な CRUD アプリを開発
    【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう
    ✏ Prisma Studio を使ってみよう
     ・Prisma に標準バンドルされている GUI
     ・npm run db:studio で Prisma Studio たちあげ
     ・http://localhost:5555 にアクセス
    ✅ fixture が DB に挿入されていることを確認

    View Slide

  79. 第6章 簡単な CRUD アプリを開発
    【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう
    ✏ Prisma Studio でレコードを追加してみよう
     ・Add record ボタンを押下
     ・新規内容を入力して
     ・Save 1 change ボタンを押下
    ✅ Prisma Studio で、DB を操作できます

    View Slide

  80. 第6章 簡単な CRUD アプリを開発
    【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう
    ✏ getServerSideProps で PrismaClient を使いユーザー一覧を表示しよう
     ・npm run dev で開発サーバーを再起動してみて
     ・http://localhost:3000/users にアクセスしてみて
     ・pages/users/index.tsx を開いて
     ・const users = await client.user.findMany() の型推論を確認して
    ✅ Prisma Client は schema.prisma から生成
    ✅ TypeScript の型推論が優れている

    View Slide

  81. 第6章 簡単な CRUD アプリを開発
    【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう
    ✏ getServerSideProps で PrismaClient を使いユーザー詳細を表示しよう
     ・http://localhost:3000/users/1 にアクセスしてみて
     ・pages/users/[id]/index.tsx を開いて
     ・getServerSideProps の引数 ctx から params.id を取得してみて
    ✏ 課題1:エラー「オブジェクトは 'undefined' である可能性があります」を消すには?

    View Slide

  82. 第6章 簡単な CRUD アプリを開発
    【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう
    ✏ getServerSideProps で PrismaClient を使いユーザー詳細を表示しよう
     ・id から該当ユーザーレコードを取得してみて
     ・const user = await client.user.findUnique({ where: { id: +ctx.params.id } })
    ✏ 課題2: const user: User | null の型推論を、const user: User にするためには?

    View Slide

  83. 第6章 簡単な CRUD アプリを開発
    【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう
    ✏ getServerSideProps で PrismaClient を使いユーザー詳細を表示しよう
     ・Page コンポーネントに、ユーザーの名前・ Email を表示してみて
     ・Page コンポーネントに、現在時刻を表示してみて
    ✏ 課題3: ユーザー詳細を表示してみて

    View Slide

  84. 第6章 簡単な CRUD アプリを開発
    【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう
    ✏ API Routes で値を受け取り、ユーザーレコードを追加してみよう
     ・pages/users/new.tsx を開いて
     ・入力値をどの様に form で送るか、一緒に確認していきます
     ・pages/api/users/index.ts を開いて
     ・送られた入力値でどの様にレコード作成するか、一緒に確認していきます
    ✅ ブラウザ -> DB 更新の一連の流れ
    ※ バリデーション・脆弱性対策に関しては、本日は SKIP

    View Slide

  85. 第6章 簡単な CRUD アプリを開発
    【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう
    ✏ ① API Routes で値を受け取り、ユーザーレコードを更新してみよう
    ✏ ② API Routes で値を受け取り、ユーザーレコードを削除してみよう
    ✏ ③ API Routes で適切なバリデーション、エラーレスポンスを返してみよう
    ✏ ④ ユーザー画面を参考に、記事投稿の CRUD 画面をつくってみよう
    ✏ ⑤ ユーザーAPIを参考に、記事投稿の CRUD API をつくってみよう
    ⏰ 制限時間まで、自由に作り込んでみてください※
    ※ Prisma Schema を追加・編集するのもありです

    View Slide

  86. Vercel に Next.js アプリを展開する利点を解説しつつ、
    実際に現場でどの様に使われているか説明します。
    第7章 現場での使われ方と最新動向

    View Slide

  87. 第7章 現場での使われ方と最新動向
    Next.js 現場での使われ方
    ■ Vercel は使いますか?
     ・あまり積極的に使われていません※
     ・セキュリティ要件がクリアできない
     ・インフラ構成に適合しない(構成に自由度がない)
     ・日本法人がない、サポート面が薄い、など
    ※講師の観測範囲に限ります

    View Slide

  88. 第7章 現場での使われ方と最新動向
    Next.js 現場での使われ方
    ■ SSG は使いますか?
     ・デプロイパイプラインで、 SSG するパターンはあります※
     ・完全に静的な Next.js をビルドするパターンです
     ・完全に静的な Next.js と API サーバーによる構成
    ✅ Full CSR の SPA 構築ツールとして使う
    ※ Static HTML Export による、完全に静的な出力

    View Slide

  89. 第7章 現場での使われ方と最新動向
    Next.js 現場での使われ方
    ■ ISR は使いますか?
     ・ISR はキャッシュ制御ノウハウが少ないため、利用実績はない(はず)
     ・SSR + 配信経路キャッシュで、 ISR と同等のことが出来る(※ 1)
      ・ISR の仕組みを、積極的に採用する理由がそこまでない
    ✅ 配信経路キャッシュ = Next.js 前段の CDN や nginx などのキャッシュサーバー(※ 2)
    ※1 細部に違いがあり、考慮すべき点があります / ※2 プロジェクト毎に構成は異なります

    View Slide

  90. 第7章 現場での使われ方と最新動向
    【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう
    ■ nginx は、先ほどの CRUD アプリに組み込み済みです
     ・http://localhost:3000で、Next.js 本番サーバーが起動していることを確認
     ・http://localhost:3001で、nginx が起動していることを確認
     ・nginx -> WEB / Next.js -> APP / PostgreSQL -> DB
    ✅ 先ほどの CRUD アプリは、簡素な WEB 3層構造
    ✅ nginx が Next.js の前段にたっている状態

    View Slide

  91. 第7章 現場での使われ方と最新動向
    【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう
    ✏ Cache-Control ヘッダーを設定してみよう( getServerSideProps 編)
     ・pages/users/index.tsx の getServerSideProps 関数を開いて
     ・関数内に await new Promise(resolve => { setTimeout(resolve, 1000) }) を記述※
     ・関数内に res.setHeader('Cache-Control', 'max-age=10') を記述
     ・npm run build && npm startで本番サーバーを再起動してみて
     ・http://localhost:3000/usersとhttp://localhost:3001/usersを比較してみて
    🗒 開発サーバーでは Cache-Control が強制上書きされてしまうので注意
    ※ 重いクエリが実行されていることをエミュレートするための遅延関数

    View Slide

  92. 第7章 現場での使われ方と最新動向
    【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう
    ✏ Cache-Control ヘッダーを設定してみよう( getServerSideProps 編)
     ✅ nginx からレスポンスが返ってきている事を確認

    View Slide

  93. 第7章 現場での使われ方と最新動向
    【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう
    ✏ Cache-Control ヘッダーを設定してみよう( getServerSideProps 編)
     ✅ キャッシュヒットした時、 TTFB が速い

    View Slide

  94. 第7章 現場での使われ方と最新動向
    【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう
    ✏ Cache-Control ヘッダーを設定してみよう( API Routes 編)
     ・pages/api/hello.ts の handler 関数を開いて
     ・関数内に await new Promise(resolve => { setTimeout(resolve, 1000) }) を記述
     ・関数内に res.setHeader('Cache-Control', 'max-age=10') を記述
     ・npm run build && npm startで本番サーバーを再起動してみて
     ・http://localhost:3001/api/helloとhttp://localhost:3001/api/helloを比較してみて
    🗒 開発サーバーでは Cache-Control が上書きされてしまうので注意
    ※ S3バケットに配備した、マスタデータへのアクセス数を間引くようなケースで有効

    View Slide

  95. 第7章 現場での使われ方と最新動向
    【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう
    ✏ Cache-Control ヘッダーを設定してみよう( API Routes 編)
     ✅ nginx からレスポンスが返ってきている事を確認

    View Slide

  96. 第7章 現場での使われ方と最新動向
    【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう
    ✏ Cache-Control ヘッダーを設定してみよう( API Routes 編)
     ✅ キャッシュが返ってきた時、 TTFB が速い

    View Slide

  97. 第7章 現場での使われ方と最新動向
    【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう
    ✏ Cache-Control ヘッダーを設定してみよう
    ✅ nginx プロキシキャッシュが返り、オリジンサーバーに到達していない
    ✅ 一定期間キャッシュを返す挙動が、 ISR の revalidate オプションに近い
    ※ 実際は必要に応じてキャッシュをパージするフローも必要

    View Slide

  98. 第7章 現場での使われ方と最新動向
    CDN・プロキシキャッシュは、 Next.js 特有のものではない
    ■ Cache-Control ヘッダーは構成をみて適切に
     ・利用する CDN によって、ディレクティブが微妙に異なる
     ・キャッシュしてはいけないデータに要注意
     ・「キャッシュ事故」で検索すると、これにまつわる記事を参照できる
    ✅ 配信経路上にキャッシュして良いデータか、十分注意する

    View Slide

  99. 第7章 現場での使われ方と最新動向
    Vercel + ISR は何が利点?
    ■ getStaticProps では、req がそもそも参照できない
     ・キャッシュ事故のリスクヘッジになる
    ■ 配信経路上のキャッシュ(インフラ構成)を考えなくて済む
     ・配信最適化のノウハウが、 APPコードに隠蔽されている
     ・Edge Computing など、最新のインフラ構成もすぐに試せる
    ✅ アカウント一つで、すぐに試すことができる
    ✅ Vercel が使えなくとも、配信構成の参考として役立つ

    View Slide

  100. 第7章 現場での使われ方と最新動向
    残りの時間で、Next,js 最新の動向を、
    別資料で紹介します。
    【おさらい:Next.js 公式の学習コンテンツもお勧めです】
    https://nextjs.org/learn/foundations/about-nextjs

    View Slide