ブックマーク / zenn.dev/takepepe (35)

  • 実践Next.js - App Router への理解を深めるために -

    Next.js の App Router を中心に解説した書籍を執筆しました。「実践 Next.js —— App Router で進化する Web アプリ開発」というです(3/16 刊行)。稿では書籍の概要と、App Router が何を解決するのかについて紹介します。 書籍の概要 書籍で解説しているサンプルコードは、public リポジトリで既に公開しています。前半、第 1 章〜第 4 章では App Router の基礎を抑えるための練習用リポジトリを使用します。後半、第 5 章〜第 10 章では、写真を投稿する SNS「Photo Share」という架空アプリの実践的リポジトリを使用します。 第 1 章:Next.js の基礎 第 2 章:Server Component とレンダリング 第 3 章:App Router の規約 第 4 章:Route Handler 第 5

    実践Next.js - App Router への理解を深めるために -
    kkeisuke
    kkeisuke 2024/02/28
  • Next.js の fetchCache を考える

    Next.js App Router は global のfetch関数に patch をあてており、自動でデータ取得が最適化されるように設計されています。そのうちの一つが、取得したデータをキャッシュし、再利用する最適化です。キャッシュされた取得データは、必要に応じて任意のタイミングで Revalidate(データ再取得・キャッシュ更新)が可能です。稿はこのfetch関数を経由してキャッシュされる「fetchCache」について、どのように向き合うべきか考察したメモです。 検証留意点 はじめに、筆者が検証にあたり留意した点を書いていきます。稿を読んでみて「自分でも検証してみたい!」となった方は、参考にしていただければと思います。 【1】取得データがキャッシュされるタイミング タイミングは2通りあります。 ビルド時: next buildNext.js アプリをビルドした時 リクエス

    Next.js の fetchCache を考える
    kkeisuke
    kkeisuke 2023/07/08
  • Next.js Route Handlers でも tRPC 風の実装がしたい

    App Router で API Routes 相当の実装を施すには Route Handlers を使用します。Next.js に限らず React 実装では今後 fetch を使用したいというニーズが多くなると思うのですが、fetch は型推論がほとんどダメです。また、Client/Server で実装が散らばっているため、リクエスト・レスポンスのずれが生じる懸念があります。Route Handlers でも tRPC のような実装ができればと考え、それっぽい実装ができたので紹介します。 愚直に実装する場合 「書籍販売するサイトの詳細ページで、クリックログを送信する機能を実装する」と仮定して、詳細をみていきましょう。まず、クライアント側はこのようになります。ボタンコンポーネントを作成し、fetch を実行します。 "use client"; type Props = { bookId:

    Next.js Route Handlers でも tRPC 風の実装がしたい
    kkeisuke
    kkeisuke 2023/05/25
  • MSW を活用した WebAPI リグレッションテスト

    MSW はネットワークレベルでリクエストをインターセプトする、自動テストで便利なモックサーバーです。過去記事でも紹介したとおり、スパイ(モック関数)をネットワークレベルに忍ばせることが可能です。実際に WebAPI が呼ばれた時の Payload の検証は、Jest 組み込みのモック機能では実現できない領域です。稿は「WebAPI リグレッションテスト」を実施するための、MSW 活用方法を解説します。記事で使用しているサンプルコードはこちら。 課題の概要 Web アプリケーションページのほとんどは「1.UI を表示し/2.入力操作し/3.WebAPI 通信し/4.通信後処理を行う」という一連処理が責務です。このようなページに書かれるテストは、WebAPI 通信前後に集中しがちです。MSW を使用すると、以下の図の様に「送信後処理」まで到達可能なため、例えば「WebAPI レスポンスが返っ

    MSW を活用した WebAPI リグレッションテスト
    kkeisuke
    kkeisuke 2023/04/24
  • フロントエンド開発のためのテスト入門 - サンプルの紹介 -

    昨年から執筆を続けていた書籍が 4/24 に刊行します。「フロントエンド開発のためのテスト入門」というです。 書籍ならではのテストコード解説を目指して 次の投票結果は、書籍企画時に持ち込んだ筆者のツイートです。フロントエンドテストに関していえば、8 割近くの方が何かしら不安や不足を感じている、という結果になりました。 不安や不足の原因は様々なものがあるかと思います。そのうち、筆者が着目したのは「テスト手法の豊富さ」です。「単体テスト・結合テスト・E2E テスト、何をどれほど書けばよいのか?」という疑問は、フロントエンドに限らず、はじめて自動テストに取り組まれる方が通る関門ではないでしょうか。 自動テストを書くには「テスト対象」を明確にしたうえで、テスト対象に適したテストコードを書く必要があります。書は、現場で書かれるものに近い「テスト対象 = アプリケーションコード」をサンプルとして用

    フロントエンド開発のためのテスト入門 - サンプルの紹介 -
    kkeisuke
    kkeisuke 2023/04/06
  • Next.js の Zod 活用術

    年は Next.js + バリデーションライブラリの Zod をよく利用し、Zenn でもいくつかの関連記事を投稿しました。稿では、この組み合わせならではの TIPS を紹介します。記事で紹介するサンプルは以下に置いています。 リクエスト検証に便利な Zod Next.js で getServerSideProps を使用すると、リクエスト検証をサーバーサイドで行えます。例えばセッションに保持している値の検証はバリデーションライブラリの Zod を使用して、次のようなコードで実現できます。 export const userSchema = z.object({ name: z.string(), email: z.string(), }); export const getServerSideProps = async (ctx) => { const sess = await ge

    Next.js の Zod 活用術
    kkeisuke
    kkeisuke 2022/12/14
  • Next.js 13 結合テストに挑戦してみた

    Next.js 13 新機能の App ディレクトリの勉強がてら、結合テストをどう書いていったらよいか考察しました。参照している公式ドキュメントが beta 版なのはもちろん、App ディレクトリそのものが beta 版なので、実運用には使えるものではないと思うので予めご了承ください。一応こんな感じで書けそう、という話です。 結合テストの準備 稿が指す結合テストとは、App ディレクトリのルートセグメントを構成する、特別なファイル(Special Files)が、与えた状態に応じてどのように表示されるかを検証するテストを指します。 ルートが外部から受ける要因として大きいものが、URL に含まれるクエリパラメーター・パスパラメーターです。コンポーネントは、これらの値を参照して API サーバーにリクエストしたり、ORM ライブラリからクエリーを発行したりなど、コンポーネント表示に必要な処理

    Next.js 13 結合テストに挑戦してみた
    kkeisuke
    kkeisuke 2022/10/29
  • Next.js API Routes に Zod を組み込む

    バリデーションライブラリである Zod を、Next.js で活用する TIPS の紹介です。筆者が Zod を知り・使い始めたのは、React Hook Form のリゾルバーがきっかけです。ブラウザでバリデーションを行うので、不正な入力値検証を API リクエストが発生する前に実行できます。 この Zod はフロントだけではなく、サーバープロセスでも使用できます。例えば、tRPCZodiosなどに見られるように、サーバーへのリクエスト(入力値)を検証しつつ型推論も解決してくれるソリューションとして注目されています。 Next.js API Routes に Zod を組み込む Next.js には REST API の実装手段として、API Routes が提供されています。しかし、reqに含まれる入力値検証は自前で用意する必要があります。この入力値検証に Zod を使用されている方

    Next.js API Routes に Zod を組み込む
    kkeisuke
    kkeisuke 2022/10/14
  • リーダブルなテストのための、jest モックファクトリー関数

    単体テストを書く時、モジュール間の関連を検証するため、一部のモジュールをモックする必要が出てくることがあります。モックは様々な手法がありますが、書き方によって、メンテナンス性やテストの可読性が変わります。一般的に行われるモック手法を確認しつつ、よりリーダブルなテストを書く方法を紹介します。 ログイン API を呼び出す Web API クライアント 今回紹介する、モック対象の Web API クライアントです。Native Fetch API を関数でラップした、自作の Web API クライアント(ログインするためのlogin関数)です。 export type Data = { redirectUrl: string; }; export type Input = { email: string; password: string; }; export async function l

    リーダブルなテストのための、jest モックファクトリー関数
    kkeisuke
    kkeisuke 2022/09/01
  • React Hook Form でも再描画に気を付ける

    React Hook Form を使うと、useStateを使う制御フォームにありがちな「頻繁な再描画」を手短かに防ぐことができます。しかし、使い方によっては、その利点を崩してしまうことがあります。それが、useFormの戻り値に含まれるwatchの使用です。 watch は頻繁な再描画の原因になる 次のコンポーネントは、よくあるサインアップフォームです。emailに入力された文字数をカウントし、インタラクティブに「何文字入力されているか」を表示します。watchは、このような値の購読に利用できる API です。しかしコメントにあるとおり、emailに文字が入力されるたび、このフォーム全体が再描画されてしまします。これは、多くの要素を含むコンポーネントで避けたい実装例です。 const defaultValues: Form = { email: "", password: "", };

    React Hook Form でも再描画に気を付ける
    kkeisuke
    kkeisuke 2022/08/28
  • React コンポーネントの「制御・非制御」を意識しない方法

    React でフォームを作るとき「制御・非制御」コンポーネントに関する知識は必須です。デザインシステムを作成するにあたり、どちらを採用するか検討されたこともあるかと思います。 「制御・非制御」コンポーネントの差分を一言でまとめると、次のとおりです。 制御コンポーネントはライブラリ(React)が「入力要素の状態」を管理 非制御コンポーネントは「入力要素の状態」を DOM 自身が保持 「制御・非制御」コンポーネントと Form ライブラリ React Hook Form は、非制御コンポーネントを使うことで、少ないコード量で高パフォーマンスの Form 実装が実現できる人気のライブラリです。「非制御コンポーネント」として作成された<Checkbox>コンポーネントの例を見てみましょう。次の方法で<input type="checkbox" name="test" />がレンダリングされ、Fo

    React コンポーネントの「制御・非制御」を意識しない方法
    kkeisuke
    kkeisuke 2022/08/13
  • 私のフロントエンドディレクトリ構成・テスト観点 2022

    近日連投していた Next.js 記事のサンプルコードを公開しました。このサンプルコードを元に、私のフロントエンドディレクトリ構成・テスト観点を紹介します(あくまで執筆現在の脳内アウトプットになりますのでご了承ください) フロントエンドディレクトリ構成の事情 タイトルの「フロントエンドディレクトリ構成」をさす「Components」のディレクトリ構成は、いつも悩みのタネです。このモジュールシステムは「デザインシステム観点・アクセシビリティ観点・フロントエンド実装観点」の 3 つの観点が混在するため事情が複雑です。どうせ作るのなら「デザイナー・フロントエンド」どちらの開発基盤にもなりえる、盤石なモジュールシステムを目指したいですよね。 "AtomicDesign やめました"という声をたまに聞くのですが「デザインシステム的に捨てていいの?」と思うこともあるので、とくに要望がなければ、筆者は「

    私のフロントエンドディレクトリ構成・テスト観点 2022
    kkeisuke
    kkeisuke 2022/06/25
  • Next.js と MSW 高階関数

    稿では Next.js アプリ設計と同時に検討しておきたい、API Mocking の設計(MSW の活用テクニック)を紹介していきます。※ 解説のなかで jest を使いますが、ここは特別こだわりがあるわけではありません。 MSW で表現する API 群 MSW は Next.js アプリのローカル開発に役立ちます。任意の API を任意のレイヤーで、個別にインターセプト可能です。 「ブラウザー → API Routes」間でインターセプト 「API Routes → API 群」間でインターセプト 「getServerSideProps → API 群」間でインターセプト また、自動テストに利用でき、フロントエンドの単体・結合テストが書きやすくなります。同一プロセスでサーバーレスポンスをモックするため、外部プロセスに依存しない、高速な自動テストを回すことができます。 MSW 高階関数

    Next.js と MSW 高階関数
    kkeisuke
    kkeisuke 2022/06/17
  • Next.js に Service層 を導入する

    稿は、Next.js で「getServerSideProps や API Routes」を利用するアプリケーション向け内容になります。重厚な作りになるので、要件に適合する・しないはあると思いますので、あしからず。 Next.js は薄いフレームワーク Next.js は SPA 配信の最適化にフォーカスしており、Backend の機能面が十分とは言えません。pages の Page コンポーネントや API Routes は、controller としての機能を提供するのみです。ドキュメントを見てもわかるとおり、一連処理はあらかじめ middleware やラッパー関数を用意するのが常套手段かと思います。 NestJS にあるような Service 層が欲しい Node.js Backend フレームワークとして、NestJS は有力な候補かと思います。レイヤーやモジュール・DI の構

    Next.js に Service層 を導入する
    kkeisuke
    kkeisuke 2022/06/04
  • a11yとテストを同時に改善する話

    これまで、a11y 改善・テスト拡充にあたり「どのように改善すべきか?どのように書くべきか?」という点がハードルだと感じていました。Chrome で a11y tree を確認するには、dev tools の隅の隅をつつく必要があり、あまり体験の良いものではなく、気に入ったエクステンションもありませんでした。 Testing Library は「誰もがアクセスできるクエリー」を優先的に使用することを推奨していますが、アプリケーションがはじめから a11y に考慮された作りになっているとは限りません。これらの背景から「data-testid」のような、テスト向け属性に頼るワークアラウンドで乗り切ることも少なくありませんでした。 Full page accessibility tree 今年 1 月にリリースされたChrome98 の新機能として「Full page accessibility

    a11yとテストを同時に改善する話
    kkeisuke
    kkeisuke 2022/05/26
  • パフォーマンス観点でみる Next.js の getLayout

    Next.js は、ページ単位でデータ取得・レンダリング手法を選べる事が利点です。そして、ページ単位でチャンクファイルが生成されるため、パフォーマンスに貢献します。 これはあるページに来訪した際、必要最低限のファイルロードで済むということです。ファイルロードの時間は、ユーザーが操作開始できるまでの時間(TTI)に繋がります。Next.js でコーディングしていれば意識せずとも、ファイル分割の最適化は適用されます。 これだけでも SPA 構築に Next.js を選ぶ理由になりますが、ファイル分割は実装次第で、良くも悪くもなることを紹介していきます。 First Load JS shared by all _appは、どのページにアクセス・ナビゲーションしても、必ず通過します。そのため、_appに関連するファイルは 「First Load JS shared by all」 として、全てのペ

    パフォーマンス観点でみる Next.js の getLayout
    kkeisuke
    kkeisuke 2022/05/21
  • データ取得で try...catch しない理由

    try { const data = await fetchSomething(); // 正常系レスポンスの処理 } catch (err) { if (isAxiosError(err)) { // 異常系レスポンスの処理 } } 動機はつぎの 3 つです。 データ取得も宣言的に書きたいから データ取得に関係ない例外も catch してしまうから HttpError の集計に不便だから データ取得も宣言的に書きたいから 要約すると、データ取得時は常にこのように書きたい、という話です。useSWR・useQuery や apollo/client でお馴染みのインターフェイスです。 const { data, err, status } = await fetchSomething(); if (data) // 正常系レスポンスの処理 if (err) // 異常系レスポンスの処理

    データ取得で try...catch しない理由
    kkeisuke
    kkeisuke 2022/04/27
  • React.ComponentProps 型を積極的に使おう

    Atomic Design でいう Atoms に相当する、汎用コンポーネントについての小話です。次の様に Props 型定義を用意し、解説している記事をよく見かけます。<input />タグを使わずコンポーネント化している理由は style を施すためかと思いますが、このコンポーネントが受け取れる Props は限定的で、メンテナンスコストが高いためお勧めできません。 type Props = { value: string; onChange?: React.ChangeEventHandler<HTMLInputElement> onBlur?: React.FocusEventHandler<HTMLInputElement> } export const Input = ({ value, onChange, onBlur }: Props) => ( <input value=

    React.ComponentProps 型を積極的に使おう
    kkeisuke
    kkeisuke 2022/03/26
  • Storybook CSF の再利用・テスト拡充

    Storybook CSF は「再利用」を目的として策定されているよ、という文献をよく見ると思います。スプレッド構文で設定を継承するのはすぐ理解できることですが、CSF にはスプレッド構文以外にも有益な「再利用」の可能性が含まれています。これは、テスト拡充と深く関わる話です。 Jest + Testing Library 最大の欠点は「盲目」なこと Jest + Testing Library でテストを書いているとき、期待通りの UI 状態を再現できず、時間を溶かした経験はないでしょうか?これは、実際にブラウザで UI を確認しながら書くテスト(Cypress など)との大きな差です。 CSF3.0 で導入された Play function でインタラクションを与えることは「目視でテストケースを作れる」と捉える事が出来るので、Jest + Testing Library のテストがぐっと

    Storybook CSF の再利用・テスト拡充
    kkeisuke
    kkeisuke 2022/02/17
  • mswjs/data で広がるテスト戦略

    稿は MSW(Mock Service Worker)エコシステムのうちの一つ mswjs/data を試してみた記事です。記事中のサンプルコードは以下で公開しています。 mswjs/data とは 仮想 DB をブラウザ(インメモリ)に展開する、データモデリング・リレーションライブラリです。MSW 単体ではハードコードされたフィクスチャのみの定義となりますが、mswjs/data を併用することで、データ駆動型 API モックを作成することが可能になります。使い始めは簡単で、以下の様にスキーマを定義しfactory関数で DB インスタンスを生成します。 import { factory, primaryKey } from '@mswjs/data' const db = factory({ user: { id: primaryKey(String), firstName: Str

    mswjs/data で広がるテスト戦略
    kkeisuke
    kkeisuke 2022/01/21