ESLintとPrettierでコードスタイルを統一する

ESLintとPrettierでコードスタイルを統一する

1. 背景 

前回の記事では、モノレポ(Monorepo)ベースの物理構造設計について取り上げました。今回はその上でコードを記述する開発者間のコーディングルールを統一する方法について説明します。

プロジェクトの規模が大きくなるほど、同じファイルを複数の開発者が修正する機会が増え、インデントや引用符のスタイルの違いによる不要なGit diffが継続的に発生していました。このようなスタイルの違いは単なるコード形式の問題にとどまらず、コードレビューの過程で繰り返し議論を引き起こし、結果的にレビュー疲れを高める要因となっていました。

社内Wikiにガイドラインを整理するだけではこの問題の解決に限界があり、コードがリモートリポジトリに反映される前に、開発者のミスに関係なくルールを強制できる自動化された仕組みが必要でした。

この記事では、Vue 3とTypeScriptの環境を前提に、ESLintとPrettierを活用してコード規約を定着させた過程と、VS Code・IntelliJの環境で同じルールを適用する方法を共有します。

2. ESLintとPrettierの役割分担

この問題を解決するため、まずESLintとPrettierの役割を明確に区別する必要がありました。

ESLintはコード品質を検証するツールで、未使用の変数、潜在的なバグパターン、誤ったコード構造などを検出します。
一方、Prettierはコード形式を一貫して維持するツールで、インデント、改行、引用符のスタイルといった視覚的なルールを自動的に整えます。

2つのツールを併用する際に最もよく発生する問題は、ルールの衝突です。ESLintにも一部のスタイルルールが含まれているため、Prettierと同じ領域について異なる判定をする可能性があります。

これを解決するため、本プロジェクトでは plugin:prettier/recommended を使用し、Prettierの結果をESLintの実行過程でも確認できるように設定しました。これにより、ESLintの実行だけでコード品質とフォーマットの問題を同時に確認できます。

プロジェクトに適用したESLint設定の例は次のとおりです。

// .eslintrc
{
  "root": true,
  "env": {
    "node": true,
    "browser": true,
    "es2021": true
  },
  "parser": "vue-eslint-parser",
  "parserOptions": {
    "parser": "@typescript-eslint/parser",
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "plugin:vue/vue3-recommended", // Vue 3 환경에서 권장되는 규칙 적용
    "plugin:prettier/recommended"
  ],
  "rules": {
    "vue/multi-word-component-names": "off", // 단일 단어 컴포넌트명 허용
    "no-console": "warn",
    "@typescript-eslint/no-explicit-any": "off"
  }
}

なお、この例は .eslintrc ベースのLegacy Config環境を前提に作成しています。プロジェクトで使用するeslint-plugin-vueのバージョンに応じて、plugin:vue/vue3-recommended または plugin:vue/recommended を使用できます。

また、ESLint 9以降ではFlat Config(eslint.config.js)の使用が推奨されているため、新規プロジェクトでは公式ドキュメントも併せて参照するとよいでしょう。

3. プロジェクト共通ルールの構成

プロジェクト内でEditorConfigをサポートするエディターが同じ基本ルールに従うように、.editorconfigを追加しました。

特に end_of_line = lf の設定は、WindowsとmacOS間の改行方式の違い(CRLF/LF)によって発生する不要なGit diffを減らすのに役立ちます。

各設定の意味は次のとおりです。

  • indent_style = space: インデントの統一

  • indent_size = 2: Vue/TSプロジェクトの基本スタイルを維持

  • end_of_line = lf: OS間の改行の衝突を防止

  • insert_final_newline = true: ファイル末尾の改行を保証

  • trim_trailing_whitespace = true: 不要な空白を削除

EditorConfigの設定は次のとおりです。

# .editorconfig
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

4. IDE環境の同期

ルールを定義しても、IDEで同じように適用されなければ意味が薄れます。実際、VS CodeとIntelliJ(WebStormを含む)を併用する環境では、フォーマットの違いによってGit diffが繰り返し発生する問題がありました。

