はじめに
自分はAngular、Vueに触れています。最近、数ヶ月掛けてようやく個人サービスをNuxt2からNuxt3にリプレイスし、モダンな知識を得たことで昔はこだわっていたフロントエンド設計についてがんばって考える必要がないんじゃないかと考え方が変わりました。これは経験上の考えで完全に主観なのでメモにでも残そうと思ったのですが、レベルの高い記事ばかりなのでたまには意識の低い記事があってもよいんじゃないかと思い書き残しました。
以前のフロントエンド設計に対する考え方
以前まではざっくりいうとAtomic Design+クリーンアーキテクチャの考え方を取り入れてフロントエンド設計をしてました。イメージとしては↓の記事に近い感じでした
難しすぎる
がんばらないフロントエンド設計に対する考え方
行く着いた先はNuxtのディレクトリ構成に従うでした。
Nuxtはディレクトリの責務が決まっており公式サイトにも明文化されているため、考える必要性がないのが利点です。考える必要がないということは共通認識をそろえる時間も少なくて済むということにもなります。ミニマムだと以下だけでも十分に機能するのではないかと思います。
|_assets
|_components
|_composables
|_layouts
|_pages
|_utils
ディレクトリの詳しい内容は公式で⇩
https://nuxt.com/docs/guide/directory-structure
ここはbulletproof-reactや「フロントエンド ディレクトリ構成」とググれば良い記事が出てくるので参考にするのはどれでも良いかと思います。NuxtはCoC原則にもとづいているため強制力があるので僕は採用しています。
意識してること、やったこと
Prettier、ESLintはまじめに使う
適当にコードを書いてもそれっぽくなるので絶対導入するようにしています。書き心地を損なわない程度に少しだけルールを加えている感じです。
ESLintのエラーを解消するのが大変だったら無効化しちゃう
たとえばanyを禁止する@typescript-eslint/no-explicit-any
を設定していますが、型定義が大変なところはすぐ無効化しちゃいます。行に対して無効化(eslint-disable-next-line
)することで無効化コードを増やせば増やすほど不快になるため抑止効果があります。
スタイルガイドに従う
コードの良し悪しは主観が混じることも多いのでESlintとスタイルガイドに従った方が楽です。フレームワーク毎に色があるので使ってるフレームワークに沿って開発すれば良いと思います。
※ react詳しくないのでスタイルガイドがわかりませんでした
Atomic Designをやめた
5つの構成要素からコンポーネントの粒度を分けていくという設計手法ですがシンプルに難しいです。抽象的な表現のため、人によって解釈が異なったり、自分で設計していても見直すと違和感を感じることが多いです。またESLintのmax-lines
を守ればそれっぽいコンポーネント設計になるためあえてAtomic Designを考える必要性がないと感じました
クリーンアーキテクチャをやめた
これもシンプルに難しいです。今はComposition APIやHooksの登場により再利用性が高まったことでクリーンアーキテクチャに求めていた疎結合や関心の分離を満たすことが出来たためやめました。
bulletproof-react参考にしてる
Nuxtのディレクトリ構成に従うといったそばから矛盾していると思いますが、Nuxtのディレクトリ構成だけでは足りないところが出てくるのでReact開発におけるベストプラクティスであるbulletproof-reactを参考にしています。
npm、yarn、pnpm、bunなんでも良い
パフォーマンスが良かったり、CommonJsが使える使えないだったり違いはありますがよくわからなければnpmかyarnをオススメします。僕はbunを使ってます。理由はアイコンがかわいいからです
テスト書かない
個人的にテストは書いたほうが良い派(カバレッジを100%にしたい)のですが、状況によりけりだと思ってます。自分の中では責任の持てるプロダクトならテストをかかなくてよいが、責任を持てないプロダクトであればテストを書くという感じで考えてます。なので個人サービスは全く書いてません。
(テストを書くなら)カバレッジはガンガン除外しちゃう
1行カバレッジが満たせなくても品質は変わらないという気持ちで時間がなければ除外しちゃっても良いと思います。細部に神は宿ると言いますが、細部は別のアプローチでテストすれば良いんです!
Tailwind CSSを入れた
クラス書いてcss書くという手間がめんどくさいので導入するようにしています。また⇩の記事の考え方がシンプル(スタイルを再利用するならコンポーネントを作る)で好きです。
UIフレームワーク入れちゃう
Tailwind CSSは低レイヤーのため、1からUIを作るのはなかなか大変です。手を抜いてリッチなUIを作りたいのでUIフレームワークを入れました。1つ注意としてはVuetify等のUIフレームワークを利用する場合はユーティリティクラスがコンフリクトするため、Tailwindでプレフィックスをつけて被らないようにするなど一工夫必要です。
Tailwind UIは高いから諦めた
ディープセレクタ(:deep
)やimportant
も使っちゃう
ディープセレクタ(:deep
)やimportant
はアンチパターンとして知られていますが、必要であれば使ってます。ほとんどのフレームワークはscopedが使えるので影響も最小限に抑えられるためそこまで神経質にならなくてもよいかなと思ってます。
グローバルステート(Global State)は極力使わない
どこでも使えるけど、どこで使われているかわからないから管理できません。ほんの一部しか使わないようにしてます。Reduxが流行った頃はグローバルステートを使いまくってましたが今となっては追えないので反省しています...
husky入れない
気軽にpushしたいので入れてません。-no-verify
つけるのすらめんどくさいので入れてません。PRのトリガーでGitHub Actionsにてテストやらlintを設定しているため個人的には不要かなと思います。
DRY原則はどうしようもなくなったらやる
特にフロントエンドにおいてはユーザーに近いということもあり、要件が頻繁に変わります。DRY原則を適用すると柔軟な変更を出来なくなる可能性が高いのでどうしようもなくなったらDRY原則を検討しても良いのではないかと思います。最近、こんな記事があって共感しました。
コードに早まってDRY原則を適用しないこと」とGoogleが呼びかけ
オレオレライブラリを作らない
例えばクエリストリングをパースするなど自前でも出来ますが、自前で作ると管理コストがかかるのでquery-stringを使ったりと極力自分で作るコードを減らすようにしています。
まとめ
好きなように作れば良いと思います!!!