はじめに
フロントエンド開発を任された際に、最低限意識しておくべきポイントについて備忘録的にまとめました。
参考程度に読んでください。
1. Atomic Designによるコンポーネント構造
コンポーネントの再利用性と保守性を高める目的
- Atoms(原子):ボタン、入力フィールド、ラベルなどの最小単位
- Molecules(分子):検索フォーム、メニューアイテムなどの小機能単位
- Organisms(生体):ヘッダー、フッター、商品カードリストなどの大機能単位
- Templates(テンプレート):ページのワイヤーフレーム
- Pages(ページ):実際のコンテンツを配置したページ
2. アセットとメタデータの管理
画像アセット
-
ロゴ:
- SVG形式が推奨
- 複数サイズの用意
-
ファビコン:
- 複数サイズ(16x16, 32x32, 180x180など)
- .ico, .png形式の用意
- Apple Touch Icon対応
-
OGP画像:
- 推奨サイズ:1200x630px
- ファイルサイズ最適化
- ブランディングの一貫性
- リンクによって動的に変更する要件がないか確認
メタデータとSEO対策
-
メタタグの実装:
- title, description
- OGPタグ
- Twitter Cards
- canonical URL
-
robots.txt設定:
- クロール制御
- サイトマップ指定
- 重要ページの優先度設定
3. ブラウザ対応とレスポンシブデザイン
対応ブラウザの選定
- モダンブラウザ(Chrome, Firefox, Safari, Edge)
- IE11対応の要否確認(必要な場合はポリフィル戦略)
- モバイルブラウザ(iOS Safari, Android Chrome)
レスポンシブ対応
-
ブレイクポイント:
- スマートフォン:375px~(iPhone SE対応)
- タブレット:768px~
- デスクトップ:1024px~
-
レスポンシブ実装:
- モバイルファースト
- フレキシブルグリッド
- fluid typography
4. パフォーマンスと最適化
フォント
-
Webフォントの選定:
- 基本フレームワークデフォルトのフォント + 無料フォント(Google Fontsなど)
- 商用フォントの場合はライセンス確認(Adobe系のフォントは有料)
- サブセット化による最適化
-
フォールバックフォント:
- システムフォントの指定
- FOIT/FOUT対策
状態管理とキャッシュ
-
状態管理:
- グローバル状態:Redux/Zustand/Jotai
- ローカル状態:useState/useReducer
- サーバー状態:React Query/SWR
-
キャッシュ戦略:
- ブラウザキャッシュ
- localStorage/sessionStorage
- Cookie(認証情報など)
状態管理とキャッシュは後から改修が難しいので早めに決めてドキュメントに残しておくと良い!
5. 開発基準とコーディング規約
デザインツール
-
Figma, Adobe XD
- レスポンシブデザインの要件があるならオートレイアウトを考慮したデザインが良い
- デザインツールからコード生成しようという取り組みは失敗するのでやらない方が良い
- やるならcssの出力程度
CSS設計方針
-
命名規則とスコープ:
-
命名規則:
- 役割に基づく命名(Block, Element, Modifier)
- 機能に基づく命名(utility-first)
- プレフィックスによる名前空間の分離
- セレクタのネスト制限
- 基本ネストした階層指定するよりはclassで指定する(コードレビューではじかれるはず)
- 必要になった時だけネスト指定を許す
- idの割り当て(テストコードでDOM指定するときに楽)
-
スコープ:
- グローバルスコープ
- コンポーネントスコープ
- 変数・ミックスインのスコープ
-
品質管理:
- スタイルガイドの作成
- 規模が大きくなったらドキュメントに残すことは大事
- Figmaなどのデザインツールかmiroなどのホワイトボードを使用して残しておきたい
- CSSリントの活用
- ESLint, Prettierを使いましょう
- レビュー基準の明確化
- デバイスやブラウザ別の確認など
- 型生成の効率化()
- バックエンド側がOpenAPI(Swagger)を使用していると
openapi-generator-cli
でクライアントコード生成も可能 -
openapi-generator-cli
は、APIドキュメントやスタブサーバーを作成可能
- バックエンド側がOpenAPI(Swagger)を使用していると
- スタイルガイドの作成
-
CSSフレームワーク
-
よく候補に挙がるCSSフレームワーク:
- Tailwind CSS
- 最近は一番先に候補として挙げている
- Material UI
-
Tailwind CSS
がダメって言われたらこちらを採用する(他PJでMUI使っていたから~、学習コストが~など)
-
- Ant Design
- 短期開発で「MUIではちょっと無理かも?」ってなったら使うことがある
- Chakra UI
- 毎回候補に挙げるけど選ばれたことはない
- Tailwind CSS
バリデーション
-
基本方針:
- エラーメッセージの一貫性
- 多言語対応を考慮した設計(i18n)
- エラーコードによる管理(運用時にコード管理しておくと問い合わせが楽)
- エラーハンドリングの統一
- 複数エラーの同時表示(「送信」ボタンクリック時に一番上のエラーに画面スクロールなど)
- フィールド単位のエラー管理
- グローバルエラー状態の管理(画面遷移する前にエラーとするなど)
- バリデーションのタイミング
- リアルタイムバリデーション(エラったら即表示?)
- サブミット時バリデーション(「送信」ボタンクリック時に表示?)
- Debounce/Throttleの適用(何起因発火?時間的な同期?)
- 再利用可能なバリデーションルール(おすすめ:Zod)
- 必須チェック
- 文字数制限
- フォーマット検証
- ビジネスロジック固有のルール
- 条件付きバリデーション
- 相関チェック
- エラーメッセージの一貫性
-
意識すること
- 文字数カウントはサロゲートペアにも対応しているか(絵文字などが2文字カウントされるか?)
- メールバリデーションはRFCに準拠しているか
- 何キャリアのメールまで対応する?
- 海外キャリアのメール通す?
コード品質管理(ESLint, Prettier)
リンター(ESLint)とフォーマッター(Prettier)をPJで設定する。
6. セキュリティとエラー処理
セキュリティ対策
-
CSPヘッダー設定(外部参照するscriptタグを埋め込むとき):
- XSS対策
- インラインスクリプト制御
- リソース読み込み制御
-
二重送信対策:
- デバウンス処理
- 送信ボタンの非活性化
- トークンによる制御
エラー管理
-
ログレベル定義:
- FATAL:システム停止につながる重大なエラー
- ERROR:業務に影響のある重要なエラー
- WARN:警告レベルの問題
- INFO:操作履歴など一般的な情報
- ユーザの操作などで出力
- DEBUG:開発時のデバッグ情報
- 関数の開始・終了などで出力
- TRACE:詳細なプログラムの実行追跡
国際化対応
-
技術的対応:
- i18nフレームワークの導入
- 言語切り替え機能
- 日時・数値のフォーマット
-
法的対応:
- EU圏の法規制確認(GDPR)
- Cookie同意取得の実装
- プライバシーポリシーの多言語対応
- 各国の個人情報保護法への対応
7. プロジェクト管理と品質保証
利用規約とプライバシーポリシー
-
法的要件:
-
必要な法令対応:
- 個人情報保護法
- 特定商取引法(ECサイトの場合)
- 電子契約法
- GDPR(EU圏対応の場合)
- CCPA(カリフォルニア州対応の場合)
-
業界固有の規制:
- 金融規制(バーゼル規制など)
- 医療情報規制(医療機能情報提供制度や医療情報システムの安全管理に関するガイドラインなど)
- 青少年保護規制(年齢確認必要か?)
- 広告規制(景品表示法や屋外広告物条例など)
-
-
利用規約:
-
サービス概要:
- サービスの定義
- 利用条件
- 利用制限事項
- 禁止事項
-
ユーザーの権利と義務:
- アカウント管理責任
- 知的財産権の取り扱い
- 投稿コンテンツの権利
- 損害賠償責任
-
運営者の権利と免責:
- サービス変更・停止条件
- 保証範囲
- 免責事項
-
-
プライバシーポリシー:
-
個人情報の取り扱い:
- 収集する情報の種類
- 利用目的の明示
- 第三者提供の範囲
- データ保管期間
-
ユーザーの権利:
- 情報アクセス権
- 訂正・削除権
- 同意撤回権
- データポータビリティ
-
Cookie・トラッキング:
- 使用目的の説明
- オプトアウト方法
- 第三者Cookie対応
- 広告トラッキング
-
ライブラリ管理
-
ライセンスチェック:
- ライセンスチェックの導入(license-checkerがおすすめ)
- PJで使用しているライブラリが商用利用可能なライセンスかチェックする
- CI/CDパイプラインでの自動チェックを検討
- 基本は開発環境デプロイ時にチェックしておけばOK
- バージョン上げた時も自動で検知できるようになる
- ライセンスチェックの導入(license-checkerがおすすめ)
非同期処理の設計
-
基本方針:
- Promise、async/awaitの適切な使用
- エラーハンドリングの統一
- まとめてエラーとするか
- エラったらすぐ落とすか
- キャンセル処理の実装
- 並列処理時のキャンセルどうするか(ファイルアップロード中のキャンセルなど)
-
同期/非同期の判断基準:
- ユーザー体験(UX)への影響
- パフォーマンスへの影響
- データの整合性への影響
UXデザイン
-
導線設計:
- ユーザの目的達成までの最短パス(ストーリーどうなっているかを重視)
- ユーザの目的達成までの最低限必要な機能を洗い出す(「〇〇あれば××もできる」は考えない。必要なコア機能だけ)
- 一番使われる機能は複数の導線を持たせたほうが良い(ヘッダーやメニュー、他ページに導線置いておくなど)
- エラー時の回復フロー
- Formでエラって毎回最初から入力はユーザが離脱する
- フィードバックの即時性
- Googleアナリティクスなどで分析して全然使われない機能などがあれば廃止の検討をする
- ユーザの目的達成までの最短パス(ストーリーどうなっているかを重視)
ビルド設定
-
gitignoreの設定:
- /build
- /node_modules
- 環境変数ファイル
-
package.json
はバージョン固定にしておく
パフォーマンス計測
-
Googleアナリティクス設定:
- コア Web バイタル
- ユーザー行動分析
- 一番アクセスのあるページは?離脱が多いアクションは?エラー率は?SNS拡散使われている?
- コンバージョン計測
コードレビュー
-
コードレベルのレビュー:
-
品質面(PJの決まり守ろう):
- 命名規則の遵守
- コードの重複排除
- 関数の単一責任
- 適切なコメント
- 型定義の適切さ
-
保守性(開発定型化しよう):
- コード関連
- 共通関数使わないで自前実装していないか(日付のフォーマットなどは共通関数で定義して再利用したほうが良い)
- テーブル(表)はページャ対応できているか
- 全件取得していない?
- 決められた件数ごとに表の切り替えできるか?
- 関数関連
- 1ファイルで1000行を超えてくると人間では読めないレベルに感じる
- 共通関数に業務ロジックが入っていないか
- 変更容易性
- 次の修正時、複数個所に影響を与えるような実装になっていないか
- コード関連
-
コーディング原則の遵守(とりあえず、書いとく):
-
DRY (Don't Repeat Yourself):
- コードの重複排除
- 共通処理の抽出
- 定数・変数の適切な利用
- ユーティリティ関数の活用
-
KISS (Keep It Simple, Stupid):
- 複雑な実装の回避
- 直感的な命名
- 明確な制御フロー
- 不要な抽象化の排除
-
YAGNI (You Aren't Gonna Need It):
- 必要最小限の実装
- 将来の拡張に過度に備えない
- 未使用コードの排除
- 過剰な柔軟性の回避
-
SOLID原則:
- 単一責任の原則
- オープン・クローズドの原則
- リスコフの置換原則
- インターフェース分離の原則
- 依存関係逆転の原則
-
-
パフォーマンス(無駄な処理消していけば勝手に観点に入っている):
- 不要な再レンダリング
- メモリリーク
- バンドルサイズ
-
-
デザインのレビュー:
- 画像の表示(画像存在しない場合どうなるか?ウイルススキャンされているか?など)
- フォントサイズ(他と統一とれている?)
- タッチ操作(2回クリックしてイベント2回実行されたりしない?)
- コンテンツの整列(文字多くても崩れない?)
- デザイン観点はテストで確認しても良いかも!
-
クロスブラウザ・デバイスのレビュー:
-
ブラウザ対応:
- 主要ブラウザでの表示確認
- Chrome
- Firefox
- Safari
- Edge
- 主要ブラウザでの表示確認
-
デバイス対応:
- スマートフォン
- iPhone(SE〜最新機種)
- Android(複数機種)
- スマホ設定の文字サイズを「大」にして崩れないか
- タブレット(必要に応じて)
- iPad(複数サイズ)
- Androidタブレット
- デスクトップ
- 異なる解像度
- 高DPIディスプレイ
- スマートフォン
-
8. テスト戦略
テストアプローチ
何でもテストしようとして後悔した(テスト自動化に失敗した)ので記載。
-
手動テストのアプローチ:
- 開発初期は仕様変更が頻繁に発生するので手動テストのほうが手戻りは少ない(いきなり自動化やろうとすると工数が2倍以上になっている気がする)
- クリティカルな機能のみテスト自動化を検討
- デグレ観点での自動化は有効
- 仕様変更と一緒にテストコードも改修していくことになるので膨らませないこと
- HARファイルをエビデンスにすると操作も追えて時短になる
- エビデンス収集に時間はかけない
- バグは出るもの
- テストケースが多くなれば人為的なミスは発生するのでトレードオフ
- カバレッジ100を目指すよりは重要なユースケース通すほうが価値は高い
-
テスト範囲の優先順位付け:
- 認証や決済機能など重要度の高い機能
- コア機能から品質担保していく
- データの整合性が重要な機能
- バグって一番困るところ
- パッチしようとしても壊れたデータだと無理
- ユーザーの使用頻度が高い機能
- ユーザの解約につながってしまうのでなるべく品質担保したい
- 認証や決済機能など重要度の高い機能
-
段階的な自動化の検討:
- 仕様が安定した後(コア機能の開発後)にE2Eテスト自動化を検討
- 回帰テストが必要な箇所から順次自動化
- CI/CDパイプラインへの組み込み
テスト階層の設計
-
単体テスト:
- コンポーネントの個別機能
- ユーティリティ関数
- カスタムフック
- カバレッジ(全部のコード通った?)
- 境界値(最小値や最大値の設定間違っていない?)
-
統合テスト:
- コンポーネント間の相互作用(ちゃんとデータ持って遷移する?)
- APIとの連携(タイムアウト何秒?)
- 状態管理の検証(リロードしてもデータ保持される?)
-
ユースケース・E2Eテスト:
- ユースケーステスト
- E2Eテスト
- デバイス・ブラウザ互換性
テストツールの選定
-
単体・統合テスト:Jest + React Testing Library
- 標準
-
E2Eテスト:Playwright
- 基本的にPlaywrightを使用する
-
APIモック:MSW(Mock Service Worker), json-server
- 必要に応じて