PrettierのPrint Widthでよくあるエラーと解決策

2025-06-06

Prettierにおける「Print Width」とは、コードの1行の最大文字数を指します。Prettierは、この設定値に基づいて、コードを自動的に整形し、指定された幅を超えないように改行を行います。

もう少し詳しく説明します。

  • 例外: Prettierは賢く、必ずしもすべての行をPrint Widthに収めるわけではありません。例えば、長い文字列リテラルやURLなど、分割すると可読性が著しく低下する場合などは、Print Widthを超えてもそのままにする場合があります。

  • 一般的な値:

    • よく使われる値は80文字や120文字です。
    • 歴史的に80文字が使われることが多かったですが、最近ではより広いディスプレイを使用する人が増えたため、120文字など、より大きな値を設定するプロジェクトも増えています。
    • チームや個人の好みに合わせて設定できます。
  • 設定方法:

    • 通常は、プロジェクトのルートにある.prettierrcのような設定ファイルでprintWidthというオプションを設定します。
    • 例:
      {
        "printWidth": 80
      }
      
      この場合、Prettierは1行の最大文字数を80文字に制限します。
  • 動作: Prettierは、コードを整形する際に、各行がPrint Widthで指定された文字数を超えないように調整します。例えば、関数呼び出しの引数が長くなったり、配列の要素がたくさんあったりする場合、Prettierは自動的にそれらを複数行に分割してくれます。

  • 目的: プロジェクト全体のコードスタイルを統一し、可読性を向上させることです。1行が長すぎると、横スクロールが必要になったり、コード全体の構造が把握しにくくなったりします。Print Widthを設定することで、この問題を解決します。



Prettier が printWidth の設定を無視する

よくある原因

  • エディタの再起動が必要
    • 設定ファイルを変更した後、エディタ(VS Codeなど)を再起動しないと、変更が反映されないことがあります。
  • 他のフォーマッターとの競合
    • ESLint や他のコードフォーマッターが Prettier と同時に有効になっていて、設定が競合している場合があります。特に ESLint の max-len ルールと Prettier の printWidth は混同されがちです。
  • ファイルの種類が対応していない
    • Prettier は、デフォルトで全てのファイル形式に対応しているわけではありません。特定のファイル形式(例: .tsx)を整形するには、別途プラグインのインストールが必要な場合があります。
  • 設定ファイルが読み込まれていない
    • .prettierrcprettier.config.js.prettierrc.json などの設定ファイルがプロジェクトのルートに正しく配置されていない。
    • VS Codeなどのエディタ拡張機能が、プロジェクトの設定ではなく、グローバル設定を読み込んでいる可能性がある。

トラブルシューティング

  • エディタの再起動
    • 設定変更後は、エディタを完全に再起動してみてください。
  • Prettier の出力ログを確認
    • VS Code の「出力」タブで「Prettier」を選択し、フォーマット実行時のログを確認します。エラーメッセージや設定の読み込み状況が表示される場合があります。
  • 競合する拡張機能の無効化
    • 一時的に ESLint などの他のフォーマッター関連の拡張機能を無効にして、Prettier の動作を確認します。
    • ESLint と Prettier を併用する場合は、eslint-config-prettiereslint-plugin-prettier を利用して、競合するルールを無効化する設定が必要です。
  • .editorconfig の確認
    • .editorconfig ファイルがプロジェクトに存在する場合、max_line_length の設定が Prettier の printWidth を上書きしている可能性があります。.editorconfig の設定も確認してください。
  • エディタ設定の確認
    • VS Codeの場合、settings.jsoneditor.defaultFormatteresbenp.prettier-vscode に設定されているか確認します。
    • また、特定の言語のフォーマッターが上書きされていないか確認します(例: "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" })。
  • 設定ファイルの確認
    • プロジェクトのルートに .prettierrcprettier.config.js などの設定ファイルが正しく存在するか確認します。
    • 設定ファイル内の printWidth オプションの値を確認します(例: printWidth: 120)。

printWidth を超えても改行されないケースがある

