がんばらないフロントエンド設計

# はじめに

自分はAngular、Vueに触れています。最近、数ヶ月掛けてようやく個人サービスをNuxt2からNuxt3にリプレイスし、モダンな知識を得たことで昔はこだわっていたフロントエンド設計についてがんばって考える必要がないんじゃないかと考え方が変わりました。これは経験上の考えで完全に主観なのでメモにでも残そうと思ったのですが、レベルの高い記事ばかりなのでたまには意識の低い記事があってもよいんじゃないかと思い書き残しました。

## 以前のフロントエンド設計に対する考え方

以前まではざっくりいうとAtomic Design＋クリーンアーキテクチャの考え方を取り入れてフロントエンド設計をしてました。イメージとしては↓の記事に近い感じでした

https://knowledge.sakura.ad.jp/36776/

難しすぎる:sob:

## がんばらないフロントエンド設計に対する考え方

行く着いた先は**Nuxtのディレクトリ構成に従う**でした。
Nuxtはディレクトリの責務が決まっており公式サイトにも明文化されているため、考える必要性がないのが利点です。考える必要がないということは共通認識をそろえる時間も少なくて済むということにもなります。ミニマムだと以下だけでも十分に機能するのではないかと思います。


```
|_assets
|_components
|_composables
|_layouts
|_pages
|_utils
```

ディレクトリの詳しい内容は公式で⇩
https://nuxt.com/docs/guide/directory-structure

ここは[bulletproof-react](https://github.com/alan2207/bulletproof-react)や「フロントエンド　ディレクトリ構成」とググれば良い記事が出てくるので参考にするのはどれでも良いかと思います。NuxtはCoC原則にもとづいているため強制力があるので僕は採用しています。

## 意識してること、やったこと

### Prettier、ESLintはまじめに使う:nerd:

適当にコードを書いてもそれっぽくなるので絶対導入するようにしています。書き心地を損なわない程度に少しだけルールを加えている感じです。

https://github.com/ikuosaito1989/nuxt3-template/blob/main/.eslintrc.cjs

### ESLintのエラーを解消するのが大変だったら無効化しちゃう:smiling_imp:

たとえばanyを禁止する`@typescript-eslint/no-explicit-any`を設定していますが、型定義が大変なところはすぐ無効化しちゃいます。行に対して無効化（`eslint-disable-next-line`）することで無効化コードを増やせば増やすほど不快になるため抑止効果があります。

### スタイルガイドに従う:nerd:

コードの良し悪しは主観が混じることも多いのでESlintとスタイルガイドに従った方が楽です。フレームワーク毎に色があるので使ってるフレームワークに沿って開発すれば良いと思います。

https://ja.vuejs.org/style-guide/

https://angular.jp/guide/styleguide

※ react詳しくないのでスタイルガイドがわかりませんでした:bow_tone1:

### Atomic Designをやめた:innocent:

5つの構成要素からコンポーネントの粒度を分けていくという設計手法ですがシンプルに難しいです。抽象的な表現のため、人によって解釈が異なったり、自分で設計していても見直すと違和感を感じることが多いです。またESLintの`max-lines`を守ればそれっぽいコンポーネント設計になるためあえてAtomic Designを考える必要性がないと感じました

https://eslint.org/docs/latest/rules/max-lines

### クリーンアーキテクチャをやめた:innocent:

これもシンプルに難しいです。今はComposition APIやHooksの登場により再利用性が高まったことでクリーンアーキテクチャに求めていた疎結合や関心の分離を満たすことが出来たためやめました。

### bulletproof-react参考にしてる:nerd:

Nuxtのディレクトリ構成に従うといったそばから矛盾していると思いますが、Nuxtのディレクトリ構成だけでは足りないところが出てくるのでReact開発におけるベストプラクティスであるbulletproof-reactを参考にしています。

https://github.com/alan2207/bulletproof-react

### npm、yarn、pnpm、bunなんでも良い:thinking:

パフォーマンスが良かったり、CommonJsが使える使えないだったり違いはありますがよくわからなければnpmかyarnをオススメします。僕はbunを使ってます。理由はアイコンがかわいいからです

https://bun.sh/

### テスト書かない:stuck_out_tongue_winking_eye:

個人的にテストは書いたほうが良い派（カバレッジを100%にしたい）のですが、状況によりけりだと思ってます。自分の中では責任の持てるプロダクトならテストをかかなくてよいが、責任を持てないプロダクトであればテストを書くという感じで考えてます。なので個人サービスは全く書いてません。

### (テストを書くなら)カバレッジはガンガン除外しちゃう:stuck_out_tongue_winking_eye:

1行カバレッジが満たせなくても品質は変わらないという気持ちで時間がなければ除外しちゃっても良いと思います。細部に神は宿ると言いますが、細部は別のアプローチでテストすれば良いんです！

https://jestjs.io/ja/docs/configuration#testpathignorepatterns-arraystring

### Tailwind CSSを入れた:couple_ww:

クラス書いてcss書くという手間がめんどくさいので導入するようにしています。また⇩の記事の考え方がシンプル（スタイルを再利用するならコンポーネントを作る）で好きです。

https://tailwindcss.com/docs/reusing-styles

### UIフレームワーク入れちゃう:couple_ww:

Tailwind CSSは低レイヤーのため、1からUIを作るのはなかなか大変です。手を抜いてリッチなUIを作りたいのでUIフレームワークを入れました。1つ注意としてはVuetify等のUIフレームワークを利用する場合はユーティリティクラスがコンフリクトするため、Tailwindでプレフィックスをつけて被らないようにするなど一工夫必要です。

Tailwind UIは高いから諦めた:sob::sob::sob:

https://tailwindui.com/

### ディープセレクタ（`:deep`）や`important`も使っちゃう:stuck_out_tongue_winking_eye:

ディープセレクタ（`:deep`）や`important`はアンチパターンとして知られていますが、必要であれば使ってます。ほとんどのフレームワークはscopedが使えるので影響も最小限に抑えられるためそこまで神経質にならなくてもよいかなと思ってます。

### グローバルステート(Global State)は極力使わない:smiling_imp:

どこでも使えるけど、どこで使われているかわからないから管理できません。ほんの一部しか使わないようにしてます。Reduxが流行った頃はグローバルステートを使いまくってましたが今となっては追えないので反省しています...

### husky入れない:stuck_out_tongue_winking_eye:

気軽にpushしたいので入れてません。`-no-verify`つけるのすらめんどくさいので入れてません。PRのトリガーでGitHub Actionsにてテストやらlintを設定しているため個人的には不要かなと思います。

https://github.com/typicode/husky

### DRY原則はどうしようもなくなったらやる:no_good_tone1:

特にフロントエンドにおいてはユーザーに近いということもあり、要件が頻繁に変わります。DRY原則を適用すると柔軟な変更を出来なくなる可能性が高いのでどうしようもなくなったらDRY原則を検討しても良いのではないかと思います。最近、こんな記事があって共感しました。

[コードに早まってDRY原則を適用しないこと」とGoogleが呼びかけ](https://gigazine.net/news/20240605-google-not-dry-prematurely/)


### オレオレライブラリを作らない:no_good_tone1:

例えばクエリストリングをパースするなど自前でも出来ますが、自前で作ると管理コストがかかるので[query-string](https://github.com/sindresorhus/query-string)を使ったりと極力自分で作るコードを減らすようにしています。

# まとめ

好きなように作れば良いと思います！！！