【重要】Next.js実装時はココを押さえて品質保とう!
はじめに
こんばんは。
こちらはだいぶ寒くなってきて毛布が手放せなくなってきたオーストラリア在住のケニーです。
前回までの記事ではテスト(Jest、E2E)の基本についてアウトプットしました。
最近は、テストの理解を深めていく事は、
【テストの重要性のみならず、品質を一定以上に保つ事に結び付く】
と痛感し始めましたので、品質を保つ事についてアウトプットしてみようと思います。
この記事の対象
ソースコードの品質管理について、
- 全然知らん!の方 :この際新たな知識のインプットに。
- なんとなく理解している方 :この際復習も兼ねて。
- 詳しいぜ!の方 :ケニーのアウトプットに間違いがないか。
目を通していただけますと嬉しいです!
TL;DR
以下を意識する事でテストの導入の敷居が低くなり、ソースコードの品質管理ができるようになる
1)できる限り機能分離する
⇒超重要:画面の処理とビジネスロジックの処理が一緒になっているのはNG。
2)関数は万能でつくらず、シンプルに。
例:formatterの関数ならformatterの仕事しかさせない。
それ以外も一緒にやるとNG。テスト導入時にも手間が一気に増える
3)識別子は超こだわる
4)letは極力使わない
では本題へ
※クリーンアーキテクチャの概念をベースに自分なりの今の考えを書いていくので、これが正解だとは限らないでしょうし、もしかしたら間違い等あるかもしれません。もしあれば優しくご指摘いただけますと嬉しいです。
余談)クリーンアーキテクチャとはRobert C. Martin(Uncle Bob)が2012年に提唱したDBやフレームワークからの独立性を確保するためのアーキテクチャ。詳細は今回は割愛します。
機能分離を意識する
機能分離がイメージしにくい場合、会社をイメージしてもらうと理解が進むかもしれません。
例えば、株式会社HOGEケニーには、以下のように機能分離をして事業を営んでいるとします。
株式会社HOGEケニー
+-- 営業部
| +-- 国内チーム
| +--東日本担当
| +--西日本担当
| +-- 海外チーム
| +--アジア担当
| +--オセアニア担当
+-- 開発部
| +-- フロントエンドチーム
| +-- バックエンドチーム
|(その他略)
このように細かく役割(機能)を分離することで、誰が何をやるっていうのが明確になり、
管理側は課題を見つけたり、カイゼンやチーム編成の修正等がしやすくなります。
このイメージを、実装に落としこんでいきます。
例:本のオンラインショップでの本の一覧画面をNext.jsで実装
(詳細のコードは割愛)
上記のような画面を実装する際、どう機能分離をするのが良いのか。
(上記図は、5分で作ったものなので、クオリティはご了承ください。。)
先に結論を書きます。
ディレクトリ構成の抜粋としては、以下のイメージになります。
web
+-- features(機能の塊)
| +-- books
| +-- index.tsx(一覧画面全体。バックエンドとの処理はここにまとめる)
| +-- bookContainer.tsx(本の一覧表を表示だけ)
| +-- bookList.tsx(本の一覧データを表示だけ)
| +-- logic(booksに関するビジネスロジックをここにまとめる)
| +-- logicA.tsx
| +-- logicB.tsx
| +-- test(logicに対するテストをここにまとめる)
| +-- logicA.test.ts
| +-- logicB.test.ts
+-- pages
| +-- books(本に関するページ)
| +-- index.tsx(routerのみ行う。中身はすべてfeaturesからインポート)
少し解説します。
1)pages/books/index.tsxの対象ページ
pagesは、あくまでルーティングさせるだけのページにする
例)本の詳細ページへの遷移
2)features/books/index.tsxの一覧画面全体
一覧画面全体を管理し、useHogehoge系の処理はすべてここで処理する
例)本の一覧データ取得、ページネーション処理、バリデーション等
3)features/books/bookContainer.tsxの本の一覧表
・本の一覧表に絞って、側を表示させる
・検索で入力されたキーワードは、features/books/index.tsxに渡す。ここでは処理しない
・親から渡されたページネーション情報をここで表示させる
4)features/books/bookList.tsx
features/books/index.tsxから渡された本の一覧データを表示させる
5)features/books/logic
features/booksに関するビジネスロジックはすべてここにまとめる
6)features/books/test
5)logicに対してのテストをここですべて実施し、品質担保する
はい、このように機能を分離させました。
ルーティングさせる機能、画面を表示させる機能、ビジネスロジック機能、テスト機能、といった具合に明確に役割を分けています。
ここでのポイントとしては、画面の処理とロジックの処理が一緒になっていない事です。
ロジックの処理を抽出することで、テスト導入の敷居がぐっと低くなります。
画面で機能分離を表すと以下のような感じ・・?
機能分離するメリット
- 可読性が増す
- 品質管理がしやすい
- メンテナンスや拡張に優れている
機能分離するデメリット
- ファイル数が多くなる
- (個人的に)慣れるまで大変
識別子は超こだわる
別記事で作成中なので、ここでは簡潔にアウトプットすると、
・(プロジェクトの)ルールに従って、
・略語は使わずなるべく簡潔に、
・第三者がみて中身がすぐイメージできるように、
命名する。といった感じでしょうか。
ifが続くケースはなるべく避ける
以下のようにifが続くケース見たことあると思いますが、
テストを導入する前提で実装する場合、できれば避けたい。
if (xxx) {
if(yyy) {
hogehoge
} else {
fugafuga
}
}
return
テストを導入する際、分岐が多くなればなるほど、大変になります。。
letは極力使わない
よく言われている事ですね。
途中で値が変わるので、処理を一個ずつ追わないといけなくなる為、
想定していないバグが発生する可能性が非常に高くなります。
(テストを実装する際も大変です)
終わりに
とりあえず機能するものを実装する「スピード重視」は理解はできるものの、
リリース後の保守運用等の長い目で見ると、プロジェクトスタートした段階からとりあえず上記を意識して実装していくと、グッと品質確保に繋がると思います!
只今、絶賛スキルアップ中ですので、次回も乞うご期待ください!♪
Discussion