ESLintのbrace-styleとは?JavaScriptコードスタイル統一の基本

2025-05-27

主に以下の3つのスタイルがよく知られており、brace-style ルールで設定できます。

  1. "1tbs" (One True Brace Style):

    • これはJavaScriptで最も一般的なスタイルの一つです。
    • 開き括弧({)は、if, for, function などのステートメントと同じ行に配置されます。
    • 閉じ括弧(})は、次の elsecatch などと同じ行、または独立した行に配置されます。
    • 例:
      if (condition) {
        // ...
      } else {
        // ...
      }
      
  2. "stroustrup":

    • "1tbs"に似ていますが、elsecatchfinally といったキーワードは、前の閉じ括弧の後に新しい行に配置されます。
    • C++の考案者であるBjarne Stroustrupのスタイルに由来します。
    • 例:
      if (condition) {
        // ...
      }
      else {
        // ...
      }
      
  3. "allman":

    • 開き括弧({)と閉じ括弧(})の両方が、それぞれのステートメントから独立した新しい行に配置されます。
    • これはC#などの言語でよく見られるスタイルです。
    • 例:
      if (condition)
      {
        // ...
      }
      else
      {
        // ...
      }
      

ESLintでの設定方法

.eslintrc.js または .eslintrc.json ファイルの rules セクションで設定します。

{
  "rules": {
    "brace-style": ["error", "1tbs", { "allowSingleLine": true }]
  }
}
  • { "allowSingleLine": true }: オプションで、単一行のブロックであれば中括弧を同じ行に配置することを許可します。

    例(allowSingleLine: true の場合):

    if (foo) { bar(); } // 許可される
    
  • "1tbs": 使用するスタイルを指定します("stroustrup" または "allman" も指定可能)。

  • "error": ルールに違反した場合にエラーとして報告します。

なぜ「brace-style」ルールを使うのか?

  • バグの防止
    意図しない改行や括弧の省略による潜在的なバグを防ぐのに役立ちます(特に curly ルールと組み合わせて「常に中括弧を使用する」とすることで)。
  • 可読性の向上
    一貫したスタイルは、コードの構造を視覚的に理解しやすくします。
  • コードの一貫性
    チーム開発において、全員が同じ括弧のスタイルを使用することで、コードの見た目と構造が統一され、読みやすさが向上します。