よくある原因

  • 特定の構文の例外ルール
    • Prettier には、特定の構文(JSX、HTMLなど)に対して、printWidth とは別に独自の整形ルールが存在する場合があります。例えば、HTMLのインライン要素内の空白は printWidth の影響を受けにくいことがあります。
  • printWidth は「厳密な上限」ではない
    • Prettier の printWidth は、あくまで「目安」であり、厳密な行の長さの上限ではありません。Prettier は、可読性を損なわずに整形できる範囲で printWidth を遵守しようとします。
    • 例えば、非常に長い文字列リテラルやURL、分割すると意味が変わってしまうコードブロックなどは、printWidth を超えても改行されないことがあります。

トラブルシューティング

  • エディタの「ソフトラップ(折り返し)」機能を利用する
    • Prettier で強制的に改行させたくないが、視覚的に長い行を折り返して表示したい場合は、エディタのソフトラップ(Word Wrap)機能を有効にするのが最も簡単な解決策です。これはコードの実際の改行には影響せず、表示上のみ折り返されます。
  • printWidth の値を調整する
    • もし、多くの箇所で printWidth を超える行が頻繁に発生し、それが視覚的に問題となる場合は、printWidth の値を少し大きくする(例: 80 → 120)ことを検討します。ただし、これは問題の根本的な解決にはなりません。
  • コードの構造を見直す
    • 長すぎる行は、そもそもコードの書き方自体に問題がある可能性があります。変数を導入して式を短くしたり、関数を分割したりするなど、コードの構造自体を見直すことを検討します。
  • // prettier-ignore コメントの利用
    • Prettier に整形させたくない特定の行やブロックがある場合、その直前に // prettier-ignore コメントを追加することで、その部分の整形をスキップさせることができます。
    • これは、一時的な対処法として有効ですが、多用するとコードスタイルの一貫性が損なわれる可能性があります。

よくある原因

  • 改行コードの違い
    • Windows と Linux/macOS で改行コード(CRLF vs LF)の違いがある場合、意図しない差分が生じることがあります。
  • Prettier の実行設定が誤っている
    • Git の pre-commit hook や CI/CD パイプラインで Prettier を実行する際のコマンドや設定が間違っている。
  • 異なる Prettier バージョン
    • 開発環境と CI/CD 環境で Prettier のバージョンが異なると、整形結果が異なる場合があります。
  • 改行コードの設定
    • .prettierrcendOfLine: "lf" を設定し、改行コードを統一します。
    • Git の .gitattributes ファイルに * text=auto eol=lf を追加することで、Git が自動的に改行コードを変換するのを防ぎ、LF に統一することができます。
  • --check フラグの利用
    • CI/CD パイプラインでは、prettier --check . のように --check フラグを付けて実行し、整形が必要なファイルがないか確認します。差分があればエラーとして扱います。
  • Prettier のバージョンを固定する
    • package.json に Prettier のバージョンを明示的に記述し、npm installyarn install で常に同じバージョンがインストールされるようにします。


例1: 基本的な関数の引数と printWidth

printWidth: 80 の場合

元のコード (整形前)

function calculateTotalAmount(price, quantity, discountPercentage, taxRate) {
  const subtotal = price * quantity;
  const discountedPrice = subtotal * (1 - discountPercentage);
  const total = discountedPrice * (1 + taxRate);
  return total;
}

Prettier で整形後 (printWidth: 80)

function calculateTotalAmount(
  price,
  quantity,
  discountPercentage,
  taxRate
) {
  const subtotal = price * quantity;
  const discountedPrice = subtotal * (1 - discountPercentage);
  const total = discountedPrice * (1 + taxRate);
  return total;
}

解説
printWidth: 80 の場合、calculateTotalAmount 関数の引数が1行に収まらないため、Prettier は自動的に引数を複数行に分割し、インデントを調整します。これにより、コードの可読性が向上します。

printWidth: 120 の場合

Prettier で整形後 (printWidth: 120)

function calculateTotalAmount(price, quantity, discountPercentage, taxRate) {
  const subtotal = price * quantity;
  const discountedPrice = subtotal * (1 - discountPercentage);
  const total = discountedPrice * (1 + taxRate);
  return total;
}

