Prettier

コード品質フォーマッターJavaScriptTypeScriptDevOps自動整形ゼロ設定

DevOpsツール

Prettier

概要

Prettierは、多言語対応のコードフォーマッターです。一貫したコードスタイルを自動的に適用し、コードレビューでのスタイル議論を不要にする「Opinionated Code Formatter」。設定不要で利用可能な「ゼロ設定」哲学により、チーム開発でのコードスタイル統一を簡素化。JavaScript、TypeScript、CSS、HTML、JSON、Markdown等の多言語をサポートし、エディターやCI統合により開発ワークフローに自然に組み込まれます。

詳細

Prettier(プリティア)は2017年にFacebookが開発したコードフォーマッターで、「コードフォーマットに関する議論を終わらせる」というコンセプトで設計されています。従来のコードフォーマッターとは異なり、意図的に設定項目を最小限に抑制し、一貫したコードスタイルを強制的に適用する「Opinionated」なアプローチを採用。

主要な特徴

  • ゼロ設定哲学: 設定なしで即座に利用可能、議論の余地を排除
  • 多言語サポート: JavaScript、TypeScript、CSS、HTML、JSON、Markdown、YAML等
  • エディター統合: VS Code、IntelliJ IDEA、Vim、Emacs等への公式プラグイン
  • 高度な構文解析: ASTベースの解析により高品質なフォーマット実現
  • 完全な冪等性: 何度実行しても同じ結果、安定したフォーマット
  • Git Hooks統合: pre-commitフックによる自動フォーマット
  • CI/CD統合: GitHub Actions、GitLab CI等での自動チェック・修正
  • プラグインエコシステム: Tailwind CSS、Solidity等の専用プラグイン

2025年現在、React、Vue.js、Angular、Next.js等の主要プロジェクトで標準採用され、「設定より規約」の開発文化を推進しています。

メリット・デメリット

メリット

  • 設定不要でチーム全体のコードスタイル統一が即座に実現
  • コードレビューでフォーマットに関する議論が完全に排除
  • エディター統合によるリアルタイム自動フォーマットで開発効率向上
  • 多言語対応により単一ツールで複数技術のフォーマット統一
  • Git Hooks統合によりコミット時の自動品質保証
  • 高度なAST解析によりコードの意味を理解した最適なフォーマット
  • 豊富なエディター・IDE統合でシームレスな開発体験
  • プラグインエコシステムにより特殊な言語・フレームワーク対応

デメリット

  • カスタマイズ性の限界(意図的な制約だが柔軟性に欠ける)
  • 大規模レガシーコードへの適用時の大幅な変更リスク
  • 個人・チームの既存コーディング習慣との乖離可能性
  • 一部言語でのフォーマット品質の限界(特殊構文等)
  • プラグイン依存による設定複雑化の可能性
  • パフォーマンス:大量ファイルでの実行時間
  • 完全制御不可:特定箇所のフォーマット無効化が困難
  • バージョン間でのフォーマット仕様変更による差分発生

参考ページ

書き方の例

インストールと基本セットアップ

# Prettierのインストール(プロジェクトローカル推奨)
npm install --save-dev prettier

# グローバルインストール(個人開発用)
npm install -g prettier

# 設定ファイル無しで即座に使用可能
npx prettier --write src/

# 基本設定ファイル作成(オプション)
echo '{"semi": false, "singleQuote": true}' > .prettierrc.json

# package.jsonにスクリプト追加
npm pkg set scripts.format="prettier --write ."
npm pkg set scripts.format:check="prettier --check ."

基本的な設定ファイル

# .prettierrc.json(JSON形式)
{
  "printWidth": 80,           # 1行の最大文字数
  "tabWidth": 2,              # インデント幅
  "useTabs": false,           # タブ使用(false=スペース)
  "semi": true,               # セミコロン
  "singleQuote": false,       # クォート(false=ダブル、true=シングル)
  "quoteProps": "as-needed",  # オブジェクトのプロパティクォート
  "trailingComma": "es5",     # 末尾カンマ(es5|all|none)
  "bracketSpacing": true,     # 中括弧内のスペース
  "bracketSameLine": false,   # JSX終了ブラケットを同一行に
  "arrowParens": "always",    # アロー関数の括弧(always|avoid)
  "endOfLine": "lf"           # 改行コード(lf|crlf|cr|auto)
}
# .prettierrc.yml(YAML形式)
printWidth: 80
tabWidth: 2
useTabs: false
semi: true
singleQuote: true
quoteProps: "as-needed"
trailingComma: "es5"
bracketSpacing: true
bracketSameLine: false
arrowParens: "always"
endOfLine: "lf"

# ファイル種別ごとの設定
overrides:
  - files: "*.test.js"
    options:
      semi: true
  - files: 
      - "*.html"
      - "legacy/**/*.js"
    options:
      tabWidth: 4