よくあるエラーと原因

    • エラーの例
      Expected opening brace at end of line. (brace-style)
      Expected closing brace to be on the same line as the next token. (brace-style)
      
    • 原因
      設定されている brace-style のオプション(例: "1tbs", "allman", "stroustrup")と、実際の中括弧の配置が一致していない場合に発生します。
      • "1tbs" を設定しているのに、開き括弧が新しい行にある場合。
      • "allman" を設定しているのに、開き括弧が同じ行にある場合。
      • "1tbs""stroustrup" で、elsecatch の閉じ括弧の後に改行がない場合。
    • 例("1tbs" でのよくある間違い)
      //  エラー: "1tbs" では開き括弧は同じ行に
      if (condition)
      {
        // ...
      }
      
      //  エラー: "1tbs" では else は閉じ括弧と同じ行に
      if (condition) {
        // ...
      }
      else {
        // ...
      }
      
  1. allowSingleLine オプションの誤解

    • エラーの例
      Expected opening brace at end of line. (brace-style)
      
      または、意図せず単一行のコードブロックが許可されてしまう。
    • 原因
      brace-style ルールには allowSingleLine: true というオプションがあり、これを設定すると単一行のブロックでは中括弧を同じ行に配置することが許可されます。このオプションが期待通りの動作をしていない場合、または意図せず有効になっている場合に発生します。

    • // .eslintrc.js
      {
        "rules": {
          "brace-style": ["error", "1tbs", { "allowSingleLine": false }] // デフォルトはfalse
        }
      }
      
      allowSingleLine: false (デフォルト)にもかかわらず、以下のコードを書くとエラーになります。
      if (foo) { bar(); } //  エラー: 単一行でも改行が強制される
      
      逆に、allowSingleLine: true に設定しているのに、コードが複数行で書かれていてエラーになる場合は、単一行での記述を強制されているわけではありません。
  2. 他の整形ツール(Prettierなど)との競合

    • エラーの例
      ESLintを実行しても、brace-style の問題が修正されない、または他のルールと競合してコードが頻繁にフォーマットし直される。
    • 原因
      Prettierのような別のコードフォーマッターを使用している場合、ESLintの整形ルールとPrettierの整形ルールが競合することがあります。Prettierは通常、ESLintよりも優先的にフォーマットを行うため、ESLintのbrace-style設定がPrettierのスタイルに上書きされてしまうことがあります。

    • ESLintが"1tbs"を設定しているのに、Prettierが"allman"のようなスタイルでフォーマットしてしまう。
  3. 設定ファイルの読み込みミス/適用漏れ

    • エラーの例
      brace-style ルールを設定したのに、ESLintがエラーを報告しない、または期待するスタイルが適用されない。
    • 原因
      • .eslintrc ファイルが正しく配置されていない、またはESLintがそれを読み込んでいない。
      • 特定のファイルやディレクトリが.eslintignoreで無視されている。
      • ESLintの実行コマンドが正しくない(例: eslint . ではなく、特定のファイルだけを対象にしている)。
      • VS Codeなどのエディタ拡張機能でESLintが正しく設定されていない。
  1. ESLint のエラーメッセージを確認する

    • ESLintのエラーメッセージは非常に具体的です。どのファイルの何行目で、どのルール(例: brace-style)に違反しているかが表示されます。
    • メッセージの内容をよく読み、どのようなスタイルの違反が起きているかを特定します。
  2. brace-style の設定を再確認する

    • .eslintrc ファイルを開き、"brace-style" ルールの設定が意図したものになっているかを確認します。
    • 特に、"1tbs", "stroustrup", "allman" のどれを設定しているか、"allowSingleLine" オプションがどのように設定されているかをチェックします。
    • 必要であれば、一時的に設定を変更して、エラーがどのように変化するかを確認します。
  3. eslint --fix を試す

    • brace-style ルールは、--fix オプションで自動的に修正できることが多いです。
    • コマンドラインで eslint --fix <ファイル名またはディレクトリ名> を実行し、自動修正されるかを確認します。
    • 自動修正されない場合は、手動でコードを修正する必要があります。
  4. 他の整形ツールとの競合を解消する

    • Prettier を使用している場合
      • ESLint と Prettier を併用する場合、通常は ESLint の整形ルールを無効にし、Prettier にフォーマットを任せるのがベストプラクティスです。
      • eslint-config-prettier を導入して、ESLint の整形に関連するルールを無効にします。これにより、Prettier と ESLint が競合することを防ぎます。
      • npm install --save-dev eslint-config-prettier
      • .eslintrcextends"prettier" を追加します(必ず最後に記述してください)。
        {
          "extends": [
            "eslint:recommended",
            "plugin:react/recommended",
            "prettier" // これを最後に追加
          ]
        }
        
    • 手動で競合を解決する場合
      • brace-style だけでなく、indentquotes など、フォーマットに関するESLintルールを無効にするか、Prettierの設定と一致するように調整します。この方法は複雑になりがちなので、eslint-config-prettier の使用が推奨されます。
  5. ESLint の実行環境と設定を確認する

    • コマンドラインからの実行
      eslint --debug <ファイル名> を実行し、ESLintがどの設定ファイルを読み込んでいるか、どのルールが適用されているかを確認します。
    • エディタ拡張機能 (VS Codeなど)
      • エディタのESLint拡張機能が有効になっているか、ESLintのパスが正しく設定されているかを確認します。
      • 時々、エディタを再起動することで問題が解決することもあります。
      • エディタのワークスペース設定やユーザー設定で、ESLintが特定のファイルタイプに適用されるように設定されているか確認します。
    • .eslintignore ファイルの確認
      目的のファイルがignoreリストに含まれていないか確認します。
  6. ESLint のバージョンを確認する

    • 稀にESLintのバージョンアップによってルールの挙動が変わることがあります。使用しているESLintのバージョンを確認し、公式ドキュメントを参照して、設定がそのバージョンで正しいか確認します。


ESLint brace-style ルールの設定例

まず、.eslintrc.js または .eslintrc.json ファイルでの設定方法を見てみましょう。

// .eslintrc.json の例
{
  "rules": {
    "brace-style": ["error", "1tbs", { "allowSingleLine": true }]
  }
}

この設定は、「brace-style ルールでエラーを報告し、"1tbs" スタイルを強制する。ただし、単一行のコードブロックでは中括弧の配置を許可する」という意味になります。

"1tbs" (One True Brace Style)