解説
printWidth: 120 の場合、関数の引数が1行に収まるため、Prettier は改行を行いません。

例2: 配列とオブジェクトリテラル

元のコード (整形前)

const fruits = ["apple", "banana", "orange", "grape", "kiwi", "strawberry", "melon", "pineapple"];

const userProfile = {
  firstName: "John",
  lastName: "Doe",
  age: 30,
  email: "[email protected]",
  address: {
    street: "123 Main St",
    city: "Anytown",
    zipCode: "12345",
    country: "USA",
  },
};

Prettier で整形後 (printWidth: 80)

const fruits = [
  "apple",
  "banana",
  "orange",
  "grape",
  "kiwi",
  "strawberry",
  "melon",
  "pineapple",
];

const userProfile = {
  firstName: "John",
  lastName: "Doe",
  age: 30,
  email: "[email protected]",
  address: {
    street: "123 Main St",
    city: "Anytown",
    zipCode: "12345",
    country: "USA",
  },
};

解説
printWidth: 80 では、fruits 配列の要素が1行に収まらないため、Prettier は各要素を個別の行に分割します。 userProfile オブジェクトも同様に、ネストされた address オブジェクトを含め、各プロパティが整形されます。

Prettier で整形後 (printWidth: 120)

const fruits = ["apple", "banana", "orange", "grape", "kiwi", "strawberry", "melon", "pineapple"];

const userProfile = {
  firstName: "John",
  lastName: "Doe",
  age: 30,
  email: "[email protected]",
  address: {
    street: "123 Main St",
    city: "Anytown",
    zipCode: "12345",
    country: "USA",
  },
};

解説
printWidth: 120 の場合、fruits 配列は1行に収まるため、改行は行われません。userProfile オブジェクトは、ネストが深いため、printWidth が大きくても各プロパティが複数行に分割される可能性があります。これは、オブジェクトの可読性を保つための Prettier の内部ルールによるものです。

例3: JSX (React)

元のコード (整形前)

function MyComponent({ title, description, imageUrl, buttonText, onClickButton }) {
  return (
    <div className="card">
      <h2 className="card-title">{title}</h2>
      <p className="card-description">{description}</p>
      <img src={imageUrl} alt="Card Image" className="card-image" />
      <button className="card-button" onClick={onClickButton}>{buttonText}</button>
    </div>
  );
}

Prettier で整形後 (printWidth: 80)

function MyComponent({
  title,
  description,
  imageUrl,
  buttonText,
  onClickButton,
}) {
  return (
    <div className="card">
      <h2 className="card-title">{title}</h2>
      <p className="card-description">{description}</p>
      <img src={imageUrl} alt="Card Image" className="card-image" />
      <button className="card-button" onClick={onClickButton}>
        {buttonText}
      </button>
    </div>
  );
}

解説
JSX の props が多い場合も、printWidth を超えると Prettier は自動的に改行を行います。特に、button タグのように中身がある場合は、その中身も改行して整形されます。

Prettier で整形後 (printWidth: 120)

function MyComponent({ title, description, imageUrl, buttonText, onClickButton }) {
  return (
    <div className="card">
      <h2 className="card-title">{title}</h2>
      <p className="card-description">{description}</p>
      <img src={imageUrl} alt="Card Image" className="card-image" />
      <button className="card-button" onClick={onClickButton}>
        {buttonText}
      </button>
    </div>
  );
}

解説
printWidth: 120 でも、JSX の props は1行に収まる可能性がありますが、Prettier は JSX の開始タグと終了タグの可読性を考慮して、特定のパターンで改行を行うことがあります。この例では、button タグの中身は printWidth の影響を受けずに改行される可能性が高いです。

これらの例は、通常、プロジェクトのルートにある .prettierrc ファイルで printWidth オプションを設定することで実現されます。

.prettierrc ファイルの例 (JSON形式)

{
  "printWidth": 80,
  "tabWidth": 2,
  "semi": true,
  "singleQuote": true,
  "trailingComma": "es5"
}

または、JavaScript 形式でコメントを記述することも可能です。

