2024年のReact SPAプロジェクト構成
この記事は kb advent calendar 8 日目の記事です。
https://adventar.org/calendars/9546
2023 年は JavaScript の世界では Vite, Next.js の Turbopack などが浸透し、React アプリケーションの開発において Webpack を使わない開発が主流になり始めたのではないでしょうか。 世の中的には Next.js が非常に広く受け入れられている一方で、基本的にはデプロイ先に Node.js が動作するサーバ環境が求められるなど、動作環境が限られているという側面もあります。
Firebase Hosting, Netlify, S3 Hosting 等にデプロイ可能な静的な SPA を開発する場合、Vite を中心とした開発環境が非常にシンプルで扱いやすいです。 この記事では 2024 年に始める開発で十分に使えるプロジェクト構成を紹介します。
サンプルコード
すべてのコードはこちらの GitHub リポジトリ Push されています。
https://github.com/kamijin-fanta/react-boilerplate-2023
では早速プロジェクトで利用している構成技術を紹介します。
corepack
https://nodejs.org/api/corepack.html
yarn のバージョン固定に利用しています。
corepack はプロジェクトに設置された package.json
ファイルの "packageManager": "yarn@3.2.2",
といった記述を見た上で、適切なバージョンのパッケージマネージャをダウンロード・実行します。
システムで corepack enable
コマンドを実行することで、 npm
yarn
コマンドが corepack のものに置き換えられ、以降は package.json
を見た上で呼び出すコマンドを切り替えてくれます。
npm,yarn のバージョンが異なると package-lock.json
yarn.lock
の生成方法が異なったり色々と厄介な点が多いので、複数人開発では非常に重宝します。
Vite
Webpack に代わる主に SPA プロジェクトをビルドするためのバンドラーです。
バンドル・開発サーバ等の SPA 開発に必要な機能が一通り揃っています。 単体テストを非常に高速に実行する vitest も提供されています。
また Vite のプラグインに加え、内部で動作する Rollup 向けのプラグインを利用することで動作を拡張させることも可能です。
このプロジェクトでは React のトランスパイルなどを行う '@vitejs/plugin-react'
と 'vite-plugin-pages'
を導入しています。
vite-plugin-pages
https://github.com/hannoeru/vite-plugin-pages
Vite 等の環境にファイルシステム・ベース・ルーティング機能を追加するプラグインです。
例えば以下のようにファイルを配置したとします。
$ tree ./src
./src
├── App.tsx
├── main.tsx
└── pages
├── index.tsx
└── user
├── index.tsx
└── setting.tsx
そうすると、React Router などで利用可能な形式でオブジェクトを生成し、URL とファイルを以下のように紐づけます。
http://example.com/ -> pages/index.tsx
http://example.com/user -> pages/user/index.tsx
http://example.com/user/settings -> pages/user/settings.tsx
このように、ディレクトリ構造を元にしたルーティングを自動的に生成するので、React Router などのルーティング設定を手動で記述する必要がありません。
TypeScript
https://www.typescriptlang.org/
基本的に Vite 等のバンドラは TypeScript の型チェックを行いません。
型チェックを行うために "typescript"
パッケージの tsc
コマンドを利用します。
Prettier
JavaScript,CSS,Markdown などに対応したコードフォーマッタです。 設定項目が非常に少なく、記述スタイルを Prettier に任せるという気持ちが良いと思います。 他の言語で利用されるフォーマッタはユーザのコードを多少尊重するフォーマッタが多いですが、Prettier は括弧の位置・スペース量などを全て無視して常に Prettier のコーディングスタイルで上書きします。 導入によりスペース・タブキーの寿命が伸びることは間違いないです。
ES Lint
リンターです。
基本的に 'eslint:recommended'
'plugin:@typescript-eslint/eslint-recommended'
等のルールを利用していれば問題ないかと思います。
このプロジェクトでは追加で、インポート順を強制する eslint-plugin-import
を導入するなど多少カスタマイズしています。
ちなみに、ES Lint 内で Prettier のフォーマットを行う eslint-plugin-prettier
は通常推奨されないという位置づけになっていますので、素直に Prettier,ES Lint をそれぞれ単体で導入するべきでしょう。
Joy UI
https://mui.com/joy-ui/getting-started/
Material UI の機能は好きだけど、見た目がちょっと… となるケース無いですか? そんなときは Joy UI を利用しましょう。 Material デザインではない Material UI です。
現在開発中ですが、軽量なデザインでカスタマイズも容易です。 他のフレームワークとも頑張れば共存が可能です。
React Hook Form
フォームを簡単に扱うための Hooks ライブラリです。
TypeScript との相性がよく、パフォーマンスも良いのが特徴です。 フォームの入力内容を zod 等のバリデータで検証し、エラー表示を行うことも容易です。
まだ <input value={value} onChange={e => setName(e.target.value)} />
といった面倒なコードを何度も書いている方は、React Hook Form を使いましょう。
React Icons
https://react-icons.github.io/react-icons/
アイコンライブラリです。
私がメンテしているので公平に判断は出来ていないですが、それでもそこそこ使いやすいんじゃないかと思います。 1 つのパッケージをインストールするだけで、30 種類以上のアイコンセットを統一した方法で利用することが出来ます。
OpenAPI Generator
OpenAPI の JSON/YAML 定義から、TypeScript の API 定義を出力するためのライブラリです。 Java 等で記述されたジェネレータが多く、Node.js で目的のコードを出力するものは非常に少ないです。
このプロジェクトでは @himenon/openapi-typescript-code-generator を利用しています。 CLI が提供されずライブラリを利用するコードを自分で書く必要があったり少々癖もありますが、拡張性が高く多くのプロジェクトに適用できるのでは無いでしょうか。
他のプロジェクトはあまり利用したことが無いですが、 @autorest/typescript 等も活発にメンテナンスされています。
さいごに
Next.js を利用しないプロジェクト構成はあまり紹介されることが無いですが、Vite を中心とした開発体験は非常に快適ですので挑戦してみても良いのでは無いかと思います。