// prettier.config.js(JavaScript形式)
/**
 * @see https://prettier.io/docs/configuration
 * @type {import("prettier").Config}
 */
const config = {
  printWidth: 100,
  tabWidth: 2,
  useTabs: false,
  semi: false,
  singleQuote: true,
  quoteProps: "as-needed",
  trailingComma: "all",
  bracketSpacing: true,
  bracketSameLine: false,
  arrowParens: "avoid",
  endOfLine: "lf",
  
  // プラグイン設定
  plugins: [
    "prettier-plugin-organize-imports",
    "prettier-plugin-tailwindcss",
  ],
  
  // 言語固有設定
  overrides: [
    {
      files: "*.json",
      options: {
        printWidth: 120,
      },
    },
    {
      files: "*.md",
      options: {
        proseWrap: "always",
        printWidth: 80,
      },
    },
  ],
};

export default config;

コマンドライン実行パターン

# 基本的なフォーマット実行
npx prettier --write src/

# 特定ファイルのフォーマット
npx prettier --write src/index.js

# 複数パターン指定
npx prettier --write "src/**/*.{js,ts,tsx,json,css,md}"

# フォーマット確認(変更なし)
npx prettier --check src/

# 設定ファイル指定
npx prettier --write src/ --config ./custom-prettier.config.js

# 特定オプション指定
npx prettier --write src/ --single-quote --trailing-comma all

# 未知ファイル無視
npx prettier --write "**/*" --ignore-unknown

# ファイル差分のみ表示
npx prettier --list-different src/

# キャッシュ使用(高速化)
npx prettier --write src/ --cache

# 設定ファイル検索
npx prettier --find-config-path src/index.js

# 詳細ログ出力
npx prettier --write src/ --loglevel debug

# 対象ファイル確認
npx prettier --write src/ --list-different

エディター統合設定例

VS Code設定

// .vscode/settings.json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.formatOnPaste": true,
  "editor.formatOnType": false,
  
  // 言語別設定
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[markdown]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.wordWrap": "on"
  },
  
  // Prettier固有設定
  "prettier.requireConfig": true,     // 設定ファイル必須
  "prettier.useEditorConfig": false,  // EditorConfig連携
  "prettier.ignorePath": ".prettierignore"
}

IntelliJ IDEA設定

// Prettierプラグインインストール後
// Settings → Languages & Frameworks → JavaScript → Prettier

// Run on save for files: *.{js,ts,jsx,tsx,css,scss,json,md}
// Node interpreter: Project Node
// Prettier package: node_modules/prettier

Git Hooks統合

# huskyインストール
npm install --save-dev husky lint-staged

# husky初期化
npx husky init

# pre-commitフック作成
echo 'npx lint-staged' > .husky/pre-commit

# lint-staged設定(package.json)
npm pkg set lint-staged.*.{js,ts,tsx,css,md}="prettier --write"

# または別ファイルで設定
# .lintstagedrc.json
{
  "*.{js,ts,tsx,json,css,md}": [
    "prettier --write"
  ],
  "*.{js,ts,tsx}": [
    "eslint --fix"
  ]
}

CI/CD統合例

# .github/workflows/format-check.yml
name: Format Check

on: [push, pull_request]

jobs:
  format-check:
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '20'
        cache: 'npm'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Check Prettier formatting
      run: npx prettier --check .
    
    - name: Comment PR if formatting issues found
      if: failure() && github.event_name == 'pull_request'
      uses: actions/github-script@v7
      with:
        script: |
          github.rest.issues.createComment({
            issue_number: context.issue.number,
            owner: context.repo.owner,
            repo: context.repo.repo,
            body: '❌ Code formatting issues detected. Please run `npm run format` to fix.'
          });

# 自動修正版(autofix.ci使用)
name: Auto-format
on:
  pull_request:
  push:
    
jobs:
  prettier:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
      - run: |
          npm ci
          npx prettier . --write
      - uses: autofix-ci/action@v1
        with:
          commit-message: "Apply Prettier formatting"

プラグイン使用例

// prettier.config.js - プラグイン統合例
import organizeImports from "prettier-plugin-organize-imports";
import tailwindcss from "prettier-plugin-tailwindcss";
import sortImports from "@trivago/prettier-plugin-sort-imports";

export default {
  plugins: [
    organizeImports,    // import文自動整理
    sortImports,        // import文ソート
    tailwindcss,        // Tailwind CSSクラスソート
  ],
  
  // @trivago/prettier-plugin-sort-imports設定
  importOrder: [
    "^react$",
    "^next",
    "^@?\\w",
    "^[./]"
  ],
  importOrderSeparation: true,
  importOrderSortSpecifiers: true,
  
  // 基本設定
  singleQuote: true,
  trailingComma: "all",
  printWidth: 100,
};