これはJavaScriptで最も一般的なスタイルです。

  • 閉じ括弧 (}): 次の else, catch, finally と同じ行に配置されるか、それらが存在しない場合は独立した行に配置されます。
  • 開き括弧 ({): if, for, function などのステートメントと同じ行に配置されます。

ESLint 設定例

{
  "rules": {
    "brace-style": ["error", "1tbs"]
  }
}

許可されるコード例

// if-else ステートメント
if (condition) { // 開き括弧が同じ行
  doSomething();
} else { // 閉じ括弧と else が同じ行
  doSomethingElse();
}

// for ループ
for (let i = 0; i < 10; i++) { // 開き括弧が同じ行
  console.log(i);
}

// function
function myFunction() { // 開き括弧が同じ行
  console.log("Hello");
}

// try-catch-finally
try { // 開き括弧が同じ行
  throw new Error("Oops");
} catch (error) { // 閉じ括弧と catch が同じ行
  console.error(error);
} finally { // 閉じ括弧と finally が同じ行
  console.log("Finished");
}

// if のみ(閉じ括弧は独立した行)
if (data) {
  processData();
}

エラーとなるコード例

// エラー: 開き括弧が新しい行にある
if (condition)
{ // "1tbs" ではエラー
  doSomething();
}

// エラー: else が新しい行にある
if (condition) {
  doSomething();
}
else { // "1tbs" ではエラー
  doSomethingElse();
}

"stroustrup"

"1tbs" に似ていますが、elsecatchfinally といったキーワードは、前の閉じ括弧の後に新しい行に配置されます。C++ の考案者である Bjarne Stroustrup のスタイルに由来します。

ESLint 設定例

{
  "rules": {
    "brace-style": ["error", "stroustrup"]
  }
}

許可されるコード例

// if-else ステートメント
if (condition) {
  doSomething();
}
else { // else が新しい行
  doSomethingElse();
}

// try-catch-finally
try {
  throw new Error("Oops");
}
catch (error) { // catch が新しい行
  console.error(error);
}
finally { // finally が新しい行
  console.log("Finished");
}

// for, function などは "1tbs" と同様
for (let i = 0; i < 10; i++) {
  console.log(i);
}

function myFunction() {
  console.log("Hello");
}

エラーとなるコード例

// エラー: else が同じ行にある
if (condition) {
  doSomething();
} else { // "stroustrup" ではエラー
  doSomethingElse();
}

"allman"

開き括弧 ({) と閉じ括弧 (}) の両方が、それぞれのステートメントから独立した新しい行に配置されます。C# などの言語でよく見られるスタイルです。

ESLint 設定例

{
  "rules": {
    "brace-style": ["error", "allman"]
  }
}

許可されるコード例

// if-else ステートメント
if (condition)
{ // 開き括弧が新しい行
  doSomething();
}
else
{ // else の後、開き括弧が新しい行
  doSomethingElse();
}

// for ループ
for (let i = 0; i < 10; i++)
{ // 開き括弧が新しい行
  console.log(i);
}

// function
function myFunction()
{ // 開き括弧が新しい行
  console.log("Hello");
}

// try-catch-finally
try
{ // 開き括弧が新しい行
  throw new Error("Oops");
}
catch (error)
{ // catch の後、開き括弧が新しい行
  console.error(error);
}
finally
{ // finally の後、開き括弧が新しい行
  console.log("Finished");
}

エラーとなるコード例

// エラー: 開き括弧が同じ行にある
if (condition) { // "allman" ではエラー
  doSomething();
}

// エラー: else が同じ行にある
if (condition)
{
  doSomething();
} else { // "allman" ではエラー
  doSomethingElse();
}

このオプションは、"1tbs", "stroustrup", "allman" のどのスタイルを使用しているかに関わらず、単一行のコードブロックに対して特別な扱いを許可します。

ESLint 設定例

{
  "rules": {
    "brace-style": ["error", "1tbs", { "allowSingleLine": true }]
  }
}

allowSingleLine: true の場合に許可されるコード例

// "1tbs" スタイルと組み合わせた例
if (condition) { doSomething(); } // 単一行なので許可される
else { doSomethingElse(); }      // 単一行なので許可される

// "allman" スタイルと組み合わせた例
// "allman" でも単一行の場合は同じ行に記述できる
if (condition) { doSomething(); }
{
  "rules": {
    "brace-style": ["error", "1tbs", { "allowSingleLine": false }]
  }
}
// エラー: allowSingleLine が false のため、単一行でも中括弧は強制的に改行される
if (condition) { doSomething(); }


Prettier(コードフォーマッター)

ESLintのbrace-styleルールは、コードのスタイリング(整形)に関するものです。Prettierは、ESLintとは独立した強力なコードフォーマッターであり、JavaScriptコードのスタイルを自動的に整形することを専門としています。

  • brace-styleとの関係

    • Prettierには、中括弧のスタイルに関する設定(bracketSameLinesingleQuote など)がありますが、ESLintのbrace-styleルールよりも優先的に動作します。
    • 一般的なプラクティス
      ESLintとPrettierを併用する場合、ESLintの整形に関するルール(brace-styleindentquotesなど)はPrettierと競合するため、ESLint側でこれらのルールを無効にするのが一般的です。これは、eslint-config-prettierという設定を使用することで簡単に行えます。
    • 代替手段としての位置づけ
      brace-styleの目的が単に中括弧のスタイルを統一することであれば、Prettierを導入するだけでその目的を達成できます。Prettierが自動的にコードをフォーマットしてくれるため、開発者は手動でスタイルを気にする必要がなくなります。
    • ESLintよりも包括的なフォーマット機能を持っています。インデント、引用符、セミコロン、そして中括弧のスタイルなど、ほとんどのコードスタイルに関する問題を自動で修正します。
    • 設定が非常にシンプルで、ほとんどの整形ルールはデフォルトで動作します。
    • 開発チーム内で、prettierを導入することで、コードの見た目に関する議論をなくし、開発効率を向上させることができます。

EditorConfig

EditorConfigは、異なるエディターやIDEを使用している開発者が同じプロジェクトで作業する際に、一貫したコーディングスタイルを維持するためのファイルフォーマットです。

  • brace-styleとの関係

    • EditorConfigは、中括弧の具体的な配置スタイル(1tbs, allmanなど)を直接指定する機能はありません。brace-styleルールのような「開き括弧は前の行に、閉じ括弧は次の行に」といった詳細なルールは定義できません。
    • しかし、インデントのスタイルを統一することで、中括弧が正しくインデントされるように間接的に影響を与えることはできます。
    • 代替手段としての位置づけ
      brace-styleのように中括弧の具体的な配置スタイルまでを強制したい場合は、EditorConfigだけでは不十分です。ESLintやPrettierと組み合わせて使用することが推奨されます。基本的なインデントや改行コードの統一には非常に有効です。
  • EditorConfigの利点

    • インデントのスタイル(スペースかタブか、幅)、改行コード(LF/CRLF)、末尾のスペース、そしてファイルエンディングの改行などを定義できます。
    • プロジェクトのルートに.editorconfigファイルを置くだけで、対応するエディターやIDEが自動的にその設定を読み込み、適用します。
    • ESLintがなくても、基本的な整形ルールを強制できます。

コミュニティのコーディング規約に準拠する(明示的なルールなし)

厳密なESLintルールを設定せずに、チームやプロジェクトの暗黙的な、または明示的なコーディング規約に従うという方法も存在します。

  • 代替手段としての位置づけ
    大規模なプロジェクトや複数人での開発においては、この方法は推奨されません。ESLintやPrettierのようなツールを使って、スタイルを自動的に強制する方が効率的でエラーを減らせます。

  • brace-styleとの関係

    • brace-styleルールを設定しない場合、ESLintは中括弧のスタイルに関する警告やエラーを報告しません。
    • 欠点
      • チームメンバー間でスタイルのばらつきが発生しやすくなります。
      • 新しいメンバーがプロジェクトに参加した際に、どのスタイルに従うべきかが分かりにくくなります。
      • コードレビューでスタイルに関する指摘が増える可能性があります。
      • 自動化されたチェックがないため、ヒューマンエラーが発生しやすいです。
  • 利点

    • 設定ファイルがシンプルになります。
    • 開発者がスタイルに関する特定のルールに縛られすぎずに、より柔軟にコードを書けます。

これはbrace-styleの「代替手段」というよりは、ESLintなどのリンターやフォーマッターを強制的に実行するための方法です。コードスタイルの問題を見逃さないようにする「最終防衛線」として機能します。

  • brace-styleとの関係

    • brace-styleルールがESLintによって有効になっている場合、huskylint-stagedを使うことで、そのルールがコミット時に確実に適用されるようになります。
    • 代替手段としての位置づけ
      これはbrace-styleルールの代わりになるものではなく、むしろbrace-styleを含むESLintルールをより効果的に適用するための「運用方法」と考えるべきです。
  • 利点

    • コミット前に自動的にESLintやPrettierが実行され、スタイルエラーが修正されるか、コミットが拒否されるため、誤ったスタイルのコードがリポジトリにコミットされるのを防げます。
    • CI/CDパイプラインでのチェックよりも、開発の早い段階で問題を発見できます。
  • lint-staged
    Gitのステージングエリアにあるファイルに対してのみ、ESLintなどのコマンドを実行できるようにするツールです。

  • Husky
    Gitの各種フック(例: pre-commit)を簡単に設定できるようにするツールです。

  • スタイルチェックの自動化と強制
    • Husky + lint-staged を導入することで、Gitコミット時に自動的にスタイルチェックと修正が行われるようにし、リポジトリへの不適切なコードの流入を防ぐことができます。
  • 基本的なインデントや改行コードの統一
    • EditorConfig が非常に有効です。ESLintやPrettierと併用することで、より包括的なスタイル統一が可能です。
  • 中括弧のスタイルを厳密に統一したい場合
    • Prettier を導入し、ESLintはeslint-config-prettierを使って整形ルールを無効にするのが最も推奨される方法です。Prettierがスタイルを自動的に統一してくれます。
    • Prettierを導入しない場合でも、ESLintのbrace-styleルールを適切に設定することで目的は達成できます。