module.exports = {
  printWidth: 120, // 1行の最大文字数を120に設定
  tabWidth: 2, // インデント幅を2に設定
  semi: true, // 文末のセミコロンを強制
  singleQuote: true, // シングルクォートを使用
  trailingComma: 'es5', // オブジェクトや配列の末尾にカンマを付ける (ES5互換)
};


Prettier の他のオプションで printWidth の動作を微調整する

これは厳密には「代替」ではありませんが、printWidth を補完・微調整する Prettier 自身のオプションについて理解することは重要です。

  • singleAttributePerLine: HTML、Vue、JSX の要素の属性を1行に1つずつ配置するかどうかを制御します。printWidth が小さい場合に、属性が自動的に複数行に分割されるのを助けます。
  • htmlWhitespaceSensitivity: HTML、Vue、Angular、Handlebars の空白の扱いを制御します。cssstrictignore などの値があり、HTML タグ内のテキストやインライン要素の改行に影響を与えることがあります。これにより、printWidth で強制的に改行されるのを防いだり、逆に意図した改行を促したりできます。
  • proseWrap: Markdown のような散文的なテキスト(プログラミングコードではない部分)に対する改行の挙動を制御します。always(常に printWidth で折り返す)、never(折り返さない)、``preserve`(元の改行を保持する)などの値があります。特に Markdown ドキュメントを Prettier で整形する場合に重要になります。

なぜ重要か
これらのオプションは、printWidth が意図しない改行を引き起こす場合や、特定のファイルタイプでprintWidth の挙動をより細かく制御したい場合に役立ちます。printWidth だけでは解決できない見た目の問題を解決できることがあります。

コードの構造自体を見直す(リファクタリング)

これは Prettier の設定そのものではありませんが、printWidth を超える行が頻繁に発生する場合の最も根本的な解決策の一つです。

  • ネストの深さの削減: if 文や for ループ、関数呼び出しなどが深くネストしていると、インデントが増えて printWidth を圧迫します。早期リターン(ガード句)の使用、小さい関数への分割、戦略パターンの適用などでネストを浅くすることを検討します。
  • インライン化の回避: 複雑な条件式や計算を直接 JSX や関数の引数にインラインで記述すると、行が長くなりがちです。これらを別の変数に抽出したり、ヘルパー関数にカプセル化したりすることで、コードの可読性を高め、行の長さを短縮できます。
  • 長いチェーンメソッドの分割: someArray.filter(...).map(...).sort(...).forEach(...) のように長いメソッドチェーンは、printWidth に収まりにくく、途中の処理が分かりにくくなることがあります。中間変数を導入したり、各処理を個別の関数に分離したりすることで、コードをより読みやすく、printWidth に収まるようにできます。

なぜ重要か
printWidth はあくまで表面的な整形ツールです。根本的に行が長すぎるコードは、設計上の問題(凝集度の低さ、結合度の高さなど)を抱えている可能性があります。コードの構造自体を改善することで、より保守しやすく、理解しやすいコードになります。

エディタの表示設定で対応する(ソフトラップ/Word Wrap)

これはコードの整形とは異なりますが、表示上の問題を解決するための代替手段です。

  • ソフトラップ (Word Wrap): 多くのモダンなエディタ(VS Code, Sublime Text, JetBrains IDEsなど)には「ソフトラップ」または「単語の折り返し」機能があります。これを有効にすると、printWidth を超える行があった場合でも、実際の改行コードを挿入することなく、表示上のみ次の行に折り返して表示されます。

なぜ重要か

  • 特定の長い行への対処: Prettier があえて改行しないような長い文字列リテラルや URL など、意味的に分割できない行を視覚的に見やすくしたい場合に非常に有効です。
  • 柔軟な表示: ユーザーは自分の好みに合わせてエディタの表示幅を調整でき、それに合わせてコードが自動的に折り返されるため、個々の環境での可読性を最適化できます。
  • ファイルサイズへの影響なし: 実際の改行コードが挿入されないため、ファイルのサイズが増えたり、Git の差分が不要に増えたりすることがありません。

注意点
これはあくまで表示上の問題解決であり、Prettier の整形ルールとは直接関係ありません。コードベース全体の整形ルールを統一したい場合は、やはり Prettier の printWidth 設定が重要になります。

ESLint の max-len ルールとの連携(非推奨だが考慮事項)

かつては ESLint の max-len ルールと Prettier の printWidth が似たような機能を持っていたため、どちらを使うか、あるいはどう連携させるかが議論の対象でした。

  • max-len (ESLint): ESLint には、1行の最大文字数を制限する max-len ルールがあります。このルールは、codecommentsignorePattern など、より詳細な設定が可能です。

現在の推奨
**基本的には、行の長さの整形に関しては Prettier の printWidth に一任し、ESLint の max-len ルールは無効化するか、Prettier と競合しないように設定することが強く推奨されています。**これは、eslint-config-prettier を利用することで簡単に実現できます。

なぜ非推奨か

  • Prettier の優位性: Prettier はフォーマッターに特化しており、行の長さの整形においてより高度なロジックを持っています。単に行の長さをチェックするだけでなく、読みやすさを考慮した上で最適な位置で改行を行います。
  • 競合と混乱: Prettier と ESLint の両方で行の長さを制御しようとすると、設定が競合したり、意図しない挙動になったりして、開発者に混乱を招きます。

Prettier の printWidth は、コード整形における「行の長さ」を定義する標準的な方法であり、ほとんどのプロジェクトでこれを中心に据えるべきです。しかし、上記の代替方法や補完的なアプローチを理解することで、より複雑な整形要件に対応したり、コードの根本的な品質改善に取り組んだり、あるいは開発者の視覚的な好みにも対応したりすることが可能になります。

  • ESLint との連携: 行の長さの整形は Prettier に一任し、ESLint との競合を避ける設定を行う。 Prettierの printWidth は、コードの自動整形において非常に強力なツールですが、その「意見が強い(opinionated)」という性質から、特定のユースケースでは代替手段や補完的なアプローチを検討することもあります。
  • エディタのソフトラップ: 表示上の問題であれば、エディタの機能で解決する。
  • リファクタリング: printWidth を超えるコードが多い場合は、コードの構造そのものに改善の余地がないか考える。
  • Prettier の微調整: printWidth だけでは解決しない見た目の問題には、proseWraphtmlWhitespaceSensitivity などのオプションを検討する。

ESLint の max-len ルール

max-len (maximum line length) は、ESLint のルールの一つで、1行の最大文字数を強制することができます。Prettier の printWidth と似ていますが、以下の点で異なります。

  • ESLint の max-len
    これは「厳密な上限」として機能します。指定された文字数を超えると、警告(warning)またはエラー(error)として報告されます。
  • Prettier の printWidth
    あくまで「目安」であり、Prettier は可読性を損なわずに整形できる範囲でこの幅を目指します。長い文字列リテラルなど、Prettier が分割すべきではないと判断した場合は、printWidth を超えることがあります。

使い分けの例

  • Prettierを使用せず、ESLintのみでフォーマットする場合
    Prettierのような自動フォーマッターを導入せず、ESLint のルールのみでコードスタイルを管理したい場合に max-len を使用します。この場合、ESLint の自動修正機能(eslint --fix)で一部の整形を行うことができますが、Prettierほど網羅的ではありません。
  • Prettierと併用する場合
    一般的に、Prettier と ESLint を併用するプロジェクトでは、eslint-config-prettier を利用して、ESLint の整形に関するルール(max-lenを含む)を無効にすることが推奨されます。これにより、Prettier と ESLint のルールが競合するのを防ぎ、Prettier にフォーマットを一任します。
    • ただし、例外
      Prettier が整形しないような極端に長い行(例:超長文のコメントなど)に対してのみ、ESLint の max-len を警告として設定し、開発者に注意を促すといった使い方をするケースもあります。

設定例 (.eslintrc.js)

module.exports = {
  // ...その他のESLint設定
  rules: {
    // Prettierと併用する場合は通常offにするか、eslint-config-prettierで無効化される
    // 'max-len': ['error', { code: 100, ignoreComments: true, ignoreUrls: true }],
    // 例:Prettierが整形しないコメントの長さを警告する場合
    'max-len': ['warn', { code: 120, ignoreStrings: true, ignoreTemplateLiterals: true, ignoreUrls: true }],
  },
};

EditorConfig の max_line_length

EditorConfig は、様々なエディタやIDE間でコードスタイルを統一するためのファイル形式です。.editorconfig ファイルをプロジェクトのルートに配置することで、インデントのスタイル、タブの幅、改行コード、そして行の最大長などを設定できます。

  • エディタ/IDEとの連携
    .editorconfig は、多くのエディタ(VS Code, IntelliJ IDEA, Sublime Textなど)がネイティブでサポートしているため、Prettierを使わない環境でも基本的なコードスタイルを統一するのに役立ちます。
  • Prettierとの連携
    Prettier は、デフォルトで .editorconfig ファイルを読み込み、そこに max_line_length が設定されていれば、その値を printWidth として使用します(ただし、.prettierrcprintWidth が明示的に設定されている場合はそちらが優先されます)。

設定例 (.editorconfig)

# top-most EditorConfig file
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100  # 1行の最大文字数を100に設定

メリット
Prettier がインストールされていない環境や、特定のファイルタイプ(Prettier がサポートしていない言語など)に対しても、基本的な行の長さを統一するのに使えます。

これはコードの整形方法ではありませんが、長い行の表示に関する「代替」として考慮されることがあります。

  • 使いどころ
    • Prettier に強制的に改行させたくないが、横スクロールは避けたい場合に有効です。
    • 特に、Prettier が改行を避けるような長い文字列リテラルやURLなどに対して、視覚的な読みやすさを確保するために利用できます。
  • Prettierとの違い
    • Prettier の printWidth は、実際にコードファイル内の改行を挿入して整形します。
    • ソフトラップは、あくまで「表示上の折り返し」であり、実際のファイル内容には変更を加えません。
  • 機能
    多くのエディタやIDEには、設定された行の長さやウィンドウの幅に合わせて、表示上のみ行を折り返す「ソフトラップ」または「単語の折り返し(Word Wrap)」機能があります。

設定例 (VS Code)

settings.json または VS Code の設定UIで editor.wordWrapon に設定します。

{
  "editor.wordWrap": "on"
}

Prettier 以外にも、コードの整形やスタイルの強制を行うツールは存在します。これらの中には、printWidth に相当する設定を持つものや、より詳細なカスタマイズが可能なものもあります。

  • 言語固有のフォーマッター
    • Go言語の gofmt、Rust言語の rustfmt、Pythonの Black など、特定のプログラミング言語に特化した公式または推奨のフォーマッターがあります。
    • これらは通常、その言語のベストプラクティスに従った非常に意見の強い整形を行います。多くの場合、printWidth に相当するような厳密な行の長さのオプションは存在せず、ツールが最適な行の長さを判断します。
  • JS Beautifier (js-beautify)
    • JavaScript、HTML、CSS を整形するためのツールです。
    • indent_sizemax_preserve_newlines など、より多くの整形オプションを提供します。
    • max_line_length のような直接的な printWidth に代わるオプションはありますが、Prettier ほど構文解析に基づいてインテリジェントに改行を行うわけではありません。
  • StandardJS
    • 「設定なし(zero-config)」を哲学とする、非常に意見が強い(opinionated)JavaScriptのスタイルガイド兼リンター兼フォーマッターです。
    • printWidth に相当する直接的な設定はありませんが、StandardJS のルールセットに従って自動的に整形されます。
    • Prettier と同様に、開発者がスタイルの議論に時間を費やすのを避けることを目的としています。
  • 他のフォーマッター/リンター
    Prettier の意見が強いアプローチが合わない場合や、より詳細なカスタマイズが必要な場合。
  • エディタのソフトラップ
    ファイル内容を変更せず、表示上の長い行を折り返したい場合。
  • EditorConfig の max_line_length
    エディタ間の設定統一や、Prettier を使わない環境での基本的なスタイル強制に。
  • ESLint の max-len
    Prettier との競合を避けつつ、特定の状況で厳密な行の長さを強制したい場合。