👷

私が愛するフロントエンドのツールたち2023

2023/01/12に公開

自分がチームでフロントエンドの開発をするときの技術選定について書きます。
ログインしてユーザーごとに個別の情報を扱うことがメインのサービスを前提に書きます。

考え方

  • メンテナンス性の優れたものを選ぶ
  • 制限が少ないものを選ぶ
  • 余計なことに気を使わない
  • 一気にいろんなことに挑戦しすぎない

フレームワーク

https://nextjs.org/

正直に書くと最近は問答無用でNext.jsを選択しています。
慎重な性格なので、自分が責任を持って開発、運用するプロダクトであれば自分の経験値が高く、多くの課題をクリアできるNext.jsを選びます。
一部インフラの制約があるものの、ページごとにSSGやSSR、On-demand ISRなどができること、Reactの大きなエコシステムの恩恵を受けられることは非常に大きいです。
採用面でも現状Reactを扱える人は他のフレームワークを扱える人より多く感じます。

次点でCloudflare Workersを前段に置くこと前提で素のReact、Vue3、Svelte、Solid.jsなどのSPAフレームワークを検討します。

失敗してもいいから挑戦的な技術を使っていいと言われたらSvelteKitやQwik、Cloudflare WorkersによるService Bindingsを前提とする構成などを検討するかもしれません。

その他のシステムの場合

SSG前提のサイトであればAstro、大規模なシステムであればマイクロフロントエンドを念頭に置いて検討します

ビルド周りのツール

https://volta.sh/
https://yarnpkg.com/
https://www.typescriptlang.org/
https://eslint.org/
https://prettier.io/

volta

nodeバージョン管理にvoltaを採用します。
voltaを使うことには賛否あると思いますが、mac、Windows、Linux、Github ActionsなどのCIでも使用できるので気に入っています。
一部のCIで使用できないこと、volta以外のツールを使っている人と喧嘩になる可能性があることは懸念点です。
volta以外の優れたツールが提案された場合受け入れます。

yarn

yarn v1を採用することが多いです。
理由はありません。
特にトラブルが起きたことはないので採用しています。
深く考えていないことを明確にするため、あえて記載しておきます。

Typescript

必ず採用します。
tsconfigはできるだけ厳しい設定をし、srcディレクトリのaliasを設定します。

ESLint/Prettier

必ず採用します。
Eslintはimport/orderなどの設定します。
editor configをコミットして、ファイル保存時にPrettierによるコード整形を強制します。

CIでlintとbuildのチェックをします。
pre commitでチェックをすることもありますが、CIでチェックすればいいと思ってる派なので積極的には行いません。

UIフレームワーク

基本的に使用しません。
管理画面等デザイン性が求められないものであれば使用を検討します。

候補

CSS

https://tailwindcss.com/

基本的にはスタイルガイドに沿った、コンポーネントに閉じたスタイルを当てられればいいのでUtility Firstのフレームワークは適しているように感じます。
TailwindはUtility Firstのフレームワークの中でも成熟しているように感じるため、強い希望がない限り他のフレームワークを検討しません。
css modulesも要件にあっていますが、独自にcss変数を定義したり、レスポンシブの対応が面倒なのであまり選択しないです。
グラデーションを多様するなどデザインに特徴がある場合やShadowDOMを使用する場合、Tailwindを採用しないかもしれません。

Test

https://jestjs.io/
https://storybook.js.org/
https://mswjs.io/

前提としてフロントにできるだけビジネスロジックを書かないように設計します。
それでもフロントで対応せざるを得ないコードに対してjestでテストを書きます。
テストではないかもしれませんが、UIの確認にStorybookを使用します。
リグレッションテストをCypress、Autifyなどで書くこともあります。

Storybook

  • UIに責務を持つコンポーネントは状態に応じたstoryを作成します。
    • ただし汎用的なコンポーネントの場合、組み合わせが指数関数的に増えるのでstorybookのpropで確認できるようにします。
  • APIに依存するコンポーネントはmswでAPIをモックし、APIのレスポンス毎にstoryを作成します。
    • OpenAPIを使用する場合、OpenAPIのスキーマに定義したexamplesをmswのレスポンスに食わせてその単位でstoryを作成します。

API

https://www.openapis.org/

必ずスキーマファースト開発を採用します。
APIの実装を想像したり、実装を待ってからフロントの開発を着手することは効率が悪いです。
ほかを使いたい理由がなければOpenAPIを採用します。
OpenAPIで定義したexamplesをstorybookでも使用します。
gRPC、GraphQLを採用してもよいと思いますが、技術的に考えることは増えるのでよほどメリットがなければ採用しないことが多いです。

Formライブラリ

https://react-hook-form.com/
https://zod.dev/

react-hook-formを使用します。
バリデーションにはzodを使用します。
どちらも便利ですが複雑なことをやろうとすると難しいですね、、

API呼び出し

https://axios-http.com/
https://openapi-generator.tech/
https://tanstack.com/query/latest

OpenAPIのスキーマからtypescript-axiosのコードを生成します。
生成したコードをreact-queryから参照して使用します。
react-queryは便利ですが、keyの扱い等難しく複雑なことをしようとすると苦戦することもあります、、

aspidaについて

https://github.com/aspida/aspida
aspidaを使っていたこともありますが、以前のバージョンでOpenAPIの仕様に沿っていないコードが生成されたことがあったので、それ以降積極的に使っていないです。
おそらく現在は改善されていて、生成されるコードも好きなのでまた使いたいです。

修正履歴

  • タイトル変更

Discussion