機能リクエスト投票サービス fequest (feature request の造語)を開発しています。
ユーザー向けと管理者向けの 2 つの Web アプリを構築中です。
開発中のコードは、以下のGitHubリポジトリで公開しています。
これまでは慣れたツールセットでスピード重視の開発を行っていましたが、今回は久しぶりに「試してみたい技術」を積極的に取り入れています。
以前はツール導入に全力を注ぎすぎて、肝心のアプリが完成しないこともありました。
ですが今は、AI のサポートによってセットアップが驚くほど簡単になったので、コーヒー片手に気楽に新しい技術を試しています。
モノリポ構成を採用し、モノレポツールには turborepo を利用しています。
さらに、UI コンポーネントやフィーチャーコードを自動生成するために turborepo のコード生成機能 turbo gen を使用しました。
アプリケーションフレームワークは Next.js 16 を採用しています。
巨人の肩には、もう少し乗っておきたいところです。
キャッシュコンポーネントはまだ使用していませんが、今後試してみたいと考えています。
「キャッシュ」という言葉には、どうしても少し抵抗があるんですよね……。
Next.js の設定には、以下の 2 点を追加しています。
Link の URL を型安全に扱える。pathpida が必要になるかもしれません。useMemo や useCallback を省略できる。また、PageProps インターフェースが自動生成され、params や searchParams に型安全にアクセスできるようになっています。
API 通信には、慣れ親しんだ tRPC を採用しました。
本来は packages/trpc として切り出す予定でしたが、DB や認証との依存関係が複雑だったため、現在は apps 内に配置しています。
eslint-config と typescript-config は、turborepo の create-turbo テンプレート由来で、そのまま利用しています。
バリデーションスキーマには Valibot を採用しました。
普段は Zod を使っていますが、Valibot は後発のスキーマバリデーションライブラリなので、試しに導入してみました。
軽量だと言われていますが、実際のところは未確認です。
Storybook v10 を使用し、フレームワークには @storybook/nextjs-vite を採用しています。
現時点では CSF 3 形式を継続使用中です。
v8.5 で Story にタグを付けてフィルタリングできる機能が追加され、v10 ではさらに「除外」もサポートされました。
これまでタグ機能をあまり意識していなかったので、今回知る良いきっかけになりました。
Vitest v4 を導入し、Storybook と連携したスナップショットテストを実行しています。
Story の play 関数にテストを書くのは少し抵抗があるため、現在は描画確認レベルのシンプルなテストにとどめています。
さらに、@storycap-testrun/browser を導入し、Storybook のテストランナー実行時に各 Story の VRT (Visual Regression Test) を自動実行するようにしました。
当初は Vitest や Storybook の公式機能で対応を試みましたが、うまく動作しなかったため、以下のアドオンを使わさせて貰いました。
vitest-config では Browser Mode ** の設定を行い、jsdom ではなく ** Playwright を利用した実 DOM テストを可能にしています。
これにより、await expect.element(el).toMatchScreenshot(); のような要素単位の VRT も実行できます。
現状では Story 単位の VRT で十分ですが、テストケースによっては使い分けも検討しています。
ui パッケージでは Tailwind CSS ** をデザイントークンとして使用し、 shadcn/ui** をベースに共通 UI コンポーネントを構築しています。
レイアウトコンポーネントは Chakra UI の思想を参考に自作しました。
以下のようなレイアウト系コンポーネントを用意しています。
BoxCenterContainerVStackHStackFlexGridまた、テキスト用の Text コンポーネントや、見出し用の Heading コンポーネントも定義しています。
CSS を書くのは好きなのですが、Tailwind を採用している以上、トークンベースで統一した方が保守性が高いため、スタイルはすべて Tailwind で管理しています。
このように、
という階層構造で UI を組み立てています。
デザイントークンをベースに、共通コンポーネントやレイアウトを使用しているため、基本的に tailwind の className はこのレイヤーまでで完結します。
ドメインレベルのコンポーネントでは、共通コンポーネントやレイアウトの variant を利用してスタイルを調整するため、直接 className を指定することは原則ありません。
全体としては、 Design Token-Based UI Architecture の考え方を意識し、 Option tokens → Decision tokens → Component tokens の三層構成でデザインを整理しています。
-
0
読み込み中...
タグ「フロントエンド」の記事
AI にコードを書かせた後、余計なコードを見つけて消す作業があります。 不毛なことなので、それらの作業を減らすためのお作法を紹介します。 未使用コードを消す 以下でも書きましたが、未使用コードの検査に knip を使うことが多いです。 ht
最近、iframeを使っています。 クライアントサイドで埋め込む想定で、iframeを使おうとしています。 色々と苦労したことがあったので、書いて残しておこうと思います。 レスポンスヘッダー 前提として、ウェブアプリケーションをプロダクショ
紙を積んだイラストをSVGで書こうとしていました。 (当たり前ですが)図形を表現するためには数学の知識が必要で、学生の頃の記憶を思い出したので疲れました。 所感について、諸々書こうと思います。 成果物 実際に完成したのは、以下の画像ができま
2026年02月17日