Next.js エンジニアリング設定:ESLint + Prettier + Husky オールインワン構築ガイド

金曜の夜の悪夢
先週の金曜日の夜のことを覚えていますか? パソコンを閉じて帰ろうとしたその時、Slackで技術責任者からメッセージが届きました。「君のPR、フォーマットの問題が多すぎるよ。直してから再提出してくれる?」GitHubを開くと、画面いっぱいの赤いdiff。ダブルクォートを使っているところもあれば、インデントがバラバラなところもありました。
正直、無力感に襲われました。コミットする前に npm run lint を実行したはずなのに、なぜまだ問題があるのでしょうか? さらに気まずかったのは、チームの別の同僚も似たような状況に陥っていたことです。彼のコードロジックは完璧でしたが、フォーマットが私と違っていたため、マージ時に無意味なコンフリクトが大量発生してしまいました。
こんな経験はありませんか? コードはちゃんと書いたのに、フォーマットの問題でPRレビューを行ったり来たりして、みんなの時間を無駄にする。その時私は思いました。「機械にこの面倒な作業を自動でやらせる、恒久的な解決策はないものか?」
答えはあります。ESLint + Prettier + Husky の最強コンボです。
なぜこの3つのツールが必要なのか?
正直なところ、最初にこの3つの名前を聞いた時は、少し複雑そうだと感じました。しかし、しばらく使ってみると、もう戻れなくなりました。それぞれの価値について説明させてください。
ESLint:コード品質の守護者
多くの人はESLintを単なるフォーマットチェックツールだと思っていますが、実際の最も重要な役割は潜在的なコードの問題を捕捉することです。
例えば、Next.js公式はHTMLの <img> タグではなく <Image> コンポーネントの使用を推奨しています。前者は自動最適化機能があるからです。もしうっかり <img> を書いてしまったら、ESLintはすぐにエラー警告を出してくれます:
Error: Do not use <img>. Use Image from 'next/image' instead.このような警告のおかげで、開発段階でパフォーマンスの落とし穴を回避できます。リリース後に画像の読み込みが遅いことに気づいて最適化するよりも、はるかに効率的です。
Next.js 15 はデフォルトで ESLint を有効にしていますが、その価値を最大限に引き出すには正しい設定が必要です。
Prettier:フォーマットの究極の解決策
ESLintはコードのロジックと品質に焦点を当て、Prettierはコードのフォーマットに焦点を当てています。両者の役割は明確で、混同すべきではありません。
私たちのチームでは以前、フォーマットの問題でよく議論になりました。シングルクォート派とダブルクォート派、2スペース派と4スペース派。コードレビューのたびに、これらのどうでもいい詳細について議論するのは、本当に時間の無駄です。
Prettierを設定すれば、これらの問題は完全に消えます。プロジェクト開始時にチームメンバーとルール(例:シングルクォート統一、2スペースインデント)を決めておけば、あとはPrettierが自動的にすべてのコードをフォーマットしてくれます。一度設定すれば、一生の利益になります。
Husky:自動化の鍵
ツールが優れていても、手動で実行しなければならないなら、誰かが必ず忘れます。
私自身、何度か経験があります。ローカル開発時に npm run lint を実行し忘れてコードをコミットしてしまい、CIプロセスが失敗してチーム全体のデプロイをブロックしてしまったことがありました。あの気まずさは二度と味わいたくありません。
Huskyの役割は、あなたがコードをコミットする前に、自動的にチェックを実行することです。Gitの pre-commit 段階でコミットをインターセプトし、ESLint と Prettier を実行し、コードが規約に準拠している場合のみコミットを許可します。
lint-staged と組み合わせることで、Huskyはプロジェクト全体をスキャンするのではなく、変更されたファイルだけをチェックするため、非常に高速です。pre-commit フックが開発のテンポを遅くする心配はありません。
3つの連携の威力
これら3つのツールを組み合わせたワークフローは以下のようになります:
- ESLint がコード品質ルールを定義(例:
var禁止、constまたはlet必須) - Prettier がコードフォーマットを統一(例:すべての文字列をシングルクォートに)
- Husky がコミット前に自動的にチェックを実行し、漏れがないことを保証
チームにとってのメリットは明らかです:
- PRレビューでフォーマットの問題に悩まされず、ビジネスロジックに集中できる
- コードのマージ競合が減少(フォーマットが統一されているため)
- CIの失敗率が低下(コミット前にチェック済みのため)
完全な設定フロー
さて、実践編に入りましょう。このツールチェーンをステップバイステップで設定していきます。できるだけ落とし穴を避けるようにガイドします。
ステップ 1:Next.js プロジェクトの初期化
既にプロジェクトがある場合はスキップしてください。新規プロジェクトの場合は以下を実行します:
npx create-next-app@latest my-app
cd my-appプロジェクト作成時、TypeScript と ESLint を選択することを忘れないでください。Next.js 15 はデフォルトで ESLint を有効にしてくれるので、手間が省けます。
ステップ 2:依存関係のインストール
以下のコマンドを実行します(私は pnpm を使っていますが、npm や yarn でも構いません):
pnpm add -D eslint eslint-config-next prettier eslint-config-prettier husky lint-staged各パッケージの役割を簡単に説明します:
eslint:ESLint コアeslint-config-next:Next.js 公式 ESLint 設定(Next.js 特有のルールを含む)prettier:Prettier コアeslint-config-prettier:Prettier と競合する ESLint のフォーマットルールを無効化husky:Git hooks 管理ツールlint-staged:ステージングされた(コミット予定の)ファイルに対してのみチェックを実行
注意:eslint-plugin-prettier はインストールしないでください。多くのチュートリアルがこれを推奨していますが、Prettier を ESLint ルールとして実行することになり、パフォーマンス問題を引き起こします。正しい方法は、ESLint と Prettier を別々に実行することです。
ステップ 3:ESLint の設定
ここは最もハマりやすいポイントです。特に Next.js 15 が ESLint 9 にアップグレードされてから、設定フォーマットが変わりました。
ESLint 9 の Flat Config フォーマットを使用(推奨)
プロジェクトのルートディレクトリに eslint.config.mjs を作成します:
// eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc';
import nextPlugin from '@next/eslint-plugin-next';
const compat = new FlatCompat();
export default [
...compat.extends('next/core-web-vitals'),
{
plugins: {
'@next/next': nextPlugin,
},
rules: {
'@next/next/no-img-element': 'error',
'react/no-unescaped-entities': 'off',
// ここに独自のルールを追加できます
},
},
{
ignores: ['.next/', 'node_modules/', 'out/'],
},
];重要ポイント:
- ESLint 9 は
.eslintrc.jsonではなく、flat config フォーマット(eslint.config.mjs)を使用します。 - Next.js 15 にアップグレード後 “The Next.js plugin was not detected” エラーが出る場合、大抵は設定フォーマットが間違っています。
- Next.js 16 では
next lintコマンドが削除される予定なので、早めに新フォーマットに慣れておくのが賢明です。
ダウングレード案(互換性の問題がある場合)
一時的に flat config を使いたくない場合は、環境変数を設定して ESLint 8 の設定フォーマットにダウングレードできます:
ESLINT_USE_FLAT_CONFIG=falseその後、.eslintrc.json を使い続けます:
{
"extends": ["next/core-web-vitals", "prettier"],
"rules": {
"@next/next/no-img-element": "error"
}
}とはいえ、これは将来のトレンドなので、できるだけ早めに flat config に移行することをお勧めします。
ステップ 4:Prettier の設定
プロジェクトルートに .prettierrc.json を作成します:
{
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"tabWidth": 2,
"printWidth": 80,
"arrowParens": "avoid"
}これらは私の個人的なお気に入りの設定ですが、チームの習慣に合わせて調整してください:
singleQuote: true:シングルクォートの方がスッキリしていて好きです。printWidth: 80:1行最大80文字。複数のエディタウィンドウを並べて表示するのに適しています。trailingComma: 'es5':オブジェクトや配列の最後の項目の後にカンマを追加します。Git diff が綺麗になります。
次に .prettierignore を作成し、Prettier に無視させるファイルを指定します:
.next
out
node_modules
public
*.lockVSCode 統合(推奨)
VSCode を使用している場合は、.vscode/settings.json を作成して、保存時に自動フォーマットするように設定できます:
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}これで Ctrl + S を押してファイルを保存するたびに、Prettier が自動的にコードをフォーマットしてくれます。本当に快適です。
ステップ 5:Husky + lint-staged の設定
このステップが全設定プロセスの真髄であり、チームのコラボレーション効率を最も向上させる部分です。
Husky の初期化
以下を実行します:
pnpm dlx husky initこのコマンドは自動的に .husky/ フォルダを作成し、package.json に prepare スクリプトを追加します:
{
"scripts": {
"prepare": "husky install"
}
}prepare スクリプトの役割は、チームメンバーが pnpm install を実行したときに、自動的に Husky hooks をインストールすることです。これにより、新しく参加した同僚も追加操作なしで、プロジェクトをクローンしたらすぐに自動チェックの保護を受けられます。
pre-commit hook の設定
.husky/pre-commit ファイルを編集します:
pnpm lint-stagedこれだけです。毎回 git commit を実行すると、Husky はまず pnpm lint-staged を実行します。
lint-staged の設定
プロジェクトルートに .lintstagedrc.mjs を作成します:
export default {
'*.{js,jsx,ts,tsx}': [
'eslint --fix',
'prettier --write',
],
'*.{json,md,css}': [
'prettier --write',
],
};この設定の意味は:
.js,.jsx,.ts,.tsxファイルに対しては、eslint --fix(問題の自動修正)を実行した後、prettier --write(フォーマット)を実行します。.json,.md,.cssファイルに対しては、prettier --writeだけを実行します。
パフォーマンス最適化のコツ:
- ステージングされたファイルのみチェック:lint-staged は自動的に
git addされたファイルをフィルタリングし、プロジェクト全体をスキャンしません。 - グローバルチェックを避ける:pre-commit 内で
pnpm lintを実行してはいけません(全プロジェクトをチェックするため非常に遅いです)。 - テストをスキップ:pre-commit はフォーマットチェックと基本的なコード品質チェックのみを行い、複雑なテストは CI に任せます。
- 緊急時のスキップ:どうしてもチェックをスキップする必要がある場合(例:緊急のバグ修正)、
git commit --no-verifyを使用できます。
よくある問題のトラブルシューティング
Windows 環境で Husky が効かない
Windows を使用している場合、CMD や PowerShell ではなく Git Bash を使用していることを確認してください。また、.husky/pre-commit ファイルに実行権限があるか確認してください:
chmod +x .husky/pre-commitフックの実行が遅すぎる
pre-commit フックが 10 秒以上かかる場合、lint-staged の設定を確認し、全プロジェクト検査を誤って設定していないか確認してください。通常、数ファイルだけの lint-staged は 2-3 秒で完了するはずです。
設定の検証
設定が完了したので、正しく動作するか検証してみましょう。
テスト手順
- 適当なファイルを変更し、わざとフォーマットの問題を作ります(例:シングルクォートをダブルクォートに変える、セミコロンを削除するなど)。
git add .を実行。git commit -m "test"を実行。- ターミナルの出力を観察します。
成功のサイン
設定が正しければ、以下のような出力が表示されます:
✔ Preparing lint-staged...
✔ Running tasks for staged files...
✔ Applying modifications from tasks...
✔ Cleaning up temporary files...その後、変更したファイルを開くと、フォーマットの問題が自動的に修正されていることがわかります。これが自動化の魅力です。
失敗した場合
.husky/pre-commitファイルが存在し、内容が正しいか確認してください。.lintstagedrc.mjsファイルがプロジェクトルートにあるか確認してください。pnpm lint-stagedを手動で実行して、エラーメッセージが出るか確認してください。
応用設定
基本的な設定でほとんどのニーズは満たせますが、より厳格なコード品質管理を求める場合は、以下の応用設定を検討してください。
commitlint の追加(コミットメッセージの標準化)
コードフォーマットだけでなく、コミットメッセージの標準も重要です。commitlint は、チームメンバーが統一されたコミットメッセージ形式(例:Conventional Commits)に従うことを保証します。
依存関係のインストール:
pnpm add -D @commitlint/cli @commitlint/config-conventionalcommitlint.config.mjs を作成:
export default {
extends: ['@commitlint/config-conventional'],
};commit-msg hook を追加:
echo "pnpm commitlint --edit \$1" > .husky/commit-msgこれで、コミットメッセージが規範に合わない場合(例:git commit -m "fix bug" ではなく git commit -m "fix: bug")、コミットはブロックされます。
TypeScript 型チェックの追加
コミット前に TypeScript の型チェックを自動実行したい場合は、.lintstagedrc.mjs を修正します:
export default {
'*.{ts,tsx}': [
() => 'tsc --noEmit', // 型チェック
'eslint --fix',
'prettier --write',
],
'*.{js,jsx}': [
'eslint --fix',
'prettier --write',
],
'*.{json,md,css}': [
'prettier --write',
],
};注意:tsc --noEmit はプロジェクト全体の型チェックを行うため、比較的遅いです。プロジェクトが大きい場合、pre-commit hook が遅くなる可能性があります。個人的には、型チェックは CI に任せ、pre-commit はフォーマットと基本チェックのみにすることをお勧めします。
Monorepo 設定
プロジェクトが Monorepo(pnpm workspace や Turborepo など)の場合、設定は少し複雑になります:
- ルートディレクトリに Husky と lint-staged をインストール。
- 各 package 下に個別の
.lintstagedrc.mjsを作成。 - 設定が他の package に「漏れない」ようにする。
具体的な設定については、lint-staged の公式ドキュメントを参照してください。
よくある質問と解決策
設定プロセス中にいくつかの問題に遭遇するかもしれません。ここでは一般的な落とし穴とその解決策をまとめます。
Q1: ESLint と Prettier のルールが競合したら?
症状:ESLint が特定の行のフォーマット不正を指摘するが、Prettier でフォーマットすると元に戻ってしまう。
解決策:eslint-config-prettier がインストールされていることを確認し、ESLint 設定で最後に prettier を extends してください:
export default [
...compat.extends('next/core-web-vitals'),
...compat.extends('prettier'), // 最後に配置
];eslint-config-prettier は Prettier と競合するすべての ESLint フォーマットルールを無効にし、Prettier がフォーマットに、ESLint がコード品質に集中できるようにします。
Q2: Next.js 15 アップグレード後、ESLint が “plugin not detected” エラーを吐く
症状:pnpm lint 実行時にエラー:
Error: The Next.js plugin was not detected in your ESLint configuration.解決策:
これは通常、ESLint 9 の flat config 形式が正しくないためです。eslint.config.mjs が @next/eslint-plugin-next を正しくインポートしているか確認してください:
import nextPlugin from '@next/eslint-plugin-next';
export default [
{
plugins: {
'@next/next': nextPlugin,
},
},
];どうしても解決しない場合は、一時的に ESLINT_USE_FLAT_CONFIG=false を設定して旧形式にダウングレードできます。
Q3: pre-commit hook が遅すぎる
症状:コミットのたびに10秒以上待たされ、開発効率に影響する。
解決策:
- lint-staged がステージングされたファイルのみをチェックしているか確認(通常は自動)。
- pre-commit からテストスクリプトを削除(テストは CI で実行すべき)。
- プロジェクトが大きい場合、ESLint の実行を
.tsと.tsxファイルのみに限定し、他は Prettier のみにする。
Q4: チームメンバーに Husky hooks がインストールされない
症状:新しい同僚がプロジェクトをクローンしたが、コミット時に pre-commit hook が作動しない。
解決策:package.json に prepare スクリプトがあることを確認してください:
{
"scripts": {
"prepare": "husky install"
}
}同僚に一度 pnpm install を実行するように伝えてください。Husky hooks が自動的にインストールされます。
Q5: Windows 環境で Husky が効かない
症状:Windows ユーザーがコミットする際、pre-commit hook が実行されない。
解決策:
- Git の設定が Git Bash を使用していることを確認(CMD ではなく)。
.husky/pre-commitファイルの権限を確認し、手動で実行権限を追加してみてください:
chmod +x .husky/pre-commit- それでもダメな場合、Husky の再初期化を試してください:
rm -rf .husky
pnpm dlx husky initまとめとベストプラクティス
このツールチェーンの設定には30分ほどかかりましたが、チームにもたらす価値は長期的です。
コアなメリット
- コード品質向上:ESLint が開発段階で潜在的な問題を捕捉し、本番での事故を防ぐ。
- チームコラボレーション効率化:統一されたコードフォーマットにより、無意味な PR 論争やマージ競合が減少。
- 自動化による保証:Husky により、すべてのコミットが規範に準拠していることが保証され、チェック漏れの心配がなくなる。
ベストプラクティスの提案
- 段階的な設定:最初から厳しすぎるルールを設定しないこと。まずはデフォルト設定で運用し、問題が見つかったら徐々に調整する。
- チームの合意:Prettier の設定(シングルクォート vs ダブルクォートなど)は、独断ではなくチームメンバーと話し合って決める。
- パフォーマンス優先:pre-commit hook は必要なチェックのみを行い、複雑なテストは CI に任せる。
- 定期的な更新:Next.js と ESLint のバージョン変更に注意を払う。特に Next.js 16 では
next lintコマンドが削除される予定です。
次のアクション
まだプロジェクトにこのツールチェーンを設定していないなら、今すぐ試してみることをお勧めします。この記事に従ってステップバイステップで操作すれば、30分で完了します。
そして、その設定をチームメンバーと共有し、全員の開発環境を統一しましょう。
最後に、チームの状況に合わせて Prettier と ESLint のルールを調整してください。ツールは人のためにあるものであり、ツールに振り回されないようにしましょう。
個人的な経験
正直なところ、このツールチェーンの設定は最初は面倒に感じるかもしれません。特に ESLint 9 の flat config 移行問題に直面した時は、私もかなり苦労しました。でも、一度使い始めたらもう手放せません。
今ではコードをコミットするたびに、フォーマットの問題を心配する必要も、lint の実行を忘れる心配もありません。pre-commit hook がすべて自動でチェックしてくれる安心感は素晴らしいです。
チームの PR レビュー効率も明らかに向上しました。以前は PR で「ここはシングルクォートにすべき」「インデントがおかしい」といった議論がありましたが、今では完全に消えました。Prettier が最初から統一してくれるからです。私たちはフォーマットの細部ではなく、ビジネスロジックやアーキテクチャ設計の議論に時間を使えるようになりました。
この自動化による効率向上は、設定にかかる時間を補って余りある価値があります。
この記事があなたの役に立つことを願っています。設定プロセスで問題が発生した場合は、コメント欄で教えてください。できる限りお答えします。
設定がうまくいきますように!
6 min read · 公開日: 2026年1月6日 · 更新日: 2026年1月22日
関連記事
Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践

Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践
Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド

Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド
Next.js ユニットテスト実践:Jest + React Testing Library 完全設定ガイド


コメント
GitHubアカウントでログインしてコメントできます