これで解決!Prettier Tab Widthのよくあるエラーとトラブルシューティング

2025-06-06

「Tab Width」は、Prettierにおける重要な設定の一つで、コードのインデント(字下げ)の幅を決定します。具体的には、タブ文字 (\t) が表示上何スペース分の幅を持つか、あるいはスペースでインデントする場合に何スペースを使うかを指定します。

「Tab Width」の役割と設定

プログラミングにおいて、インデントはコードの構造を視覚的に分かりやすくするために不可欠です。Prettierは、設定された「Tab Width」に基づいて、コードを自動的に整形します。

設定可能な値

  • 4に設定すると、インデントは4スペース分になります。
  • 2に設定すると、インデントは2スペース分になります。
  • 通常は整数で指定します。例えば、24などが一般的です。

設定方法

Prettierの設定ファイル(例: .prettierrcpackage.jsonprettierフィールドなど)でtabWidthプロパティを設定します。

例(.prettierrcの場合)

{
  "tabWidth": 2
}

この設定により、Prettierは以下のようにコードを整形します。

整形前

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

整形後(tabWidth: 2の場合)

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

Prettierには、「Tab Width」の他に「Use Tabs」(useTabs)という設定もあります。これら2つの設定は密接に関連していますが、異なる役割を持っています。

  • useTabs: インデントにタブ文字を使用するか、スペースを使用するかを決定します。
  • tabWidth: インデントの「幅」を決定します。

組み合わせの例

    • インデントには2つのスペースが使用されます。
  1. tabWidth: 4, useTabs: true

    • インデントにはタブ文字が使用され、そのタブ文字は表示上4スペース分の幅を持ちます。

多くのプロジェクトでは、一貫性を保つためにtabWidthuseTabsを適切に設定し、チーム全体で同じインデントルールを適用しています。



よくあるエラーと問題

    • Prettierを設定したはずなのに、コードが期待するタブ幅(例: 2スペースや4スペース)で整形されない。
    • タブとスペースが混在してしまっている。
  1. エディタの表示とPrettierの整形結果が一致しない

    • VS Codeなどのエディタでタブ幅を4スペースに設定しているのに、Prettierで整形すると2スペースになってしまう。
    • またはその逆。
  2. プロジェクト内でインデントがバラバラになる

    • チームメンバーや異なる環境で作業すると、同じファイルでもインデントの幅が異なってしまう。
  3. .prettierrcなどの設定ファイルが無視される

    • 設定ファイルにtabWidthを記述しているのに、Prettierがその設定を適用してくれない。

これらの問題のほとんどは、設定の競合や優先順位の理解不足によって引き起こされます。

設定ファイルの競合を確認する

