「コミット直前にESLintとPrettierを必ず通したい」「壊れたコードがmainブランチに混入するのを防ぎたい」「コミットメッセージの体裁を統一したい」――そんな現場の悩みを解決するのが、Husky + lint-stagedの組み合わせです。本記事では、Husky 9・lint-staged 15 を基準に、pre-commit hook の構築、型チェック・テスト連動、commitlint による Conventional Commits の強制、monorepo 対応、CI との二重チェック設計まで、コピペで動く設定を 40 を超えるコードブロックで網羅的に解説します。
本記事の前提パッケージバージョンは以下の通りです。Node.js は 20 LTS 以上、パッケージマネージャは pnpm を主軸に扱いますが、npm / yarn / bun でも置換可能です。
| パッケージ | バージョン | 役割 |
|---|---|---|
| husky | ^9.1.7 | Git hook 管理 |
| lint-staged | ^15.2.10 | ステージ済みファイルのみに lint 適用 |
| @commitlint/cli | ^19.6.0 | コミットメッセージ検証 |
| @commitlint/config-conventional | ^19.6.0 | Conventional Commits ルール |
| eslint | ^9.17.0 | 静的解析 |
| prettier | ^3.4.2 | 整形 |
- Husky とは何か:Git hook を「コミットされた設定」として運用する
- lint-staged を組み合わせて「ステージ済みファイルだけ」を高速チェック
- TypeScript 型チェックを pre-commit で走らせる
- Vitest テストを pre-commit で連動させる
- commitlint で Conventional Commits を強制する
- pre-push hook でテストとビルドを最終チェック
- semantic-release と連携してバージョン自動化
- monorepo(pnpm workspace)対応
- Turborepo + Husky で並列実行
- GitHub Actions と Husky の二重チェック設計
- pre-commit hook の高速化テクニック
- Husky をスキップしたい時の安全策
- shellcheck で hook 自体の品質を担保
- Windows / WSL / Git Bash 環境で動かす
- CI 環境では hook を skip する
- 自動コミットメッセージ生成 hook
- PR テンプレートとの連携
- アンチパターン集
- トラブルシュート
- 実運用テンプレート(Next.js + TypeScript + pnpm)
- まとめ:Husky + lint-staged は「品質の最後の砦」
Husky とは何か:Git hook を「コミットされた設定」として運用する
Husky は .git/hooks/ ディレクトリを直接編集する代わりに、リポジトリ管理下の .husky/ ディレクトリに hook スクリプトを置き、git config core.hooksPath で読み替える仕組みです。Husky 9 以降は仕組みが大幅に簡略化され、シェバンや husky.sh の読み込み行が不要になりました。
Husky 9 のインストール手順
まずは新規プロジェクトに Husky を導入します。husky init は package.json への prepare スクリプト追記と .husky/pre-commit の生成を同時に行います。
# pnpm の場合
pnpm add -D husky
pnpm exec husky init
# npm の場合
npm install -D husky
npx husky init
# yarn の場合
yarn add -D husky
yarn dlx husky init
# bun の場合
bun add -D husky
bunx husky init
実行後、package.json に以下のスクリプトが自動で追加されます。prepare は pnpm install 時に自動実行されるため、チームメンバが clone 後に install するだけで hook が有効化されます。
{
"name": "my-app",
"version": "0.1.0",
"scripts": {
"prepare": "husky",
"dev": "next dev",
"build": "next build",
"lint": "eslint .",
"format": "prettier --write ."
},
"devDependencies": {
"husky": "^9.1.7"
}
}
生成される .husky/pre-commit の中身
Husky 9 が生成するファイルは極めて簡潔で、Husky 4 時代に必要だったシェバン行や . "$(dirname -- "$0")/_/husky.sh" はもう書きません。書くと逆に警告が出ます。
# .husky/pre-commit
npm test
このシンプルさが Husky 9 の特徴です。1 行目から実行コマンドを書くだけで動作します。Husky 8 以前から移行する場合は、不要なヘッダ行を削除してください。
lint-staged を組み合わせて「ステージ済みファイルだけ」を高速チェック
プロジェクト全体に eslint . をかけると数万ファイルでは数十秒かかります。lint-staged は git diff --cached で抽出したファイルだけに lint を実行するため、コミットあたりの待ち時間を 1〜2 秒に短縮できます。
lint-staged のインストールと package.json 設定
pnpm add -D lint-staged
package.json に lint-staged キーを追加し、ファイル拡張子ごとに実行コマンドを書きます。
{
"scripts": {
"prepare": "husky"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md,yml,yaml,css,scss}": [
"prettier --write"
]
},
"devDependencies": {
"husky": "^9.1.7",
"lint-staged": "^15.2.10"
}
}
.husky/pre-commit から lint-staged を呼び出す
# .husky/pre-commit
pnpm exec lint-staged
これだけで「ステージ済みファイルに ESLint と Prettier を自動適用 → 失敗したらコミット中止」という動作が実現します。npm 環境なら npx lint-staged に置き換えてください。
設定ファイルを切り出す:lintstagedrc.js
条件分岐やコマンド組み立てが複雑になってきたら、JS ファイルとして外出しできます。CommonJS でも ESM でも書けます(プロジェクトの "type" に合わせる)。
// lint-staged.config.js (CommonJS)
module.exports = {
'*.{ts,tsx}': (files) => [
`eslint --fix --max-warnings=0 ${files.join(' ')}`,
`prettier --write ${files.join(' ')}`,
],
'*.{js,jsx}': ['eslint --fix', 'prettier --write'],
'*.{json,md,yml}': 'prettier --write',
};
// lint-staged.config.mjs (ESM)
export default {
'*.{ts,tsx}': ['eslint --fix --max-warnings=0', 'prettier --write'],
'*.{js,jsx}': ['eslint --fix', 'prettier --write'],
'*.{json,md,yml}': 'prettier --write',
};
TypeScript 型チェックを pre-commit で走らせる
ESLint は型情報なしでも動く設定が一般的なため、tsc --noEmit による厳密な型チェックは別途必要です。ただし型チェックは「変更されたファイルだけ」を対象にできないため、運用に工夫が要ります。
NGパターン:ファイル単位で tsc を呼ぶ
// ❌ これは動かない(tsconfig.json が無視されパスエイリアスが解決できない)
module.exports = {
'*.ts': (files) => `tsc --noEmit ${files.join(' ')}`,
};
ファイル指定で tsc を呼ぶと tsconfig.json が読まれず、paths や baseUrl が無視されます。これは公式ドキュメントでも明記された制約です。
OKパターン:プロジェクト全体で型チェック
// lint-staged.config.js
module.exports = {
'*.{ts,tsx}': [
'eslint --fix',
'prettier --write',
// ファイル名を渡さず常にプロジェクト全体を検査する
() => 'tsc --noEmit -p tsconfig.json',
],
};
関数を返すことで「lint-staged が拾ったファイル名を捨て」、tsconfig ベースで全体チェックを行えます。大規模プロジェクトで遅い場合は --incremental を有効化しましょう。
// tsconfig.json
{
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": "./node_modules/.cache/tsbuildinfo",
"strict": true,
"noEmit": true,
"skipLibCheck": true
}
}
Vitest テストを pre-commit で連動させる
「変更ファイルに関連するテストだけ」を回したい場合、Vitest の --related オプションが有効です。
// lint-staged.config.js
module.exports = {
'*.{ts,tsx}': [
'eslint --fix',
'prettier --write',
(files) => `vitest related --run ${files.join(' ')}`,
],
};
vitest related は依存グラフを解析し、変更されたファイルを import しているテストのみを実行します。pre-commit に置く場合は必ず --run(watch しない)を付けてください。
テスト失敗時の挙動を制御する
# .husky/pre-commit
pnpm exec lint-staged
# テストだけは別扱いにし、CI 環境でないときだけ走らせる
if [ "$CI" != "true" ]; then
pnpm exec vitest --run --changed HEAD
fi
commitlint で Conventional Commits を強制する
「fix: ボタンが押せない」のような統一フォーマットを全員に守らせるには commit-msg hook で commitlint を走らせます。
インストール
pnpm add -D @commitlint/cli @commitlint/config-conventional
設定ファイル commitlint.config.js
// commitlint.config.js
export default {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'feat', // 新機能
'fix', // バグ修正
'docs', // ドキュメント
'style', // コードスタイル(動作に影響なし)
'refactor', // リファクタ
'perf', // パフォーマンス改善
'test', // テスト
'build', // ビルドシステム
'ci', // CI 設定
'chore', // その他
'revert', // revert コミット
],
],
'subject-case': [0],
'subject-max-length': [2, 'always', 100],
},
};
.husky/commit-msg を作成
# .husky/commit-msg
pnpm exec commitlint --edit "$1"
$1 には Git が用意したコミットメッセージファイル .git/COMMIT_EDITMSG のパスが渡されます。--edit オプションでファイルから読み込んで検証します。
正しいコミットメッセージの例
feat(auth): add OAuth2 login flow
Implement Google and GitHub providers using next-auth v5.
Includes session refresh and error fallback page.
BREAKING CHANGE: removed legacy /login endpoint
NG例(commitlint で弾かれる)
update auth # type が無い → 失敗
Feat: add login # 大文字 type → config によっては失敗
fix:add login # コロン後にスペース無し → 失敗
pre-push hook でテストとビルドを最終チェック
pre-commit は軽量に保ち、重い処理は pre-push に集約するのが定石です。
# .husky/pre-push
echo "🚀 pre-push: running full test suite..."
pnpm exec vitest --run --coverage
echo "🏗️ pre-push: type-check across all packages..."
pnpm exec tsc --noEmit
echo "✅ pre-push: ok"
これにより pre-commit は 2〜3 秒で完了し、push 時に 30 秒程度のフルテストを行うバランスが取れます。
semantic-release と連携してバージョン自動化
Conventional Commits を守れば、semantic-release が CHANGELOG 生成・npm publish・GitHub Release 作成までを完全自動化できます。
pnpm add -D semantic-release
@semantic-release/changelog
@semantic-release/git
@semantic-release/github
// .releaserc.json
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
["@semantic-release/changelog", { "changelogFile": "CHANGELOG.md" }],
"@semantic-release/npm",
[
"@semantic-release/git",
{
"assets": ["package.json", "CHANGELOG.md"],
"message": "chore(release): ${nextRelease.version} [skip ci]"
}
],
"@semantic-release/github"
]
}
feat: は minor、fix: は patch、BREAKING CHANGE: は major と自動判定されます。手動で npm version を叩く運用から解放されるのが大きな利点です。
monorepo(pnpm workspace)対応
monorepo では各パッケージ配下のファイルしか変更されないコミットでも、ルートで lint-staged を実行する設計が安定します。
ルート package.json
{
"name": "my-monorepo",
"private": true,
"scripts": {
"prepare": "husky"
},
"lint-staged": {
"*.{ts,tsx,js,jsx}": ["eslint --fix", "prettier --write"],
"*.{json,md,yml}": "prettier --write"
},
"devDependencies": {
"husky": "^9.1.7",
"lint-staged": "^15.2.10",
"eslint": "^9.17.0",
"prettier": "^3.4.2"
}
}
pnpm-workspace.yaml
packages:
- 'apps/*'
- 'packages/*'
パッケージごとに違うルールを当てる
// lint-staged.config.js
module.exports = {
'apps/web/**/*.{ts,tsx}': ['eslint --fix', 'prettier --write'],
'packages/ui/**/*.{ts,tsx}': [
'eslint --fix --config packages/ui/eslint.config.mjs',
'prettier --write',
],
'packages/api/**/*.ts': [
'eslint --fix',
() => 'pnpm --filter @myorg/api typecheck',
],
};
Turborepo + Husky で並列実行
Turborepo を入れていれば、lint-staged 内でも turbo run を呼べます。キャッシュが効くため、変更がないパッケージは即座にスキップされます。
// lint-staged.config.js
module.exports = {
'*.{ts,tsx}': [
() => 'turbo run lint --filter=...[HEAD^1]',
() => 'turbo run typecheck --filter=...[HEAD^1]',
],
};
// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"lint": {
"outputs": []
},
"typecheck": {
"dependsOn": ["^build"],
"outputs": []
},
"test": {
"dependsOn": ["^build"],
"outputs": ["coverage/**"]
}
}
}
GitHub Actions と Husky の二重チェック設計
ローカルで --no-verify を使われたり、Husky を install していないメンバが居ても CI で同じチェックを必ず通すのが正解です。
# .github/workflows/ci.yml
name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm exec eslint . --max-warnings=0
- name: Format check
run: pnpm exec prettier --check .
- name: Type check
run: pnpm exec tsc --noEmit
- name: Test
run: pnpm exec vitest --run --coverage
- name: Commitlint(PR タイトル)
if: github.event_name == 'pull_request'
run: echo "${{ github.event.pull_request.title }}" | pnpm exec commitlint
pre-commit hook の高速化テクニック
テクニック 1:lint-staged の並列実行を制御
lint-staged は標準で並列実行されますが、メモリを食う ESLint と TypeScript を同時に走らせるとマシンが固まることがあります。--concurrent で並列数を制限できます。
# .husky/pre-commit
pnpm exec lint-staged --concurrent 2
テクニック 2:–no-stash で I/O を減らす
lint-staged はデフォルトで未ステージ変更を stash しますが、ファイルが多いと数秒のオーバーヘッドになります。CI 環境やクリーンな状態でしか動かさない場合は --no-stash で省略できます。
# .husky/pre-commit
pnpm exec lint-staged --no-stash --concurrent 4
ただし未ステージ変更を巻き戻せなくなるため、ローカル開発者には推奨しません。CI でのみ有効にする運用が無難です。
テクニック 3:ESLint キャッシュ
// lint-staged.config.js
module.exports = {
'*.{ts,tsx,js,jsx}': [
'eslint --fix --cache --cache-location node_modules/.cache/eslint',
'prettier --write --cache --cache-location node_modules/.cache/prettier',
],
};
ESLint と Prettier は両者ともキャッシュをサポートしています。これだけで 2 回目以降の lint-staged が 3〜5 倍速くなります。
Husky をスキップしたい時の安全策
「WIP コミットなので一旦 hook を通さず保存したい」場面は確かにあります。--no-verify は危険なので、安全に運用する仕組みを用意しましょう。
方法 1:HUSKY 環境変数で一時停止
# 当該シェルだけ Husky 全停止
HUSKY=0 git commit -m "wip: tmp"
# 永続化したい場合
export HUSKY=0
Husky 9 では HUSKY=0 を渡すと .husky/* がすべてスキップされます。--no-verify と違い意図的にスキップした履歴が環境変数に残るため、レビュー時に検知しやすくなります。
方法 2:特定の hook だけ条件分岐でスキップ
# .husky/pre-commit
if [ "$SKIP_LINT" = "1" ]; then
echo "⚠️ SKIP_LINT=1 detected, skipping lint-staged"
exit 0
fi
pnpm exec lint-staged
shellcheck で hook 自体の品質を担保
Husky の hook はシェルスクリプトなので、shellcheck で静的解析できます。CI に組み込むと「全員の hook が壊れていないか」を継続検査できます。
# .github/workflows/shellcheck.yml
name: shellcheck
on: [pull_request]
jobs:
shellcheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ludeeus/action-shellcheck@master
with:
scandir: './.husky'
Windows / WSL / Git Bash 環境で動かす
Husky 9 は Windows ネイティブでも動きますが、いくつか落とし穴があります。
改行コードを LF に固定
# .gitattributes
.husky/* text eol=lf
*.sh text eol=lf
CRLF だとシェルが「コマンドが見つからない」エラーを返します。.gitattributes で必ず LF を強制してください。
Windows のパス区切り対応
// lint-staged.config.js
module.exports = {
'*.{ts,tsx}': (files) => {
// Windows でもスペース入りパスが壊れないようにシングルクォートで囲む
const list = files.map((f) => `'${f}'`).join(' ');
return [`eslint --fix ${list}`, `prettier --write ${list}`];
},
};
CI 環境では hook を skip する
CI で pnpm install すると prepare スクリプトで Husky が走ろうとし、Git ディレクトリが無い環境でエラーになることがあります。これを回避する標準パターンが以下です。
// package.json
{
"scripts": {
"prepare": "node -e "if (process.env.CI !== 'true') require('child_process').execSync('husky', { stdio: 'inherit' })""
}
}
または公式推奨の Husky 9 用ワンライナー:
{
"scripts": {
"prepare": "husky || true"
}
}
|| true で失敗を吸収します。CI 上では Husky のセットアップは不要なので、エラーを無視して install を続行させるのが目的です。
自動コミットメッセージ生成 hook
prepare-commit-msg hook を使うと、ブランチ名から自動でプレフィックスを付けるなどの自動化が可能です。
# .husky/prepare-commit-msg
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
# feature/123-add-login というブランチから feat(#123): をプレフィックスに
if [ -z "$COMMIT_SOURCE" ] && [[ $BRANCH =~ ^feature/([0-9]+) ]]; then
ISSUE="${BASH_REMATCH[1]}"
CURRENT_MSG=$(cat "$COMMIT_MSG_FILE")
if [[ ! $CURRENT_MSG =~ ^feat ]]; then
echo "feat(#$ISSUE): $CURRENT_MSG" > "$COMMIT_MSG_FILE"
fi
fi
PR テンプレートとの連携
commitlint で守られた Conventional Commits を、PR タイトル検査でも適用します。
# .github/workflows/pr-title.yml
name: PR title
on:
pull_request:
types: [opened, edited, synchronize, reopened]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
docs
refactor
perf
test
build
ci
chore
revert
# .github/pull_request_template.md
## 変更の種類
- [ ] feat: 新機能
- [ ] fix: バグ修正
- [ ] refactor: リファクタ
- [ ] docs: ドキュメント
- [ ] chore: その他
## 概要
## 動作確認
- [ ] `pnpm test` がローカルで成功
- [ ] `pnpm exec tsc --noEmit` が成功
- [ ] スクリーンショット添付(UI 変更がある場合)
アンチパターン集
アンチパターン 1:pre-commit に重いビルドを置く
# ❌ NG: コミットのたびに 30 秒待たされ、開発者が --no-verify を多用するようになる
# .husky/pre-commit
pnpm run build
pnpm exec vitest --run --coverage
重いタスクは pre-push か CI に逃がしましょう。pre-commit は2 秒以内を目標に設計します。
アンチパターン 2:lint-staged で全ファイルを対象にする
// ❌ NG: ステージ済みファイルだけを対象にする lint-staged の意味がなくなる
{
"lint-staged": {
"*": "eslint ."
}
}
アンチパターン 3:Husky 4 時代のヘッダ行を残す
# ❌ Husky 9 では不要(警告が出る)
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm exec lint-staged
Husky 9 では純粋なコマンドだけ書けば OK です。
アンチパターン 4:eslint-config-prettier を入れずに両方走らせる
ESLint のフォーマット系ルールと Prettier がぶつかり、保存するたびに整形が往復します。必ず eslint-config-prettier を ESLint 設定の最後で extends してください。
// eslint.config.mjs
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import prettier from 'eslint-config-prettier';
export default [
js.configs.recommended,
...tseslint.configs.recommended,
prettier, // ← 必ず最後
];
トラブルシュート
症状 1:Husky install しても hook が動かない
# 原因確認:core.hooksPath が .husky を指しているか
git config core.hooksPath
# 期待値: .husky/_
# 違う値が返るなら、再 init で直す
pnpm exec husky init
症状 2:lint-staged が「No staged files found」で終わる
# git add し忘れ、または .gitignore で対象が除外されている可能性
git status
git diff --cached --name-only
# どのファイルがステージ済みか必ず確認
症状 3:commitlint が hook で動かない
# .husky/commit-msg を直接実行して再現する
sh .husky/commit-msg .git/COMMIT_EDITMSG
# pnpm exec が見つからない場合はパスを通す
export PATH="$PATH:/usr/local/bin:$HOME/.local/share/pnpm"
症状 4:VSCode の Source Control タブからコミットすると hook が動かない
VSCode は親プロセスの PATH を引き継ぐため、nvm や Volta で入れた Node が見えないことがあります。VSCode 設定で "terminal.integrated.inheritEnv": true にするか、Node のフルパスを .husky/* に書きます。
# .husky/pre-commit(Node のパスを明示)
export PATH="$HOME/.volta/bin:$HOME/.nvm/versions/node/v20.18.0/bin:$PATH"
pnpm exec lint-staged
症状 5:Husky 8 から 9 にアップグレード後、警告が出る
husky - DEPRECATED
Please remove the following two lines from .husky/pre-commit:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
表示の通り 2 行を削除すれば解決します。1 ファイルずつ確認し、コマンド行だけ残します。
実運用テンプレート(Next.js + TypeScript + pnpm)
最後に、Next.js プロジェクトでそのまま使えるテンプレートを示します。Husky 9・lint-staged 15・commitlint 19 を組み合わせた、現場標準の最小構成です。
// package.json
{
"name": "next-app",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint .",
"format": "prettier --write .",
"typecheck": "tsc --noEmit",
"test": "vitest --run",
"prepare": "husky || true"
},
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix --cache --max-warnings=0",
"prettier --write --cache"
],
"*.{js,jsx,mjs,cjs}": [
"eslint --fix --cache",
"prettier --write --cache"
],
"*.{json,md,yml,yaml,css}": "prettier --write --cache"
},
"devDependencies": {
"@commitlint/cli": "^19.6.0",
"@commitlint/config-conventional": "^19.6.0",
"eslint": "^9.17.0",
"eslint-config-prettier": "^9.1.0",
"husky": "^9.1.7",
"lint-staged": "^15.2.10",
"prettier": "^3.4.2",
"typescript": "^5.7.2",
"vitest": "^2.1.8"
}
}
# .husky/pre-commit
pnpm exec lint-staged --concurrent 2
# .husky/commit-msg
pnpm exec commitlint --edit "$1"
# .husky/pre-push
echo "🔍 pre-push: typecheck"
pnpm exec tsc --noEmit
echo "🧪 pre-push: tests"
pnpm exec vitest --run
// commitlint.config.js
export default {
extends: ['@commitlint/config-conventional'],
};
まとめ:Husky + lint-staged は「品質の最後の砦」
本記事では Husky 9・lint-staged 15 を中心に、pre-commit hook の構築から TypeScript 型チェック・Vitest 連動・commitlint による Conventional Commits 強制・monorepo 対応・GitHub Actions との二重チェック・パフォーマンス最適化・トラブルシュートまでを通しで解説しました。要点をもう一度整理します。
- Husky 9 は
husky init一発で導入完了。シェバン行は書かない。 - lint-staged はステージ済みファイルだけを対象にし、ESLint と Prettier は
--cacheを必ず付ける。 - 型チェックはファイル単位ではなくプロジェクト単位で実行する。
--incrementalで高速化。 - commit-msg hook と commitlint で Conventional Commits を強制し、semantic-release で版管理まで自動化。
- 重い処理は pre-push か CI に逃がし、pre-commit は 2 秒以内を死守する。
- CI 上では
prepare: "husky || true"で失敗を吸収。GitHub Actions で必ず同じチェックを再実行し二重防御。 - monorepo は Turborepo の
--filter=...[HEAD^1]で差分パッケージだけを検査。 - Windows 環境は
.gitattributesで LF 強制。VSCode から動かないときは PATH を明示。
Git hook は地味な仕組みですが、チーム開発において「壊れたコード・統一感のないコミット」を未然に防ぐ最後の砦です。本記事のテンプレートをそのまま自プロジェクトに貼り付け、コミット品質の底上げを今日から始めてください。
関連記事として、ESLint 9 と Prettier 3 の Flat Config 詳細設定は ESLint 9 + Prettier 3完全設定ガイド、Monorepo の並列ビルド最適化は Turborepo + pnpm workspaceでMonorepo構築完全ガイド も併せてご覧ください。Web フロントエンドエンジニアとしてのキャリアを伸ばしたい方は テックアカデミー や 侍エンジニア のようなマンツーマンメンタリング型スクールも実務 Tips の即時習得に有効です。

コメント