Share
Embed
Transcript
68 slides
-
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) -
開発環境の確認 ▪ 最新の Node.js ▪ リポジトリをクローンしたら、 node_moduels をインストールしておきましょう → $ npm
i ✏ 研修用 GitHub リポジトリのクローンをお願いします https://github.com/recruit-tech/bootcamp-2024-nextjs -
第1章 フロントエンド開発と SPA フレームワーク JSX(TSX)は、 UI コンポーネント(View)を関数で実装します ▪ 入力(Props)を与えると、出力(HTML)を得る ▪ 要素一覧、ボタン、フォームなど
▪ 小さい UI コンポーネントを組み上げる → ページ相当の UI コンポーネントが出来る → 先日の React 研修のとおり UI コンポーネント単位の開発 -
第1章 フロントエンド開発と SPA フレームワーク React は UI ライブラリ ▪ UI コンポーネント実装・レンダリングに特化
▪ ページとして提供する方法は、別途必要になる → Web アプリケーションサーバーとしての機能は持たない UI コンポーネント単位の開発 -
第1章 フロントエンド開発と SPA フレームワーク MPA はリクエストごとに HTML を表示 ▪ MPA は
SPA との対比で使用される用語 → Multi Page Application / Single Page Application ▪ 複数 の HTML ページで構成される → サーバーが HTML をレスポンス → 状態の復元は Cookie などを頼りに SPA・MPA の違い 画面遷移毎に「ページのリクエスト」が発生するもの HTML 画面遷移 HTML HTML 画面遷移 -
第1章 フロントエンド開発と SPA フレームワーク SPA は DOM を適宜書き換えることで、画面遷移 ▪ 初回レスポンスは、単一 HTML
▪ URL 変更(History API)に応じて JSON を非同期で取得 ▪ JSON を HTML コンテンツとして書き換え → 仮想 DOM を更新・実 DOM に反映 → ブラウザ上で動的に HTML に反映 SPA・MPA の違い 画面遷移毎に「コンテンツの書き換え」が発生するもの HTML 画面遷移 画面遷移 JSON JSON -
第1章 フロントエンド開発と SPA フレームワーク ✅ SPA/MPA の違いは「画面遷移」である ▪ SPA は画面遷移しても、ブラウザの状態が破棄されない → 一度取得したデータ、ユーザーの状態を維持できる
▪ 非同期で必要なコンテンツのみをダウンロードする → データソースアクセスが必要最小限に → 画面遷移が高速 SPA・MPA の違い HTML 画面遷移 画面遷移 JSON JSON React は SPA のためとは限らない -
第1章 フロントエンド開発と SPA フレームワーク 単一の HTML で SPA 展開するもの ▪ 典型的な
SPA(古典的な SPA) ▪ 初期描画では不要な JavaScript バンドルのロードが発生 → FID ※1 の低下に直結 ▪ 最適化にはチューニングが必要 フレームワークを採用する利点 HTML 画面遷移 画面遷移 JSON JSON 初回ロードで大量の JavaScript バンドルファイルを取得する必要 大量のJavaScript 課題 ※1 FID(First Input Delay)コアウェブバイタルの指標の 1つ。初回入力までの遅延時間。 -
第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 -
第1章 フロントエンド開発と SPA フレームワーク 複数の HTML で SPA 展開するもの ▪ Next.js、Remix、Sveltekit、Nuxt、...etc
▪ バンドラーを含み、ページ毎のレスポンス(ダウンロードファイル)が最適化 ▪ ページによって、動的・静的にレスポンスを選択する フレームワークを採用する利点 HTML 画面遷移 画面遷移 JSON JSON 具体的にどのようなアプローチが採用されるのか、1日の研修を通して解説します SPA フレームワーク 解決 ? -
第1章 フロントエンド開発と SPA フレームワーク ✅ React 単体よりも、良いアプリケーション開発が可能 ▪ バンドラー、ルーター、データ取得の最適解が盛り込まれている ▪ 配信方法の最適解は、多様化している
▪ Next.js は SPA 以外にも、ニーズにあわせて選択可能 ▪ コンテンツの性質に応じて選べる フレームワークを採用する利点 -
第2章 Next.js の SPA create next app を実行してみよう ▪ create next
app とは? → Next.js プロジェクトの雛形生成ツール ▪ $ npx create-next-app@latest 【実技】Next.js プロジェクトを作ってみよう (消す前提なので)まずは適当なディレクトリで試してみましょう -
第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 プロジェクトを作ってみよう -
第2章 Next.js の SPA Next.js 開発サーバーを起動してみよう ▪ $ cd my-app ▪
$ npm run dev ▪ http://localhost:3000/ を確認してみよう ▪ 「Ctrl + C」で開発サーバーを終了 【実技】Next.js プロジェクトを作ってみよう ✅ Next.js プロジェクトの準備はこれで完了! -
第2章 Next.js の SPA 研修リポジトリの「lesson-1」を使用します ▪ カレントディレクトリを移動して → $ cd lesson-1 ▪
開発サーバーを起動して → $ npm run dev 【実技】pages ルーティングを体験してみよう 研修リポジトリのサンプルは、 create next app で作成しました -
第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 -
第2章 Next.js の SPA ファイルシステムベースのルーティング ▪ 「pages」 というディレクトリに「 Page ファイル」を配備する → pages
ディレクトリに配備するだけで、ルーティング対象となる → ページ相当の UI コンポーネントを export default(📌:1-1) 【実技】pages ルーティングを体験してみよう -
第2章 Next.js の SPA Link コンポーネントを使用した SPA ナビゲーション ▪ import Link
from "next/link"; → a要素のように使用。href 属性を指定する(📌:1-2) 【実技】pages ルーティングを体験してみよう -
第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 ルーティングを体験してみよう -
第2章 Next.js の SPA ファイルシステムの命名規則と、 Router の使い方が基本 ▪ Link コンポーネントや Router
を使用すると、SPA ナビゲーションができる ▪ ページルーティングは、ファイルを配置するだけ ▪ 命名規則によってリクエストパラメーターを取得できる ✅ 単純な SPA サイトなら、すぐに実装できる -
第2章 Next.js の SPA 開発サーバー・本番サーバーは別物 ▪ Next.js アプリ 開発サーバーの起動 → ▪
Next.js アプリ(本番サーバー)のビルド → ▪ Next.js アプリ(本番サーバー)の起動 → 【実技】npm script を試してみよう -
第2章 Next.js の SPA 開発サーバー・本番サーバーは別物 ▪ Next.js アプリ 開発サーバーの起動 → $ npm
run dev ▪ Next.js アプリ(本番サーバー)のビルド → $ npm run build ▪ Next.js アプリ(本番サーバー)の起動 → $ npm start 【実技】npm script を試してみよう 研修後半、使い分けるため注意 -
第2章 Next.js の SPA TypeScript の型互換エラーがある状況でビルドしてみよう ▪ const value: string =
0; を適当に追加 ▪ $ npm run build → 【実技】npm script を試してみよう -
第2章 Next.js の SPA TypeScript の型互換エラーがある状況でビルドしてみよう ▪ const value: string =
0; を適当に追加 ▪ $ npm run build → Type error: Type 'number' is not assignable to type 'string'. 【実技】npm script を試してみよう 型互換エラーがあるとビルドに失敗する -
ESLint コーディング規約違反がある状況でビルドしてみよう ▪ (📌:1-6)の行を削除 ▪ $ npm run build →
▪ $ npm run lint eslint の実行(コーディング規約違反チェック) → 第2章 Next.js の SPA 【実技】npm script を試してみよう -
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 コーディング規約違反があるとビルドに失敗する -
第3章 Next.js の BFF Web アプリケーションサーバーとしての機能 ▪ SSR(Server Side Rendering)機能 → データ取得
→ リクエスト単位の検証(認証認可) → 正常系以外のレスポンス(リダイレクト、エラー表示) Next.js の BFF とは SSR は SEO 観点でも必要になることがある -
第3章 Next.js の BFF Web アプリケーションサーバーとしての機能 ▪ Web API 機能 → データ取得・更新
→ リクエスト単位の検証(認証認可) → クレデンシャル情報を扱う外部連携 Next.js の BFF とは 静的サイトとの大きな違い -
第3章 Next.js の BFF 外部サーバー(サブシステム)との中継役を担い、永続層と接続する ▪ VPC ネットワーク内の外部サーバー(サブシステム)と疎通 → バックエンド API サーバーと疎通
→ API サーバーから取得したデータの集約(アグリゲーション) ▪ DB サーバーと疎通 → Prisma など ORM 経由で Next.js の BFF とは システム構成によって使い分けることができる -
第3章 Next.js の BFF 基本 Node.js サーバーとして稼働 ▪ ランタイムは Node.js 以外も選べる(次世代の話)
→ Edge Runtime → 今日の研修では触れません Next.js の BFF とは システム構成によって使い分けることができる -
第3章 Next.js の BFF ✅ Next.js は Web アプリケーションサーバーとして利用できる ▪ 単一
Next.js プロジェクトコードで、フロント・ BFF 実装ができる ▪ 完全に静的なサイトジェネレーターとしても利用できる Next.js の BFF とは -
第3章 Next.js の BFF 研修リポジトリの第3章をひらき、開発サーバーを起動しましょう ▪ カレントディレクトリを移動して → $ cd lesson-2 ▪
開発サーバーを起動して → $ npm run dev 【実技】SSR を試してみよう -
第3章 Next.js の BFF getServerSideProps(gSSP)とは? ▪ ページに向けたデータ取得関数 → ページリクエストのたび、実行される → サーバーログを確認してみよう( 📌:2-1) ▪
SSR(Server Side Rendering)向け → 取得したデータを埋め込み、 HTML をレスポンス 【実技】SSR を試してみよう -
第3章 Next.js の BFF 動的パラメーターの取得 ▪ gSSP の引数 ctx.query から query・path
パラメーターが参照できる( 📌:2-2) ▪ gSSP が定義されている場合、 useRouter の挙動が変わる(📌:2-3) 【実技】SSR を試してみよう getServerSideProps あり getServerSideProps なし -
Cookie の参照 ▪ gSSP では Cookie の読み書きができる( 📌:2-4) → nookies(Next.js で
Cookie を扱いやすくするライブラリ) ▪ Cookie にセットした sessionID から、session 値を参照 → session 値を使用した外部リクエストなど 第3章 Next.js の BFF 【実技】SSR を試してみよう -
第3章 Next.js の BFF ✅ gSSP はページのレンダリングだけでなく、リクエスト検証が行える ▪ ログインユーザーに紐づいた情報の取得 ▪ VPC
内のバックエンド API サーバー(サブシステム)との連携に ▪ サーバーで実行されるため、クレデンシャル情報を扱える 【実技】SSR を試してみよう -
第3章 Next.js の BFF Next.js では環境変数を参照する仕組みが提供されている ▪ .env ファイル(📌:2-5) → MY_SECRET_VAR(サーバーでのみ参照できる) → NEXT_PUBLIC_VAR(クライアント・サーバーで参照できる)
【実技】環境変数を参照してみよう 「NEXT_PUBLIC_」接頭辞がついた環境変数は、クライアントにも公開される -
第3章 Next.js の BFF SSR では環境変数が参照できる( 📌:2-6) ▪ gSSP で取得した環境変数は、 props
を経由すると… → フロントでも参照できてしまう → やってはダメ 【実技】環境変数を参照してみよう -
第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 エラー) 【実技】環境変数を参照してみよう -
第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 管理されてしまうので、クレデンシャル情報は含めないこと 【実技】環境変数を参照してみよう -
第3章 Next.js の BFF ✅ 環境変数定義の方法が豊富 ▪ .env ファイルを使用することで、環境変数が定義できる ▪ サーバーランタイムだけでなく、ブラウザランタイムでも参照できる
→ 「NEXT_PUBLIC_」接頭辞をつける → 露出して問題ない定数か注意する ▪ ビルドモードによって設定を細かく指定できる ▪ 環境変数はビルドタイムで決まる → ランタイムで決める方法もある → https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration 【実技】環境変数を参照してみよう -
第3章 Next.js の BFF API Routes とは? ▪ Next.js が提供する Web
API の構築方法 ▪ getServerSideProps と同様にサーバーサイドの処理ができる ▪ SPA で必要になる Web API が実装できる 【実技】Web API を試してみよう -
第3章 Next.js の BFF Cookie を使用した counter 実装(📌:2-8) ▪ http://localhost:3000/api/counter/memory ▪
リクエストを送るごとにインクリメント ▪ カウントは共有される 【実技】Web API を試してみよう トップレベル変数はサーバーメモリに(実際はこんな実装はほぼしない) -
第3章 Next.js の BFF Cookie を使用した counter 実装(📌:2-9) ▪ http://localhost:3000/api/counter/cookie ▪
リクエストを送るごとにインクリメント ▪ カウントは共有されない 【実技】Web API を試してみよう getServerSideProps と同様に Cookie を扱える -
第3章 Next.js の BFF ✅ API Routes はリクエスト検証付きの Web API 実装ができる
▪ 基本、ブラウザに表示された UI コンポーネントから利用される Web API → 値をフォームに入力・ボタンを押下 → 値を送信する先が、 API Routes(Web API) ▪ ログインユーザーに紐づいた情報の取得 ▪ VPC 内のバックエンド API サーバー(サブシステム)との連携に ▪ サーバーで実行されるため、クレデンシャル情報を扱える 【実技】Web API を試してみよう -
第3章 Next.js の BFF Next.js が Fullstack フレームワークと呼ばれる所以 ▪ SSR(getServerSideProps) ▪
Web API(API Routes) ▪ middleware 機能もある ✅ SPA と BFF を同時に構築できる Next.js は SPA フレームワークであり、 Web アプリケーションサーバーとして利用できる -
チャンクファイルとは? ▪ 一塊の JavaScript バンドルファイル ▪ ビルド時に確認できる → 共有ファイル 第4章 Next.js と
パフォーマンス チャンクファイルの分割 -
チャンクファイルとは? ▪ 一塊の JavaScript バンドルファイル ▪ ビルド時に確認できる → ページ毎のファイル 第4章 Next.js と
パフォーマンス チャンクファイルの分割 -
チャンクファイルとは? ▪ 一塊の JavaScript バンドルファイル ▪ ビルド時に確認できる → ページ毎の First Load
第4章 Next.js と パフォーマンス チャンクファイルの分割 First Load JS 量がグリーンのページはバンドルサイズが十分小さく、良好なページ -
チャンクファイルが分割されないとどうなるのか? ▪ どのエントリーポイント(ページのリクエスト)でも、全ページ分の取得 Web サーバー 第4章 Next.js と パフォーマンス チャンクファイルの分割 画面遷移
画面遷移 HTML 単一の HTML ファイル・JavaScript バンドルをレスポンス(古典的な SPA ) 大量のJavaScript 課題 JSON JSON /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト -
チャンクファイルが分割されないとどうなるのか? ▪ どのエントリーポイント(ページのリクエスト)でも、全ページ分の取得 Web サーバー 第4章 Next.js と パフォーマンス チャンクファイルの分割 画面遷移
画面遷移 HTML つまり、ページが増えるほどアプリの起動が遅くなる 大量のJavaScript 課題 JSON JSON /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト -
Web サーバー 第4章 Next.js と パフォーマンス ページ単位で、必要最低限のチャンクファイルが分割出力されるように ▪ 新規機能・新規ページを追加しても、既存ページの初期動作は遅くならない チャンクファイルの分割 必要最低限のJavaScript
必要最低限のJavaScript 必要最低限のJavaScript /page-a /page-b /page-c 分割 分割 分割 /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト -
第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) 分割 分割 分割 -
第4章 Next.js と パフォーマンス 静的ファイルだけで構成される時(静的サイトの場合)も分割される ▪ 動的ルートページを含む場合、 Web サーバー(Nginx 等)でルーティングが必要 → 分割されるため、静的サイトでも
Next.js 採用にメリット チャンクファイルの分割 必要最低限のJavaScript 必要最低限のJavaScript 必要最低限のJavaScript /page-a /page-b /page-c /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト Web サーバー(Nginx 等) 分割 分割 分割 -
第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 に触れます -
第5章 簡単なアプリを作ってみよう 簡単なブログアプリのサンプルを用意しました。 まずターミナルで、ブログデータを管理する Web API サーバーを起動しましょう。 ▪ $ cd api
▪ $ npm start 次に別ターミナルで、ブログアプリ(Next.js)サーバーを起動しましょう。 ▪ $ cd blog-pages-router-scaffold ▪ $ npm run dev 【実技】簡単なアプリを作ってみよう Web API サーバーはDBを使用していません。 投稿記事はメモリに保持されます(再起動すると初期化される) -
第5章 簡単なアプリを作ってみよう 以下のピンを検索し「記事一覧」ページを完成させましょう。 ▪ 📌:5-1 データ取得関数(@/fetchers/server)から、getPosts を import して使ってみよう ▪ 📌:5-2
getServersideProps で取得したデータが、ターミナルにログ出力されているか確認しよう ▪ 📌:5-3 各記事へのリンクリストをレンダリングしてみよう 【実技】「記事一覧」ページを完成させよう http://localhost:3000/posts が該当 URL です -
第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 です -
第5章 簡単なアプリを作ってみよう 以下のピンを検索し「記事作成」ページを完成させましょう。 ▪ 📌:5-12 「記事ID」が入力できるようにしてみよう ▪ 📌:5-13 「タイトル」が入力できるようにしてみよう ▪ 📌:5-14
「本文」が入力できるようにしてみよう ▪ 📌:5-15 「記事一覧に戻る」ボタンを追加してみよう ▪ 📌:5-16 「新規作成」ボタンを追加してみよう ▪ 📌:5-17 「新規作成」ボタンクリック時に form がサブミットされるようにしてください 【実技】「記事作成」ページを完成させよう http://localhost:3000/posts/new が該当 URL です -
第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 です