Prettierは複数の場所から設定を読み込みます。優先順位は以下のようになります(上に行くほど優先度が高い)。

  • エディタ(VS Codeなど)のPrettier拡張機能の設定
  • Prettierのデフォルト設定
  • package.jsonprettier フィールド
  • .prettierrc / .prettierrc.json / prettier.config.js などのプロジェクト固有の設定ファイル
  • インライン設定(// prettier-ignoreなど)

確認すべきこと

  • ワークスペース設定とユーザー設定の確認 (VS Codeの場合)
    • VS Codeでは、グローバルな「ユーザー設定」と、プロジェクト固有の「ワークスペース設定」があります。ワークスペース設定はユーザー設定よりも優先されます。意図したtabWidthがワークスペース設定で上書きされていないか確認しましょう。
  • .editorconfig ファイルがないか?
    • .editorconfig はエディタのインデント設定などを統一するためのファイルで、Prettierよりもエディタが優先して読み込むことがあります。もしプロジェクトに.editorconfigがあり、indent_sizeindent_styleが設定されている場合、それがPrettierの挙動に影響を与える可能性があります。.editorconfigの設定とPrettierの設定を一致させるか、どちらかを無効化することを検討してください。
  • 複数の設定ファイルが存在しないか?
    • 例えば、.prettierrc.jsonpackage.jsonの両方にtabWidthが設定されている場合、優先される方が適用されます。意図しないファイルに古い設定が残っていないか確認しましょう。

Prettierの実行方法を確認する

  • CLIで直接実行しているか、エディタの拡張機能を使っているか?
    • CLIで実行する場合は、コマンドに直接オプションを渡すこともできますが、通常は設定ファイルを参照します。
    • エディタの拡張機能を使用している場合、拡張機能自体の設定がPrettierの設定を上書きしている可能性があります。

エディタの設定とPrettierの設定を一致させる

最も一般的なトラブルの原因は、エディタのタブ幅設定とPrettierのtabWidth設定が一致していないことです。

  • VS Codeの場合
    • VS Codeのユーザー設定またはワークスペース設定を開きます(Ctrl + , または Cmd + ,)。
    • Editor: Tab Size を検索し、PrettierのtabWidthと同じ値に設定します。
    • Editor: Detect Indentation を無効にすることも検討してください。これはファイルの内容からインデントを自動検出する機能ですが、Prettierを使用する場合はPrettierの設定に任せた方が一貫性が保たれます。
    • prettier.tabWidthprettier.useTabsの設定も確認し、意図した通りになっているか確認します。

Prettierの出力ログを確認する

Prettierの拡張機能(VS Codeなど)には、整形時のログを出力する機能がある場合があります。このログを確認することで、どの設定ファイルが読み込まれているか、どのようなオプションが適用されているかを知ることができます。

  • VS Codeの場合、出力パネル(Ctrl + Shift + U または Cmd + Shift + U)を開き、ドロップダウンから「Prettier」を選択します。

キャッシュや依存関係の問題

ごく稀に、node_modulesのキャッシュが原因で問題が発生することがあります。

  • node_modulesフォルダを削除し、npm installまたはyarn installを再実行してみてください。

シンプルな設定から始める

もし複雑な設定になってしまっている場合は、一度最小限の設定から始めることを検討してください。

  • プロジェクトルートにシンプルな.prettierrcファイル(例: {"tabWidth": 2, "useTabs": false})を作成し、他のPrettier関連の設定ファイル(package.jsonprettierフィールドなど)を一時的に削除またはコメントアウトしてテストします。これにより、問題の切り分けがしやすくなります。


これらの例は、Prettierがどのようにコードを整形するか、そしてtabWidth設定がそれにどのように影響するかを示します。

例1: 基本的な tabWidth の設定と効果

この例では、tabWidth2 に設定した場合と 4 に設定した場合のPrettierによる整形結果の違いを示します。

設定ファイル (.prettierrc) の準備

まずは、Prettierの設定ファイルを作成します。

A. tabWidth: 2 の場合

project-root/.prettierrc

{
  "tabWidth": 2,
  "useTabs": false,
  "singleQuote": true,
  "printWidth": 80
}

B. tabWidth: 4 の場合

{
  "tabWidth": 4,
  "useTabs": false,
  "singleQuote": true,
  "printWidth": 80
}

整形前のコード (index.js)

project-root/index.js

function greet(name) {
        if (name) {
                console.log('Hello, ' + name + '!');
        } else {
                        console.log('Hello, anonymous!');
        }
}

const user = {
        id: 1,
        name: 'Alice',
        email: '[email protected]'
};

function processData(data) {
    if (data.length > 0) {
        data.forEach(item => {
            console.log(item);
        });
    }
}

Note: 上記の整形前のコードは、意図的に不揃いなインデントを含んでいます。

Prettierで整形を実行

ターミナルでプロジェクトのルートディレクトリに移動し、以下のコマンドを実行します。

npx prettier --write index.js

整形後のコード

A. tabWidth: 2 で整形した場合の index.js

function greet(name) {
  if (name) {
    console.log('Hello, ' + name + '!');
  } else {
    console.log('Hello, anonymous!');
  }
}

const user = {
  id: 1,
  name: 'Alice',
  email: '[email protected]',
};

function processData(data) {
  if (data.length > 0) {
    data.forEach((item) => {
      console.log(item);
    });
  }
}

解説
全てのインデントが2スペース幅に統一されています。

B. tabWidth: 4 で整形した場合の index.js

function greet(name) {
    if (name) {
        console.log('Hello, ' + name + '!');
    } else {
        console.log('Hello, anonymous!');
    }
}

const user = {
    id: 1,
    name: 'Alice',
    email: '[email protected]',
};

function processData(data) {
    if (data.length > 0) {
        data.forEach((item) => {
            console.log(item);
        });
    }
}

解説
全てのインデントが4スペース幅に統一されています。

例2: tabWidthuseTabs の組み合わせ

tabWidth はインデントの「幅」を指定しますが、実際にタブ文字 (\t) を使うかスペースを使うかは useTabs オプションで決定します。

設定ファイル (.prettierrc) の準備

A. tabWidth: 4, useTabs: true の場合

{
  "tabWidth": 4,
  "useTabs": true,
  "singleQuote": true
}

Note: tabWidth: 4useTabs: true の組み合わせは、タブ文字が挿入され、エディタでそのタブが4スペースとして表示されることを意味します。

B. tabWidth: 4, useTabs: false の場合 (デフォルトの挙動)

{
  "tabWidth": 4,
  "useTabs": false,
  "singleQuote": true
}

Note: これはスペースをインデントに使用し、その幅が4スペースになることを意味します。

整形前のコード (data.js)

project-root/data.js

class MyClass {
constructor() {
        this.value = 0;
        }

        myMethod() {
                        if (this.value === 0) {
                                console.log('Value is zero');
            } else {
                console.log('Value is ' + this.value);
            }
        }
}

Prettierで整形を実行

npx prettier --write data.js

整形後のコード

A. tabWidth: 4, useTabs: true で整形した場合の data.js (注意: タブ文字は目に見えないため、表示上は4スペースに見えますが、実際にはタブ文字が挿入されています)

class MyClass {
	constructor() {
		this.value = 0;
	}

	myMethod() {
		if (this.value === 0) {
			console.log('Value is zero');
		} else {
			console.log('Value is ' + this.value);
		}
	}
}

Note: 上記のコードは、タブ文字でインデントされています。このテキストエディタではタブ文字が4スペースとして表示されていることを想定しています。実際のファイルの内容を確認すると、\t 文字が挿入されていることがわかります。

B. tabWidth: 4, useTabs: false で整形した場合の data.js

class MyClass {
    constructor() {
        this.value = 0;
    }

    myMethod() {
        if (this.value === 0) {
            console.log('Value is zero');
        } else {
            console.log('Value is ' + this.value);
        }
    }
}

解説
4つのスペースでインデントされています。これがデフォルトの挙動です。

tabWidth 設定とは直接関係ありませんが、Prettierの整形を特定のファイルやディレクトリに適用したくない場合に使います。

設定ファイル (.prettierrc) の準備

{
  "tabWidth": 2,
  "useTabs": false
}

無視するファイルを指定 (.prettierignore)

project-root/.prettierignore

dist/
node_modules/
legacy_code.js

整形対象のファイルと無視されるファイル

project-root/src/main.js (整形される)

function calculateSum(a, b) {
  return a + b;
}

project-root/legacy_code.js (整形されない)

function   oldFunction(  param1, param2) {
        // This is old, messy code
                if (param1  > 0) {
                                console.log("Old logic");
                }
}

Prettierでプロジェクト全体を整形

npx prettier --write .
  • legacy_code.js.prettierignore に含まれているため、元の不揃いなインデントのまま変更されません。
  • src/main.jstabWidth: 2 に従って整形されます。


.editorconfig ファイルの使用

.editorconfig は、異なるエディタやIDE間で一貫したコーディングスタイルを定義するためのファイルフォーマットです。PrettierのtabWidth設定と競合する場合があるため、理解しておくことが重要です。

特徴

  • ファイルパスに基づいて設定を適用できるため、プロジェクト内の異なる種類のファイルで異なるスタイルを適用することも可能です。
  • 多くの主要なエディタ(VS Code, IntelliJ IDEA, Sublime Textなど)がネイティブでサポートしています。
  • エディタレベルでのインデント設定(indent_sizeindent_style)などを制御できます。

Prettierとの関係
Prettierは直接.editorconfigを読み込むわけではありませんが、エディタによっては.editorconfigの設定をPrettierの拡張機能に適用したり、Prettierが実行される前にエディタがその設定を適用したりすることがあります。 推奨される使い方: Prettierと.editorconfigの両方を使用する場合、両方のインデント設定を一致させることが最も推奨されます。これにより、エディタでの自動整形とPrettierによる整形が一貫した挙動になります。

例: .editorconfig ファイル

# top-most EditorConfig file
root = true

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

[*.md]
trim_trailing_whitespace = false
  • indent_style = space: スペースでインデント
  • indent_size = 2: インデント幅を2に設定

エディタ/IDEのインデント設定

各開発者が使用するエディタやIDEには、独自のインデント設定があります。Prettierを使用している場合でも、エディタの設定がPrettierの動作に影響を与えることがあるため、これらの設定をPrettierと同期させることが重要です。

一般的な設定項目

  • ファイルのインデントを検出 (Detect Indentation)
    ファイルを開いた際に、そのファイルの既存のインデントスタイルを自動的に検出して適用するかどうか。
  • 自動インデント (Auto Indent)
    新しい行で自動的にインデントを挿入するかどうか。
  • インデントスタイル (Indent Style)
    タブ文字を使用するか、スペースを使用するか。
  • タブサイズ (Tab Size)
    タブ文字が何スペースとして表示されるか、またはスペースインデントの場合に何スペース使用するか。

Prettierとの連携

  • VS Codeの場合
    • Editor: Tab Size: PrettierのtabWidthと同じ値に設定します。
    • Editor: Insert Spaces: PrettierのuseTabsfalseならtrueに、trueならfalseに設定します。
    • Editor: Detect Indentation: Prettierを使用する場合は、これを無効にすることが推奨されます。Prettierが常に一貫したスタイルを適用するため、エディタが既存のインデントに合わせようとすると混乱を招くことがあります。
    • Prettier拡張機能自体の設定 (prettier.tabWidth など) も、.prettierrc の設定と一致しているか確認します。

例: VS Codeの settings.json

{
  "editor.tabSize": 2,
  "editor.insertSpaces": true, // useTabs: false と同じ意味
  "editor.detectIndentation": false,
  "prettier.tabWidth": 2, // Prettier拡張機能の設定
  "prettier.useTabs": false // Prettier拡張機能の設定
}

Git Pre-commit Hooks (Husky + lint-staged)

開発者がコミットする前に自動的にコードを整形するための強力な方法です。これにより、リポジトリに不適切なインデントのコードがコミットされるのを防ぎ、コードベース全体で一貫性を保証できます。

仕組み

  1. Husky
    Gitのフック(pre-commitなど)を簡単に設定できるようにするツール。
  2. lint-staged
    Gitのステージングエリアにあるファイルに対してのみLinterやFormatterを実行するツール。

Prettierとの連携
pre-commit フックで lint-staged を実行し、lint-staged がPrettierを呼び出して変更されたファイルを整形するように設定します。

例: package.json の設定

{
  "name": "my-project",
  "version": "1.0.0",
  "scripts": {
    "format": "prettier --write .",
    "precommit": "lint-staged" // Huskyがこれを実行
  },
  "devDependencies": {
    "prettier": "^3.0.0",
    "husky": "^9.0.0",
    "lint-staged": "^15.0.0"
  },
  "lint-staged": {
    "*.{js,jsx,ts,tsx,json,css,md}": [
      "prettier --write"
    ]
  },
  "prettier": { // .prettierrc の代わりに package.json に設定を記述
    "tabWidth": 2,
    "useTabs": false,
    "singleQuote": true
  }
}

そして、Huskyのセットアップ:

npm install husky --save-dev
npx husky init
npx husky add .husky/pre-commit "npm run precommit"

これで、git commit を実行するたびに、コミットされるファイルがPrettierによって自動的に整形されます。

Gitフックがクライアントサイドでのチェックであるのに対し、CI/CDパイプラインでのチェックはサーバーサイドで実行されます。これにより、万が一クライアントサイドのチェックがスキップされた場合でも、不適切なコードが本番環境にデプロイされるのを防ぐことができます。

仕組み
Pull Request (PR) が作成された際や、特定のブランチにマージされる前に、CI/CDパイプラインの一部としてPrettierのフォーマットチェックを実行します。

Prettierとの連携
Prettierを --check オプション付きで実行し、フォーマットされていないファイルがあればCI/CDビルドを失敗させます。

例: GitHub Actions のワークフローの一部

name: Code Quality

on:
  pull_request:
    branches: [ main, develop ]

jobs:
  format-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Install dependencies
        run: npm ci
      - name: Check formatting with Prettier
        run: npx prettier --check .

この設定では、main または develop ブランチへのプルリクエスト時に、Prettierがすべてのファイルをチェックし、フォーマット違反があればビルドが失敗します。

PrettierのtabWidthは、コードのインデントを統一するための中心的な設定ですが、より堅牢なインデント管理を実現するためには、以下の代替手段(または組み合わせ)を考慮することが重要です。

  • CI/CDパイプラインでのチェック
    リモートリポジトリへの不適切なコード流入を防止。
  • Git Pre-commit Hooks (Husky + lint-staged)
    コミット前に自動整形を強制。
  • エディタ/IDE設定
    開発環境の設定をPrettierと同期させる。
  • .editorconfig
    エディタ間での一貫性を確保。