4.1 問題の原因

VS Codeでは拡張機能を利用してPrettierを簡単に適用できますが、IntelliJは基本的に独自のフォーマッターを使用するため、設定によってはPrettierではなくIDEのフォーマッターが実行されることがあります。その結果、同じコードであってもIDEによってフォーマット結果が異なる問題が発生しました。

4.2 解決方法

4.2.1 VS Codeの設定

VS Codeでは、保存時に自動フォーマットとESLintの自動修正が動作するように設定しました。

{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
}

なお、VS CodeおよびESLint拡張機能のバージョンによって source.fixAll.eslint の設定方法は異なる場合があり、最新の環境では "explicit" の使用が推奨されることもあります。

4.2.2 IntelliJの設定

IntelliJ環境では、次のように設定を統一しました。

  • Prettierのパスをプロジェクトのnode_modules基準で明示

  • コードのreformat時にPrettierの使用を強制

  • 保存時のフォーマットをIDEのフォーマッターではなくPrettierに委任

この設定により、IDE間のフォーマットの違いを最小限に抑えました。

5. Vue SFCのパースエラーの原因と解決

初期導入の過程で、Vue 3のSingle File Component(SFC、.vue)内部でESLintのパースエラーが発生しました。特に <script setup lang="ts"> の領域が正常に解釈されず、TypeScript関連のエラーが不正に発生する問題がありました。これは、Vue SFCの構造を理解するvue-eslint-parserを使用せずに@typescript-eslint/parserだけを使用した場合や、parserの構成が正しく接続されていない場合に発生する可能性があります。

これを解決するため、Vueの構造とスクリプト領域のパーサーを分離しました。

// .eslintrc
{
// ...생략
  "parser": "vue-eslint-parser", // 최상단 파서로 Vue 파일의 기본 구조 해석
  "parserOptions": {
    "parser": "@typescript-eslint/parser", // 스크립트 내부 영역만 TS 파서가 담당
    "ecmaVersion": "latest",
    "sourceType": "module"
},
// ...생략
}

この設定以降、.vueファイルでも正常にlintが動作し、パースエラーが解消されました。

6. 運用経験と限界

初期導入時には、既存のコードベースで200件以上のlintエラーが発生しました。特に、anyの使用、console.log、Vueコンポーネントの命名規則違反が主な原因でした。すべてのルールをErrorとして強制すると開発速度に影響する可能性があるため、初期段階では一部のルールをwarnまたはoffに設定し、段階的に適用する戦略を使用しました。また、console.logはデバッグ過程で頻繁に使用されるため、初期段階ではno-consoleをWarningレベルで運用しました。

また、今回はHuskyベースのコミット検証を適用しませんでした。初期段階ではlint-stagedとHuskyによるコミット段階での強制も検討しましたが、まずはローカル開発環境の統一とチーム内の開発体験の安定化を優先しました。今後は、コミット段階またはCI段階でESLint検証を追加し、開発環境の違いに左右されずコード品質を検証できる構成へ拡張することを検討しています。

7. 結論

ESLintとPrettierを適用した後、最も大きく実感できた変化はコードレビューの進め方でした。機能と直接関係のないスタイル修正が大幅に減ったことで、開発者はコード形式ではなくビジネスロジックにより集中できる環境を作ることができました。その結果、コードレビューの時間と不要な変更履歴を減らすのに役立ち、コード品質を一定水準以上に維持する基盤を整えることができました。

自動化されたコード規約の環境は、大規模な共同開発で一貫性を維持するための重要な基盤となり得ます。

参考文献

- ESLint Official Documentation: https://eslint.org/

- Prettier公式ドキュメント: https://prettier.io/

- EditorConfig公式ドキュメント: https://editorconfig.org/

- Vue ESLintプラグイン公式ドキュメント: https://eslint.vuejs.org/

Code_Latte

Site footer