高度な設定とカスタマイゼーション

// .prettierrc.js - 企業レベル設定例
module.exports = {
  // 基本フォーマット設定
  printWidth: 120,
  tabWidth: 2,
  useTabs: false,
  semi: true,
  singleQuote: true,
  quoteProps: "as-needed",
  trailingComma: "all",
  bracketSpacing: true,
  bracketSameLine: false,
  arrowParens: "avoid",
  endOfLine: "lf",
  
  // HTML/JSX設定
  htmlWhitespaceSensitivity: "css",
  singleAttributePerLine: false,
  
  // プラグイン
  plugins: [
    require.resolve("prettier-plugin-organize-imports"),
    require.resolve("prettier-plugin-packagejson"),
    require.resolve("@prettier/plugin-xml"),
  ],
  
  // ファイル種別設定
  overrides: [
    // JavaScript/TypeScript
    {
      files: ["*.js", "*.jsx", "*.ts", "*.tsx"],
      options: {
        printWidth: 100,
        singleQuote: true,
        trailingComma: "all",
      },
    },
    
    // JSON
    {
      files: ["*.json", "*.jsonc"],
      options: {
        printWidth: 120,
        tabWidth: 2,
      },
    },
    
    // Markdown
    {
      files: ["*.md", "*.mdx"],
      options: {
        printWidth: 80,
        proseWrap: "always",
        tabWidth: 2,
      },
    },
    
    // CSS/SCSS
    {
      files: ["*.css", "*.scss", "*.less"],
      options: {
        printWidth: 120,
        singleQuote: false,
      },
    },
    
    // YAML
    {
      files: ["*.yml", "*.yaml"],
      options: {
        tabWidth: 2,
        singleQuote: false,
      },
    },
    
    // パッケージファイル
    {
      files: ["package.json"],
      options: {
        printWidth: 120,
        tabWidth: 2,
      },
    },
    
    // 設定ファイル
    {
      files: [
        ".prettierrc",
        ".prettierrc.json",
        ".eslintrc.json",
        "tsconfig.json",
      ],
      options: {
        printWidth: 120,
        tabWidth: 2,
      },
    },
  ],
};

無視ファイル設定

# .prettierignore
# ビルド出力
dist/
build/
out/
.next/
.nuxt/

# 依存関係
node_modules/
vendor/

# ログファイル
*.log
logs/

# 一時ファイル
.tmp/
.cache/

# 自動生成ファイル
*.min.js
*.min.css
bundle.js
*.generated.*

# ドキュメント
CHANGELOG.md
README.md

# 特定ディレクトリ
legacy/
third-party/

# 特定ファイル形式
*.svg
*.png
*.jpg
*.ico

# パッケージファイル(自動生成される場合)
package-lock.json
yarn.lock
pnpm-lock.yaml

# 環境設定
.env*

ESLintとの連携設定

// eslint.config.js - Prettier + ESLint統合
import prettier from "eslint-plugin-prettier";
import prettierConfig from "eslint-config-prettier";

export default [
  // その他のESLint設定...
  
  // Prettier統合
  {
    plugins: {
      prettier,
    },
    rules: {
      "prettier/prettier": "error",
    },
  },
  
  // Prettierと競合するルールを無効化
  prettierConfig,
  
  // カスタムPrettierルール
  {
    rules: {
      "prettier/prettier": [
        "error",
        {
          singleQuote: true,
          trailingComma: "all",
          printWidth: 100,
        },
      ],
    },
  },
];

プロジェクト別設定例

// React プロジェクト用設定
export default {
  printWidth: 100,
  tabWidth: 2,
  useTabs: false,
  semi: false,
  singleQuote: true,
  quoteProps: "as-needed",
  jsxSingleQuote: true,
  trailingComma: "all",
  bracketSpacing: true,
  bracketSameLine: false,
  arrowParens: "avoid",
  endOfLine: "lf",
  
  plugins: ["prettier-plugin-organize-imports"],
};

// Node.js プロジェクト用設定
export default {
  printWidth: 120,
  tabWidth: 4,
  useTabs: false,
  semi: true,
  singleQuote: true,
  trailingComma: "es5",
  bracketSpacing: true,
  arrowParens: "always",
  endOfLine: "lf",
};

// Vue.js プロジェクト用設定
export default {
  printWidth: 100,
  tabWidth: 2,
  useTabs: false,
  semi: false,
  singleQuote: true,
  trailingComma: "all",
  bracketSpacing: true,
  arrowParens: "avoid",
  endOfLine: "lf",
  
  plugins: ["prettier-plugin-organize-imports"],
  
  overrides: [
    {
      files: "*.vue",
      options: {
        parser: "vue",
      },
    },
  ],
};