これで解決!Prettier Tab Widthのよくあるエラーとトラブルシューティング
「Tab Width」は、Prettierにおける重要な設定の一つで、コードのインデント(字下げ)の幅を決定します。具体的には、タブ文字 (\t
) が表示上何スペース分の幅を持つか、あるいはスペースでインデントする場合に何スペースを使うかを指定します。
「Tab Width」の役割と設定
プログラミングにおいて、インデントはコードの構造を視覚的に分かりやすくするために不可欠です。Prettierは、設定された「Tab Width」に基づいて、コードを自動的に整形します。
設定可能な値
4
に設定すると、インデントは4スペース分になります。2
に設定すると、インデントは2スペース分になります。- 通常は整数で指定します。例えば、
2
や4
などが一般的です。
設定方法
Prettierの設定ファイル(例: .prettierrc
、package.json
のprettier
フィールドなど)で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つのスペースが使用されます。
-
tabWidth: 4, useTabs: true
- インデントにはタブ文字が使用され、そのタブ文字は表示上4スペース分の幅を持ちます。
多くのプロジェクトでは、一貫性を保つためにtabWidth
とuseTabs
を適切に設定し、チーム全体で同じインデントルールを適用しています。
よくあるエラーと問題
-
- Prettierを設定したはずなのに、コードが期待するタブ幅(例: 2スペースや4スペース)で整形されない。
- タブとスペースが混在してしまっている。
-
エディタの表示とPrettierの整形結果が一致しない
- VS Codeなどのエディタでタブ幅を4スペースに設定しているのに、Prettierで整形すると2スペースになってしまう。
- またはその逆。
-
プロジェクト内でインデントがバラバラになる
- チームメンバーや異なる環境で作業すると、同じファイルでもインデントの幅が異なってしまう。
-
.prettierrcなどの設定ファイルが無視される
- 設定ファイルに
tabWidth
を記述しているのに、Prettierがその設定を適用してくれない。
- 設定ファイルに
これらの問題のほとんどは、設定の競合や優先順位の理解不足によって引き起こされます。
設定ファイルの競合を確認する
Prettierは複数の場所から設定を読み込みます。優先順位は以下のようになります(上に行くほど優先度が高い)。
- エディタ(VS Codeなど)のPrettier拡張機能の設定
- Prettierのデフォルト設定
package.json
のprettier
フィールド.prettierrc
/.prettierrc.json
/prettier.config.js
などのプロジェクト固有の設定ファイル- インライン設定(
// prettier-ignore
など)
確認すべきこと
- ワークスペース設定とユーザー設定の確認 (VS Codeの場合)
- VS Codeでは、グローバルな「ユーザー設定」と、プロジェクト固有の「ワークスペース設定」があります。ワークスペース設定はユーザー設定よりも優先されます。意図した
tabWidth
がワークスペース設定で上書きされていないか確認しましょう。
- VS Codeでは、グローバルな「ユーザー設定」と、プロジェクト固有の「ワークスペース設定」があります。ワークスペース設定はユーザー設定よりも優先されます。意図した
.editorconfig
ファイルがないか?.editorconfig
はエディタのインデント設定などを統一するためのファイルで、Prettierよりもエディタが優先して読み込むことがあります。もしプロジェクトに.editorconfig
があり、indent_size
やindent_style
が設定されている場合、それがPrettierの挙動に影響を与える可能性があります。.editorconfig
の設定とPrettierの設定を一致させるか、どちらかを無効化することを検討してください。
- 複数の設定ファイルが存在しないか?
- 例えば、
.prettierrc.json
とpackage.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.tabWidth
とprettier.useTabs
の設定も確認し、意図した通りになっているか確認します。
- VS Codeのユーザー設定またはワークスペース設定を開きます(
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.json
のprettier
フィールドなど)を一時的に削除またはコメントアウトしてテストします。これにより、問題の切り分けがしやすくなります。
これらの例は、Prettierがどのようにコードを整形するか、そしてtabWidth
設定がそれにどのように影響するかを示します。
例1: 基本的な tabWidth
の設定と効果
この例では、tabWidth
を 2
に設定した場合と 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: tabWidth
と useTabs
の組み合わせ
tabWidth
はインデントの「幅」を指定しますが、実際にタブ文字 (\t
) を使うかスペースを使うかは useTabs
オプションで決定します。
設定ファイル (.prettierrc) の準備
A. tabWidth: 4
, useTabs: true
の場合
{
"tabWidth": 4,
"useTabs": true,
"singleQuote": true
}
Note: tabWidth: 4
と useTabs: 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.js
はtabWidth: 2
に従って整形されます。
.editorconfig ファイルの使用
.editorconfig
は、異なるエディタやIDE間で一貫したコーディングスタイルを定義するためのファイルフォーマットです。PrettierのtabWidth
設定と競合する場合があるため、理解しておくことが重要です。
特徴
- ファイルパスに基づいて設定を適用できるため、プロジェクト内の異なる種類のファイルで異なるスタイルを適用することも可能です。
- 多くの主要なエディタ(VS Code, IntelliJ IDEA, Sublime Textなど)がネイティブでサポートしています。
- エディタレベルでのインデント設定(
indent_size
、indent_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のuseTabs
がfalse
なら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)
開発者がコミットする前に自動的にコードを整形するための強力な方法です。これにより、リポジトリに不適切なインデントのコードがコミットされるのを防ぎ、コードベース全体で一貫性を保証できます。
仕組み
- Husky
Gitのフック(pre-commit
など)を簡単に設定できるようにするツール。 - 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
エディタ間での一貫性を確保。