フロントエンドコード規約とエンジニアリング実践:ESLint + Prettier + Husky 完全セットアップ
前端工程
なぜチームにコード規約の自動化が必要か
2 つの実例です。
例 A:開発者 A は 2 スペースインデント、開発者 B は 4 スペース。コードレビューのたびに diff の 80% が空白と改行。レビュアーのエネルギーはフォーマットに消費され、ロジックの問題が見逃されます。
例 B:インターンがコードをプッシュし、npm run build はパス。main ブランチにマージした翌日、本番環境でエラー:「typo in variable name」。自動チェックがあれば、このコミットは pre-commit フックを通過できませんでした。
コード規約は「人を縛るルール」ではなく、「ツールで自動的に品質のベースラインを保証し、本当に価値のある判断に集中できるようにするもの」です。この記事は 3 つのチームでの実装経験に基づいています。
セットアップ後の効果
git add .
git commit -m "feat: ユーザーログイン機能を追加"
# Husky が pre-commit フックを自動起動
# → lint-staged がステージングファイルに ESLint --fix + Prettier --write を実行
# → commitlint がコミットメッセージ形式を検証
# → すべてパス → コミット成功
ESLint Flat Config:.eslintrc からの脱却
2024 年末、ESLint 9.x で Flat Config がデフォルトになり、古い .eslintrc.* は非推奨になりました。
Flat Config の基本構造
// eslint.config.mjs
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import globals from 'globals';
export default tseslint.config(
js.configs.recommended,
...tseslint.configs.recommended,
{
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
parserOptions: {
project: './tsconfig.json',
},
},
},
{
rules: {
'@typescript-eslint/no-unused-vars': ['error', {
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
}],
'@typescript-eslint/no-explicit-any': 'warn',
'no-console': ['warn', { allow: ['warn', 'error'] }],
'prefer-const': 'error',
'no-var': 'error',
'eqeqeq': ['error', 'always'],
},
},
{
ignores: [
'dist/**',
'node_modules/**',
'.next/**',
'coverage/**',
],
}
);
移行理由
| 旧形式 | 新形式 | 説明 |
|---|---|---|
.eslintrc.js / .eslintrc.json |
eslint.config.mjs |
単一の統一ファイル |
extends チェーン継承 |
tseslint.config() 合成 |
継承より関数合成 |
overrides + glob パターン |
設定オブジェクトの files |
より直感的 |
| プラグインを文字列名で指定 | import pluginX from '...' |
ネイティブ ESM インポート |
Prettier:フォーマットは専門ツールに任せる
// .prettierrc
{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2,
"arrowParens": "always",
"endOfLine": "lf",
"bracketSpacing": true
}
ESLint と Prettier の共存:
// eslint.config.mjs
import prettier from 'eslint-config-prettier';
export default tseslint.config(
// ... 前の設定
prettier, // 最後に配置し、競合する全ルールを上書き
);
Husky + lint-staged:コミット前に問題をブロック
npm i -D husky lint-staged
npx husky init
// package.json
{
"lint-staged": {
"*.{ts,tsx,js,jsx}": [
"eslint --fix --max-warnings=0",
"prettier --write"
],
"*.{json,css,scss,md}": [
"prettier --write"
]
}
}
# .husky/pre-commit
npx lint-staged
--max-warnings=0 により、警告 1 件でもコミットがブロックされます。
commitlint:コミットメッセージ形式の統一
npm i -D @commitlint/cli @commitlint/config-conventional
// commitlint.config.mjs
export default {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'feat', 'fix', 'docs', 'style',
'refactor', 'perf', 'test', 'chore',
'ci', 'revert',
],
],
'subject-case': [0],
},
};
正しいコミット形式:
git commit -m "feat: ユーザー認証モジュールを追加"
git commit -m "fix: トークン更新の競合状態を修正"
CI パイプライン統合
# .github/workflows/lint.yml
name: Lint & Format Check
on:
pull_request:
branches: [main, develop]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: 依存関係のインストール
run: npm ci
- name: ESLint 実行
run: npx eslint . --max-warnings=0
- name: フォーマットチェック
run: npx prettier --check "src/**/*.{ts,tsx,js,jsx,json,css}"
- name: 型チェック
run: npx tsc --noEmit
実際の移行経験
ステップ 1:フォーマットを先に、ルールは後で
# 1. まず Prettier でプロジェクト全体をフォーマット
npx prettier --write "src/**/*.{ts,tsx}"
# 2. フォーマット変更をコミット
git add .
git commit -m "style: Prettier で全ファイルをフォーマット"
# 3. ESLint ルールを段階的に有効化
ステップ 2:段階的な厳格化
// フェーズ 1:error レベルのみ
{
rules: {
'@typescript-eslint/no-explicit-any': 'warn',
'no-console': 'off',
'@typescript-eslint/no-unused-vars': 'error',
},
}
よくある落とし穴
落とし穴 1:ESLint Flat Config と VS Code プラグインの非互換
{
"eslint.useFlatConfig": true,
"eslint.options": {
"overrideConfigFile": "eslint.config.mjs"
}
}
落とし穴 2:Windows と macOS の改行コード衝突
.prettierrc に "endOfLine": "lf" を設定し、.gitattributes を追加:
* text=auto eol=lf
関連ツール
- JSON フォーマッター — 設定ファイルの検証と整形
- テキスト差分 — フォーマット前後のコード比較
- Base64 エンコード/デコード — ビルド成果物の分析
ブラウザローカルツールを無料で試す →
#ESLint#Prettier#代码规范#工程化#前端#教程