💊

【React×TypeScript】フロントエンドコーディング規約に取り入れてよかったもの

2024/04/23に公開

はじめに

今回はフロントエンドチームで運用しているコーディング規約で、取り入れてよかったものをいくつか紹介します。

コーディング規約を決める目的は以下の2つだと考えます。

  • 可読性、保守性を高めること
  • 一定の品質を担保すること(誰が実装するかによって品質が著しく低下しないようにする)

まずは規約を作成する目的から考え進めてみると良いかと思います。

技術

主要技術は以下です。

  • React
  • TypeScript
  • TailwindCSS
  • Jest

命名規則について

  • 定数は全て全て大文字でスネークケースで記述すること
export const NUMBER = {
  ARRAY_INITIAL_INDEX: 0,
}
  • 配列やオブジェクトなど、複数のデータがある場合、変数名は複数形にすること
const users = [
 { id: 1 , name: 'taro' },
 { id: 2 , name: 'hanako' },
]
  • 関数名の始まりは動詞を用いること
    • 名前の短さよりも分かりやすさを優先して命名する、名前が長くなることを気にしすぎない

変数/定数宣言について

  • 変数の宣言にはconstを使用し、let、varは使用しないこと
    • 再代入は禁止し、オブジェクト型や配列に関しても、値の操作は行わないこと
以下は禁止❌

const user = { id: 1 , name: 'taro' }
user.name = 'hanako'

引数について

  • 複数引数を受け取る場合は、第一引数をオブジェクトで受け取る
    • 関数の呼び出し元でどのようなデータが必要かが明確になる
    • 新しい引数を追加しやすい
    • 引数の順序を覚える必要がなくなる
type Props = {
    dividend: number;
    divisor: number
}

const divideNumber = ({dividend, divisor}: Props) => {}

共通関数・コンポーネントについて

  • 共通関数・コンポーネントは責務は小さくシンプルにすること
  • 必ずしも共通化せずに、複雑になる場合は新しい関数・コンポーネントを作ること

コメントルールについて

記述 意味
TODO: 修正が必要なもの
NOTE: コードの説明を記載
/** */ 定数、変数名の名称/補足などを記入
  • コメントを記載するときは、上記のアノテーションをつけること
  • TODOコメントを残すときは、issueを作成し、issue番号を記載すること
  • コード上で読み取れる内容をわざわざコメントに書かないこと
const users = [
 { id: 1 , name: 'taro' },
 { id: 2 , name: 'hanako' },
]

以下は不要❌
<!-- NOTE: ユーザーを特定  -->
const findUser = users.find((user) => user.id === id )
  • JSDocコメントは努力義務で記載すること(ロジックが複雑な場合や分かりにくい場合)

ハードコーディングについて

  • ハードコーディングは禁止
  • マジックナンバーは原則禁止
    • 0 など、初期化のための値は例外とする

Reactについて

  • コンポーネントは関数コンポーネントで定義、hookを使用すること
  • フラグメントは<></>を使用する→必要のないフラグメントは削除すること
  • 関数は原則アロー関数で定義すること
  • 関数コンポーネントの引数(props)は分割代入で受け取ること
type Props = {
    name: string
    age: number
}

const MyComponent({ name, age }: Props) ==> { 
  • 関数コンポーネントはdefault exportとし、それ以外はnamed exportにすること
  • 1ファイル内で書くソースは500行を目安とすること
    • 超えてしまう場合はリファクタリングを検討すること

react-hookについて

  • useEffectについては原則使用しないこと
    • まずは使用しない方向で考えてみて、useEffect以外の手段がない場合のみ使用する
  • useMemo、useCallbackについても原則使用しないこと
    • パフォーマンス改善をする必要がある場合のみ使用を検討すること

TypeScriptについて

  • 型はtypeで定義すること
  • 関数の返り値の型記入は努力義務とする。必要に応じて型を指定したい場合のみつけること
  • 原則anyを許容しない
    • ライブラリを使用していて、やむを得ない場合に関してはanyを許容
    • anyを使用する場合はコメントにて補足すること
  • asを使った型アサーションは原則使用しないこと
    • TypeScriptを使うメリットが薄まってしまう

TailwindCSSについて

  • CSSは原則書かないこと(TailwindCSS側で用意されているクラス名で対応すること)
  • baseクラスについてはindex.cssにて記載(.body{}など)
  • コンポーネント内のスタイルオーバーライドに関してはwhere:を使用すること
  • 汎用性のあるものはtailwind.configに定義すること
    • デザインシステムにて定義されているもの
    • colorfontFamilyfontSizefontWeightzIndexbordeRadiusboxShadowに関してはtailwind.configで定義したもの以外の使用を禁止とする(ベタ打ち禁止とする→bg-[#fff]など)
  • 動的にクラス名を生成することは不可能なので注意すること
  • 変数にクラス名を持たせないこと
NG
const buttonClassName = 'bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded' 
  • clsx使ってクラスをグルーピングして可読性の向上に努めること
    • flex、propsによる条件分岐、タイポグラフィ、positionなど
    <button
      type='button'
      className={clsx(
        // flex系
        'flex items-center',
        // タイポグラフィ系
        'text-[14px] text-white font-bold',
        // 条件分岐など
        disabled && 'pointer-events-none opacity-40'
      )}
    >
      {children}
    </button>

テストコードについて

  • 1関数に1テストケースは原則書くこと
  • 要素を取得する際に、Tailwindクラスを使用して取得しないこと(スタイル変更時に落ちる可能性があるため)

その他

  • 改行に<br />は使用しないこと

おわりに

普段は複数人のフロントチームで開発を行っていますが、コーディング規約を導入することで一貫性のあるコードが多少は書けていると思います。

またチーム全員がコーディング規約にメリットを感じているので形骸化することなく運用できています。

コードの一貫性などに課題をお持ちの方は、まずは小さくでも良いので規約を作成してみることから始めると良いかと思います。

Discussion