情報をより丁寧に残すための小さい思想 (2024)
Article
#設計
#TypeScript
#React
小さな思想とは、コードレビューで指摘するほどではないが、自分なりに工夫している点です。来年には変わるかもしれないので、今年のものとして記録しておきます。
それらはコードに限らず、情報をよりストレスなくより正確に伝えることが根幹の考えとしてあります。
コンポーネント名の最後に名詞をつける
// ✅
const WritingSection = () => {...}
// ❌
const Writing = () => {...}
コンポーネント名には、そのコンポーネントを表現する名詞をつけます。(例: XxxSection, XxxButton, XxxInput, XxxCard)
コンポーネントは結果として UI を提供するものであり、その情報は不可欠です。
フック名の最初に振る舞いをつける
// ✅
const useRenderDialog = () => {...}
// ❌
const useDialog = () => {...}
フック名には、そのフックが提供する振る舞いをつけます。(例: useRenderDialog, useSubmitUserForm)
フックは振る舞いを提供することが多いためです。ただし、振る舞いのみではない場合もあるため、状況に応じて判断します。
ファイル名は kebab-case、変数名は camelCase
// ✅
// confirm-dialog.tsx
const ConfirmDialog = () => {...}
const confirmDialogConfig = {}
// ❌
// ConfirmDialog.tsx
const ConfirmDialog = () => {...}
const CONFIRM_DIALOG_CONFIG = {}
ファイル名は kebab-case、変数名は camelCase で統一します。統一感を保つためです。
定数として CONSTANT_CASE を使用するパターンもありますが、変数は基本的に const であるため、 camelCase との境界が曖昧になってしまいます。そのため、変数は camelCase で統一します。
ファイルのメイン部分を上に置く
// ✅
export const Component = () => {...}
const config = {}
const styles = {}
// ❌
const config = {}
const styles = {}
export const Component = () => {...}
ファイルを開いたときに、その内容をすぐに把握できるように、メイン部分を上に置きます。
ただし、定義の順番の制約により難しい場合は、無理にこのルールに従う必要はありません。
条件が並列している場合は else や switch-case を使用する
// ✅
if (state === "loading") {
// ...
} else if (state === "error") {
// ...
}
// ✅
switch (state) {
case "loading":
// ...
break;
case "error":
// ...
break;
}
// ❌
if (state === "loading") {
// ...
}
if (state === "error") {
// ...
}
条件が並列している場合は、早期リターンや条件文を複数書くなどで分岐を実現するのではなく else や switch-case を使用しています。
条件が並列している場合は、それぞれの条件が独立していることを明確にした方が良いです。 (個人的には ts-pattern などを使用して、パターンマッチングをしたい)
rebase でコミットを整理する
# ✅
xxx feat(scope2): 新機能を追加
xxx feat(scope1): 新機能を追加
xxx refactor: リファクタリング
# ❌
xxx style: fix format
xxx fix: バグを修正
xxx feat(scope2): 新機能2を追加
xxx feat(scope1): 新機能1を追加
xxx feat(scope1): 新機能1のための部分的な機能追加
xxx refactor: リファクタリング
コミット履歴をわかりやすくするために、rebase で整理します。 コミットは細かすぎても良いとは思っていなく、その変更がプロダクトに残す情報なのかどうかとその影響するスコープで判断しています。 たとえば、フォーマットの修正はもちろん、ある機能を実現するための部分的な機能追加は、それだけでコミットを分けない方が良いです。
PR を作成する前に、ベースブランチに rebase もよくします。
実装について会話したら co-author でコミットする
# ✅
> fix(scope): バグを修正
>
> Co-authored-by: Author Name <[email protected]>
# ❌
> fix(scope): バグを修正
実装について他者と会話した場合、co-author でコミットします。コミットの著者を明確にするためです。 具体的な実装判断が自分だけではない場合、なぜこのコミットをしたのか後からわからなくなることがあります。 このときに co-author でコミットすることで、他のメンバーとの会話の結果であることがわかり、情報が鮮明になります。
ただし、他のメンバーが提案した具体的な実装から離れている場合は、co-author は入れていません。
半角文字と全角文字の間にスペースを入れる
// ✅
// value は number のみを許容する
// ❌
// valueはnumberのみを許容する
実装というより、文章についての思想です。 視覚的に詰まって見えないように、半角文字と全角文字の間にスペースを入れます。
コロンを使用する
// ✅
// value は次のような型を許容する:
// - number
// - string
// ❌
// value は次のような型を許容する
// - number
// - string
文章に関連性を持たせるために、コロンを使用します。前の文章に続く情報であることがわかりやすくなります。 ただ、これを機に調べているところ、私はこれまで誤用していることに気付きました。
おわりに
今回は自分の中にある小さな思想を言語化しました。
これらの思想は、正直自分でもまだ曖昧な部分もあります。 また、あくまで私の中での思想であり、それぞれのプロジェクトで適切な判断をする必要があります。