Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Next.js
Search
Recruit
PRO
September 09, 2022
Technology
28
21k
Next.js
2022年度リクルート エンジニアコース新人研修の講義資料です
Recruit
PRO
September 09, 2022
Tweet
Share
More Decks by Recruit
See All by Recruit
Flutterによる 効率的なAndroid・iOS・Webアプリケーション開発の事例
recruitengineers
PRO
0
73
VPC Traffic Mirroring とOSS を利⽤した ネットワークフォレンジック基盤の構築・運⽤
recruitengineers
PRO
1
44
スタサプ ForSCHOOLアプリのシンプルな設計
recruitengineers
PRO
3
1k
リクルート流データ基盤塾~鶴谷と学ぶ~
recruitengineers
PRO
5
240
『SUUMO』 スマホサイト デザインリニューアルへの挑戦
recruitengineers
PRO
5
340
『リクルートダイレクトスカウト』 のリニューアルから振り返る: ビジョンドリブンの可能性
recruitengineers
PRO
3
310
負債あるモノリスのオブザーバビリティに組織で向き合う
recruitengineers
PRO
9
400
あなたの知らないiOS開発の世界
recruitengineers
PRO
4
330
大規模プロダクトにおける組織作りと技術ポートフォリオマネジメント
recruitengineers
PRO
4
490
Other Decks in Technology
See All in Technology
複雑なState管理からの脱却
sansantech
PRO
1
140
テストコード品質を高めるためにMutation Testingライブラリ・Strykerを実戦導入してみた話
ysknsid25
7
2.6k
Lambdaと地方とコミュニティ
miu_crescent
2
370
EventHub Startup CTO of the year 2024 ピッチ資料
eventhub
0
110
誰も全体を知らない ~ ロールの垣根を超えて引き上げる開発生産性 / Boosting Development Productivity Across Roles
kakehashi
1
220
サイバーセキュリティと認知バイアス:対策の隙を埋める心理学的アプローチ
shumei_ito
0
380
Terraform CI/CD パイプラインにおける AWS CodeCommit の代替手段
hiyanger
1
240
Lexical Analysis
shigashiyama
1
150
いざ、BSC討伐の旅
nikinusu
2
780
rootlessコンテナのすゝめ - 研究室サーバーでもできる安全なコンテナ管理
kitsuya0828
3
380
AWS Media Services 最新サービスアップデート 2024
eijikominami
0
190
隣接領域をBeyondするFinatextのエンジニア組織設計 / beyond-engineering-areas
stajima
1
270
Featured
See All Featured
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.2k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
120
Gamification - CAS2011
davidbonilla
80
5k
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.8k
Rails Girls Zürich Keynote
gr2m
94
13k
A Tale of Four Properties
chriscoyier
156
23k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
28
2k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3k
Bash Introduction
62gerente
608
210k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
It's Worth the Effort
3n
183
27k
Transcript
Next.js 研修 2022年4月18日 リクルート63期新人BC_エンジニアコース
講師の自己紹介 吉井 健文 @Takepepe / フロントエンド関連の記事書いたり 所属:横断エンジニアリング部 ASG 2020年10月入社、Next.js を採用したプロジェクトの
開発支援を中心に、横断従事
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 を触るのは初めて ※ かなり詰め込んでいるので、全体的に駆け足気味の構成です
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) ✏ より理解しやすいよう、解説途中に手を動かすことが多いです
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)
MPA と SPA の比較と、なぜ SPA を 採用する機会が増えてきているのか説明します。 第1章 MPA と SPA
第1章 MPA と SPA WEB 3層構造。WEB アプリケーション構築における標準的なシステム構成。 ▪ WEB サーバー ▪
APP サーバー ▪ DB サーバー
第1章 MPA と SPA WEB 3層構造。WEB アプリケーション構築における標準的なシステム構成。 ▪ WEB サーバー ▪
APP サーバー ▪ DB サーバー APP サーバー構築にむけ、様々な言語のフレームワークが存在しますが、 近年、フロントエンド SPA(Single Page Application) 構築を兼ねる フレームワークが注目を集めています。
第1章 MPA と SPA WEB 3層構造。WEB アプリケーション構築における標準的なシステム構成。 ▪ WEB サーバー ▪
APP サーバー ▪ DB サーバー 本日の題材である「Next.js」が、そのひとつです。 TypeScript(JavaScript)でコードを書き、Node.js で稼働します。
第1章 MPA と SPA MPA(Multi Page Application)とは? ▪ 書き換えの粒度が「ページ単位」 ▪ ページリクエストに応じ、サーバーが
HTML ページをレスポンス ▪ 複数のページで構成され、リクエストとページが1体1の関係 SPA の対義語として用いられることが多く、 本日の研修でも対義語として用います。
第1章 MPA と SPA MPA(Multi Page Application)とは? ▪ 書き換えの粒度が「ページ単位」 ▪ ページリクエストに応じ、サーバーが
HTML ページをレスポンス ▪ 複数のページで構成され、リクエストとページが1体1の関係 オリジンサーバーで処理をするとき、 データ取得完了までレスポンス待ちになる。
第1章 MPA と SPA SPA(Single Page Application)とは? ▪ 書き換えの粒度が「UIコンポーネント単位」 ▪ 骨格となる
HTML ページを受け取るところまでは MPA と同じ ▪ JavaScript で動的に UIコンポーネント や URL を書き換える ページは表示されたまま「部分的に書き換える」ため、 データ取得中も何かしらの情報を提供できる。
第1章 MPA と SPA SPA を採用するメリット ▪ ユーザー体験が良い:より良い体験が、サービス価値最大化に貢献 ▪ オーバーヘッドが少ない:必要に応じて、必要なデータだけを取得 ▪
責務の分離:モノリスな MPA からの脱却
第1章 MPA と SPA SPA を採用するメリット ▪ ユーザー体験が良い:より良い体験が、サービス価値最大化に貢献 ▪ オーバーヘッドが少ない:必要に応じて、必要なデータだけを取得 ▪
責務の分離:モノリスな MPA からの脱却 ✅ サービス価値最大化貢献と、システム全体最適化貢献が SPA 採用のメリット。 🎥 参考動画 Google I/O:Core Web Vitals によるビジネス インパクト
第1章 MPA と SPA SPA を採用するメリット ▪ ユーザー体験が良い:より良い体験が、サービス価値最大化に貢献 ▪ オーバーヘッドが少ない:必要に応じて、必要なデータだけを取得 ▪
責務の分離:モノリスな MPA からの脱却 「Next.js」は APP サーバーを兼ねることが可能な、 SPA 構築フレームワークです。 コンポーネントライブラリの「 React」をベースとしています。
UIコンポーネントライブラリの「 React」について、 基本的な概略を説明、実際に触れていきます。 第2章 React ハンズオン
第2章 React ハンズオン UIコンポーネントライブラリの「 React」について ▪ UIコンポーネントとは、ブラウザで情報を表示・操作するもの( HTML) ▪ UIコンポーネントは、JSX で記述する
▪ JSX は JavaScript の拡張構文で、HTML のようなタグ構文に倣っている ▪ JavaScript -> JSX、TypeScript -> TSX MPA フレームワークで View を担っていた、テンプレートエンジンと責務は近い。 Next.js 研修に最低限の理解は必要なので、手取り早く試して概念を掴みましょう
第2章 React ハンズオン 【実技】CodeSandbox で試してみよう ✏ https://codesandbox.io/ にアクセス ・GitHub または Google アカウントでサインイン
・「Create Sandbox」を押下 ・「React Typescript」をテンプレートから選択 CodeSandbox は、環境構築不要・ブラウザだけで、すぐに動くコードを試せます。
第2章 React ハンズオン はじめに表示される「 App.tsx」のなかに、コードを書いていきます。 真ん中がエディタ、右がコンパイル結果です。
第2章 React ハンズオン ✏ 「<h1>Hello Codesandbox</h1>」の文字列を編集してみよう ✏ 好きな HTML タグを書き、中括弧に式を書いてみよう
第2章 React ハンズオン ✏ <button> タグを書いて、 onClick イベントのハンドラー関数を渡してみよう ✏ onClick ハンドラー関数に、console.log(‘hello’)
を仕込んでみよう
第2章 React ハンズオン ✏ 書いた<button> タグを Button 関数(コンポーネント)に切り出してみよう ✏ <Button />
コンポーネントを 3つ並べてみよう
第2章 React ハンズオン ✏ <Button /> コンポーネントに Props(引数){ value: number }
を型注釈してみよう ✏ <Button /> コンポーネント 3つに、異なる value を渡してみよう
✏ 配列を作り、コンポーネント内で出力してみよう( map 関数を使用) ✏ <Button /> コンポーネント 3つを、map 関数出力に書き換えてみよう
第2章 React ハンズオン
✏ <Button /> コンポーネントを<Counter /> コンポーネントにリネームしよう ✏ <Counter /> コンポーネントに状態を保持し、カウントアップ機能を作り込んでみよう
第2章 React ハンズオン
✏ <button /> を押下して、ニュースデータを取得、コンポーネントに表示してみよう https://hacker-news.firebaseio.com/v0/item/31000386.json 第2章 React ハンズオン
React ベースのフレームワークである Next.js の基礎を解説、 いくつかの抑えておきたい概念を説明します。 第3章 Next.js の基礎と概念
第3章 Next.js の基礎と概念 Next.js は、React ベースのフレームワーク ✅ 簡単に SPA 開発が始められる ✅
素早く SPA 開発が進められる ✅ 高品質な SPA を作れる
第3章 Next.js の基礎と概念 ✅ 簡単に SPA 開発が始められる ▪ Node.js がインストールされていれば、 CLI
一つでプロジェクト作成可能 ▪ 過去、整備が大変だった開発環境も、デフォルトで整備済み ・Webpack:バンドラー設定 ・TypeScript:トランスパイラ設定 ・ESLint:コードリンター設定
第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
第3章 Next.js の基礎と概念 ✅ 素早く SPA 開発が進められる ▪ ファイルシステムベースのルーティング ・フォルダ構成が、そのままページルーティングになる
第3章 Next.js の基礎と概念 ✅ 素早く SPA 開発が進められる ▪ ファイルシステムベースのルーティング ・フォルダ構成が、そのままページルーティングになる ▪
規定の関数 を export すれば、フレームワークのレールに乗れる ・特定ページの表示(レンダリング)方法など
第3章 Next.js の基礎と概念 ✅ 素早く SPA 開発が進められる ▪ ファイルシステムベースのルーティング ・フォルダ構成が、そのままページルーティングになる ▪
規定の関数 を export すれば、フレームワークのレールに乗れる ・特定ページの表示(レンダリング)方法など 【実技】ページを増やしてみよう ✏ $ cp pages/index.tsx pages/hello.tsx
第3章 Next.js の基礎と概念 ✅ 高品質な SPA を作れる ▪ SPA はバンドルサイズの肥大化が課題 ・SPA
はクライアントサイドの再描画が基本 ・初回ロードするファイルが多いほど、ユーザーを待たせてしまう
第3章 Next.js の基礎と概念 ✅ 高品質な SPA を作れる ▪ SPA はバンドルサイズの肥大化が課題 ・SPA
はクライアントサイドの再描画が基本 ・初回ロードするファイルが多いほど、ユーザーを待たせてしまう ▪ Next.js はバンドルサイズの肥大化を避けられる ・ページ単位で、チャンク分割される ・遷移先ページで必要なファイルが、必要なタイミングで読み込まれる Next.js は、サイズ肥大化をあまり意識する必要がない
第3章 Next.js の基礎と概念 ✅ 高品質な SPA を作れる ▪ APP サーバーへの負荷低減 ・ページの性質に応じて、最適な提供方法を選択できる
・可能なページは、事前に HTML を生成しておく、など 重要なポイントであり、研修のメインテーマです
第3章 Next.js の基礎と概念 抑えておきたい、3つの両極 ▪ 開発サーバー / 本番サーバー ▪ ビルドタイム /
ランタイム ▪ クライアントサイド・レンダリング / サーバーサイド・レンダリング Next.js は、クライアント(ブラウザ)で実行されるコードだけでなく、 サーバーで実行されるコードも含みます。
第3章 Next.js の基礎と概念 開発サーバー / 本番サーバー ▪ 開発サーバー ・Next.js に備わっている、開発モードのサーバー( npm
run dev) ▪ 本番サーバー ・Next.js プロジェクトをビルド( npm run build) ・ビルド後、起動した本番サーバー( npm start)
第3章 Next.js の基礎と概念 ビルドタイム / ランタイム ▪ ビルドタイム ・Next.js プロジェクトを、ビルドする時 ▪
ランタイム ・アプリの稼働中、コードが実行される時
第3章 Next.js の基礎と概念 クライアントサイド・レンダリング / サーバーサイド・レンダリング ▪ クライアントサイド・レンダリング ・React コードを「ブラウザ」で HTML
化、ページを書き換える ▪ サーバーサイド・レンダリング ・React コードを「サーバー」で HTML 化、ブラウザに送る
第3章 Next.js の基礎と概念 3種類のレンダリング( HTML生成) ▪ CSR:クライアントサイド・レンダリング( Client-Side Rendering) ▪ SSR:サーバーサイド・レンダリング(
Server-Side Rendering) ▪ SSG:静的サイトの生成( Static Site Generation) ページ単位・コンポーネント単位で、選ぶことができます。 なぜ、これほど種類があるのでしょうか?
3種類のレンダリング( HTML生成) ✅ 表示するデータに応じて、使い分ける必要があるから ・ページに表示するデータは、他人と共有できるものか? ・ページに表示するデータは、更新頻度がどれほどか? ・ ページは、どの様なデータで構成されているか? 第3章 Next.js の基礎と概念
第3章 Next.js の基礎と概念 レイアウトが全く同じでも、 サイトが提供するデータによって、 最適なレンダリングは異なります。 右の様なレイアウトを例えに、 いくつかのページを見てみましょう。
例)ニュースサイト・TOPページの場合 ▪ A)ヘッドライン ▪ B)カテゴリ一覧 ▪ C)トピック一覧のリンク 全てパブリックデータであり、 他人と共有できるものです。 B
A C 第3章 Next.js の基礎と概念
例)ニュースサイト・TOPページの場合 ▪ A)ヘッドライン ▪ B)カテゴリ一覧 ▪ C)トピック一覧のリンク 配信経路上のキャッシュサーバー ※で キャッシュすることが出来ます。
この様なページは SSG が適しています。 ※ CDN・nginx など B A C 第3章 Next.js の基礎と概念
例)SaaS・ダッシュボードの場合 ▪ A)プロジェクトのメトリクス ▪ B)サブプロジェクト一覧 ▪ C)ユーザーの行動履歴 全てパーソナルデータであり、 他人と共有することはできません。 B
A C 第3章 Next.js の基礎と概念
例)SaaS・ダッシュボードの場合 ▪ A)プロジェクトのメトリクス ▪ B)サブプロジェクト一覧 ▪ C)ユーザーの行動履歴 配信経路上にキャッシュできないので、 オリジンサーバーが応答します。 この様なページは
SSR が適しています。 B A C 第3章 Next.js の基礎と概念
例)旅行・宿泊予約サイトの場合 ▪ A)キャンペーンへのリンク ▪ B)特集ページへのリンク ▪ C)ログインユーザー情報 大部分はパブリックデータですが、 一部、パーソナルデータです。 B
A C 第3章 Next.js の基礎と概念
例)旅行・宿泊予約サイトの場合 ▪ A)キャンペーンへのリンク ▪ B)特集ページへのリンク ▪ C)ログインユーザー情報 青い部分だけをキャッシュで返し、 緑の部分だけを後から書き換えます。 この様なエリアは
CSR が対応します。 B A C 第3章 Next.js の基礎と概念
紹介したようにレイアウトが全く同じでも、 プロジェクトによって最適なレンダリングが 異なることが分かります。 さらには、同じプロジェクトでも 「このページはコレ・あのページはアレ」という 見極めが必要、ということです。 第3章 Next.js の基礎と概念
配信経路上のキャッシュを活用すると、 高速・低負荷でページを提供できます。 しかし、キャッシュできるデータは限られます。 どの様にレンダリングするか?という判断は、 共有キャッシュ化の判断、とも言い換えられます。 第3章 Next.js の基礎と概念
「ページ単位・エリア単位」でレンダリングを選択出来れば、 配信を最適化することができます。 これこそが Next.js の強みであり、 WEB サイト・アプリケーション配信のベストプラクティスです。 第3章 Next.js の基礎と概念
Next.js の重要な機能のうちのひとつ、 静的生成について、手を動かしながら理解を深めます。 第4章 静的生成 ハンズオン
第4章 静的生成 ハンズオン ページには「データ取得関数」を定義することができます ▪ データ取得関数とは? ・Next.js 特有の、規程関数 ・ページに必要なデータを、予め取得する関数 ・pages フォルダに含まれる「ページファイル」で使う関数
・pages フォルダ内の .tsx ファイルは基本的に「ページファイル」扱い ✅ データ取得関数は、決まった名前で export する
第4章 静的生成 ハンズオン ページを静的生成するためには「 getStaticProps 関数」を使います ▪ getStaticProps 関数とは? ・静的生成に必要なデータを、予め取得する関数 ・関数はブラウザで実行されることはなく、
Node.js プロセスで実行される ✅ getStaticProps 関数の有無で「静的生成ページか?」を、 Next.js が自動判断
第4章 静的生成 ハンズオン 【実技】getStaticProps でレンダリングしよう ✏ getStaticProps 関数で時刻を表示しよう ・getStaticProps 関数内で console.log(new
Date().toISOString()) ・npm run devでは、リクエストの度に html レスポンスが変わる ・npm run build && npm startでは、html レスポンスが固定 ✅ 開発サーバー・本番サーバーでは、挙動が異なる ✅ 以降基本的に「本番サーバーで作業するもの 」として研修を進めます
第4章 静的生成 ハンズオン 【実技】getStaticProps でレンダリングしよう ✏ getStaticProps 関数でデータを取得しよう ・hacker-news で記事タイトルを取得 ・npm
run devでは、リクエストの度に取得 ・npm run build && npm startでは、ビルド時に取得 ✅ 本番サーバーでは、データ取得の回数が少ない(必要な時のみ) ✅ 結果、ページリクエスト時にデータ取得しなくてよい -> レスポンスが速い ✅ 結果、APIサーバーへの負荷が少ない ❌ データが生成時のものに固定され、固定内容が配信される
第4章 静的生成 ハンズオン 【実技】ISR を体験しよう ✏ revalidate オプションで「秒」を指定してみよう ・指定時間経過前:予め生成された HTML(キャッシュ)が返却される ・指定時間経過後:予め生成された
HTML(キャッシュ)が返却される ・直後は、古い内容が返る ・裏側で「再生成」が試行される ・再生成が完了すると、次回以降リクエストは新しい内容が返る ✅ ページ生成後、指定経過時間を超過すると「再生成」が試行される
第4章 静的生成 ハンズオン 【実技】ISR を体験しよう ✏ revalidate オプションを付与すると ISR(Incremental Static Regeneration)となる
・一定期間、古いデータ配信を許容する変わり、パフォーマンスが高まる ・ビルドタイムで HTML が事前生成される場合もある ・オンデマンドで再生成される場合もある ✅ revalidate オプションがあると、本番サーバーでもデータ取得が発生する ✅ revalidate は「一定時間古いデータを返すことを許容」できる要件に適合 ❌ 一定期間古いデータを返すことが許容できない場合、 SSG はそもそも不向き
第4章 静的生成 ハンズオン 【実技】動的ルートを参照してみよう ▪ 動的ルートとは? ・path param が参照できる(url path に含まれる変数)ルート
・例えば /users/1 というルートは、ユーザー IDに相当する「1」が参照できる ✏ pages/users/[id].tsx を作ってみよう ・getStaticProps関数に、GetStaticProps型注釈をしてみよう ・引数のctx から、ctx.params.idを参照、console.log しよう
第4章 静的生成 ハンズオン 【実技】getStaticPaths を使ってみよう ▪ getStaticPaths とは? ・動的ルートを参照する、 getStaticProps と一緒に利用するもの
・ビルドタイムに「生成する・しない」 ページの数を決めるもの ・オンデマンドで「生成する・しない」 ページの振る舞いを決めるもの https://nextjs.org/docs/basic-features/data-fetching/get-static-paths
第4章 静的生成 ハンズオン 【実技】getStaticPaths を使ってみよう ▪ fallback: false とは? ・「オンデマンドで生成しない」指定 ・「paths」に含まれる要素の数だけ、ビルドタイムにページ生成
・「paths」に含まれない path 相当ページは「404」
第4章 静的生成 ハンズオン 【実技】getStaticPaths を使ってみよう ▪ fallback: true とは? ・「オンデマンドで生成する」指定 ・「paths」に含まれる要素の数だけ、ビルドタイムにページ生成
・「paths」に含まれない path 相当ページは「オンデマンド生成」を試行する
第4章 静的生成 ハンズオン 【実技】getStaticPaths を使ってみよう ✏ fallback: false を試してみよう ・npm run
build && npm startを実行、ビルドログを見てみて ・.next/server/pages/users/に生成されている HTML を見てみて ・http://localhost:3000/users/4にアクセスしてみて ✅ paths に対応するページが、ビルドタイムに生成されている ✅ paths に対応しないページは、 404 が返される
第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 が同時に生成される
第4章 静的生成 ハンズオン 【実技】静的生成まとめ ▪ データはパブリックに共有できるものに限られる ▪ リクエストに応じて「オンデマンドで HTML を静的生成」することが Next.js
の特徴 ・再生成契機となる、経過時間の指定ができる ・動的ルートも、オンデマンド生成があるため対応できる ・事前にすべて生成することもできる ✅ ビルドタイムに全ページ生成する必要がないので、ビルドが速い ✅ 配信データが、少し古くても良いか否かに応じて、細かく制御ができる
Next.js の重要な機能のうちのひとつ、 動的生成について、手を動かしながら理解を深めます。 第5章 動的生成 ハンズオン
第5章 動的生成 ハンズオン Next.js 最大の強みは「ページ単位で」レンダリング(事前生成)を選べることです ▪ SSG で、ビルドタイムに事前生成( getStaticProps) ▪ ISR
で、オンデマンドに事前生成 (getStaticProps) ▪ SSR で、リアルタイムに事前生成( getServerSideProps) ✅ getStaticProps (SSG,ISR) / getServerSideProps (SSR) のいずれか 🗒 SSRは Next.js に限らず、React 単体 + 簡易サーバーでも提供可能な、普遍的機能
第5章 動的生成 ハンズオン 【実技】getServerSideProps を使ってみよう ✏ getServerSideProps でリクエスト毎の実行を確認 ・関数内に console.log(new Date().toISOString())
を記述 ・ブラウザから該当ページへアクセス ・アクセス時刻が出力されることを確認 ・返却内容を Network タブ、Preview/Response 内訳を確認して ✅ リクエストのたび、生成内容が異なる ✅ export されているデータ取得関数で、ページのレンダリング方法が決定される
第5章 動的生成 ハンズオン 【実技】getServerSideProps を使ってみよう ✏ getServerSideProps で header の中を確認 ・getServerSideProps関数にGetServerSideProps型を注釈
・引数ctxを、console.log で出力してみて ✅ リクエストの内訳が、確認できる
第5章 動的生成 ハンズオン 【実技】getServerSideProps を使ってみよう ✏ nookies で cookie の値を読み書きしよう ・Next.js
で cookie を扱いやすくするライブラリ ・npm i nookiesを実行、インストール ・setCookie、parseCookies で値の読み書きを確認 ・cookie 内容を Network タブ、Cookies で確認して ✅ クライアントに紐づいた Cookie の内容が、読み書きできる https://www.npmjs.com/package/nookies
第5章 動的生成 ハンズオン 【実技】API Routes を使ってみよう ▪ API Routes とは? ・pages/api
に定義することで、Web API 定義ができる ・ページ出力(HTML)ではなく、JSON を返すことが一般的 ・GET 以外に POST / PUT / DELETE などのメソッドにも対応 ・pages と同様、ファイルシステムに則ったルーティング
第5章 動的生成 ハンズオン 【実技】API Routes を使ってみよう ✏ JSON を返してみよう ・pages/api/hello.ts のファイルを確認
・res.status(200).json({ }) の内容を書き換えてみて ✏ nookies で cookie の値を読み書きしよう ・getServierSideProps でセットした値を読み書きしてみて ✅ getServerSideProps と同じように、req / res を扱える
ORM ライブラリの Prisma を利用し DB 接続、 簡単な記事投稿 CRUD アプリ開発を体験します。 第6章 簡単な
CRUD アプリを開発
第6章 簡単な CRUD アプリを開発 【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう ✏ 以下のリポジトリをクローン ・https://github.com/recruit-tech/bootcamp-2022-nextjs ・docker-compose
up -d で、コンテナを立ち上げる ・PostgreSQL が立ち上がっていることを確認
第6章 簡単な CRUD アプリを開発 【実技】ORM ライブラリの Prisma を使います ▪ Prisma ざっくり概要
・Prisma Schema Language(PSL)でスキーマを書く ・スキーマから、各言語向けの Client が生成できる ・スキーマから、マイグレーションファイルが生成できる ・TypeScript との親和性が高い 今日の研修では Prisma 詳説はしません。予め用意したスキーマで開発を進めます。 ※ バリデーション・脆弱性対策に関しては、本日は SKIP
第6章 簡単な CRUD アプリを開発 【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう ✏ Prisma をセットアップしよう ・npm
run db:migrate でマイグレーション、 seeding を実行 ✅ リセットは npm run db:migrate:reset で
第6章 簡単な CRUD アプリを開発 【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう ✏ Prisma Studio を使ってみよう
・Prisma に標準バンドルされている GUI ・npm run db:studio で Prisma Studio たちあげ ・http://localhost:5555 にアクセス ✅ fixture が DB に挿入されていることを確認
第6章 簡単な CRUD アプリを開発 【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう ✏ Prisma Studio でレコードを追加してみよう
・Add record ボタンを押下 ・新規内容を入力して ・Save 1 change ボタンを押下 ✅ Prisma Studio で、DB を操作できます
第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 の型推論が優れている
第6章 簡単な CRUD アプリを開発 【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう ✏ getServerSideProps で PrismaClient
を使いユーザー詳細を表示しよう ・http://localhost:3000/users/1 にアクセスしてみて ・pages/users/[id]/index.tsx を開いて ・getServerSideProps の引数 ctx から params.id を取得してみて ✏ 課題1:エラー「オブジェクトは 'undefined' である可能性があります」を消すには?
第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 にするためには?
第6章 簡単な CRUD アプリを開発 【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう ✏ getServerSideProps で PrismaClient
を使いユーザー詳細を表示しよう ・Page コンポーネントに、ユーザーの名前・ Email を表示してみて ・Page コンポーネントに、現在時刻を表示してみて ✏ 課題3: ユーザー詳細を表示してみて
第6章 簡単な CRUD アプリを開発 【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう ✏ API Routes で値を受け取り、ユーザーレコードを追加してみよう
・pages/users/new.tsx を開いて ・入力値をどの様に form で送るか、一緒に確認していきます ・pages/api/users/index.ts を開いて ・送られた入力値でどの様にレコード作成するか、一緒に確認していきます ✅ ブラウザ -> DB 更新の一連の流れ ※ バリデーション・脆弱性対策に関しては、本日は SKIP
第6章 簡単な CRUD アプリを開発 【実技】DBサーバーと接続して、 CRUD アプリを作ってみよう ✏ ① API Routes
で値を受け取り、ユーザーレコードを更新してみよう ✏ ② API Routes で値を受け取り、ユーザーレコードを削除してみよう ✏ ③ API Routes で適切なバリデーション、エラーレスポンスを返してみよう ✏ ④ ユーザー画面を参考に、記事投稿の CRUD 画面をつくってみよう ✏ ⑤ ユーザーAPIを参考に、記事投稿の CRUD API をつくってみよう ⏰ 制限時間まで、自由に作り込んでみてください※ ※ Prisma Schema を追加・編集するのもありです
Vercel に Next.js アプリを展開する利点を解説しつつ、 実際に現場でどの様に使われているか説明します。 第7章 現場での使われ方と最新動向
第7章 現場での使われ方と最新動向 Next.js 現場での使われ方 ▪ Vercel は使いますか? ・あまり積極的に使われていません※ ・セキュリティ要件がクリアできない ・インフラ構成に適合しない(構成に自由度がない) ・日本法人がない、サポート面が薄い、など
※講師の観測範囲に限ります
第7章 現場での使われ方と最新動向 Next.js 現場での使われ方 ▪ SSG は使いますか? ・デプロイパイプラインで、 SSG するパターンはあります※ ・完全に静的な
Next.js をビルドするパターンです ・完全に静的な Next.js と API サーバーによる構成 ✅ Full CSR の SPA 構築ツールとして使う ※ Static HTML Export による、完全に静的な出力
第7章 現場での使われ方と最新動向 Next.js 現場での使われ方 ▪ ISR は使いますか? ・ISR はキャッシュ制御ノウハウが少ないため、利用実績はない(はず) ・SSR +
配信経路キャッシュで、 ISR と同等のことが出来る(※ 1) ・ISR の仕組みを、積極的に採用する理由がそこまでない ✅ 配信経路キャッシュ = Next.js 前段の CDN や nginx などのキャッシュサーバー(※ 2) ※1 細部に違いがあり、考慮すべき点があります / ※2 プロジェクト毎に構成は異なります
第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 の前段にたっている状態
第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 が強制上書きされてしまうので注意 ※ 重いクエリが実行されていることをエミュレートするための遅延関数
第7章 現場での使われ方と最新動向 【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう ✏ Cache-Control ヘッダーを設定してみよう(
getServerSideProps 編) ✅ nginx からレスポンスが返ってきている事を確認
第7章 現場での使われ方と最新動向 【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう ✏ Cache-Control ヘッダーを設定してみよう(
getServerSideProps 編) ✅ キャッシュヒットした時、 TTFB が速い
第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バケットに配備した、マスタデータへのアクセス数を間引くようなケースで有効
第7章 現場での使われ方と最新動向 【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう ✏ Cache-Control ヘッダーを設定してみよう(
API Routes 編) ✅ nginx からレスポンスが返ってきている事を確認
第7章 現場での使われ方と最新動向 【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう ✏ Cache-Control ヘッダーを設定してみよう(
API Routes 編) ✅ キャッシュが返ってきた時、 TTFB が速い
第7章 現場での使われ方と最新動向 【実技】SSR + nginx プロキシキャッシュで、 ISR の再現をしよう ✏ Cache-Control ヘッダーを設定してみよう
✅ nginx プロキシキャッシュが返り、オリジンサーバーに到達していない ✅ 一定期間キャッシュを返す挙動が、 ISR の revalidate オプションに近い ※ 実際は必要に応じてキャッシュをパージするフローも必要
第7章 現場での使われ方と最新動向 CDN・プロキシキャッシュは、 Next.js 特有のものではない ▪ Cache-Control ヘッダーは構成をみて適切に ・利用する CDN によって、ディレクティブが微妙に異なる
・キャッシュしてはいけないデータに要注意 ・「キャッシュ事故」で検索すると、これにまつわる記事を参照できる ✅ 配信経路上にキャッシュして良いデータか、十分注意する
第7章 現場での使われ方と最新動向 Vercel + ISR は何が利点? ▪ getStaticProps では、req がそもそも参照できない ・キャッシュ事故のリスクヘッジになる
▪ 配信経路上のキャッシュ(インフラ構成)を考えなくて済む ・配信最適化のノウハウが、 APPコードに隠蔽されている ・Edge Computing など、最新のインフラ構成もすぐに試せる ✅ アカウント一つで、すぐに試すことができる ✅ Vercel が使えなくとも、配信構成の参考として役立つ
第7章 現場での使われ方と最新動向 残りの時間で、Next,js 最新の動向を、 別資料で紹介します。 【おさらい:Next.js 公式の学習コンテンツもお勧めです】 https://nextjs.org/learn/foundations/about-nextjs