--- id: wiki-2026-0508-코드-포매팅-code-formatting title: 코드 포매팅 (Code Formatting) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Code Formatting, Auto-formatting, Prettier, Black, gofmt] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [tooling, style, formatter, prettier, ruff, black] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: polyglot framework: prettier-ruff-gofmt --- # 코드 포매팅 (Code Formatting) ## 매 한 줄 > **"매 style debate 의 종결자"**. Code formatting 은 코드의 visual structure (whitespace, indent, line breaks, quote style) 를 deterministic rule 로 enforce 하는 tooling 영역. 2026 현재 매 모든 mainstream language 는 official 또는 de-facto formatter 를 가지며 (Black, Ruff format, Prettier, gofmt, rustfmt, dart format, ktlint), CI 의 commit hook 의 universal 으로 적용. 매 "어떻게 보일지" 의 human discussion 의 X — 매 tool 의 결정. ## 매 핵심 ### 매 formatter 의 철학 - **Opinionated** (매 ideal): 매 minimal config — Black, gofmt, Prettier. 매 bikeshedding 의 elimination. - **Configurable** (매 legacy): 매 ESLint stylistic rules, autopep8 — 매 team config drift 의 risk. - **Idempotent**: `format(format(x)) == format(x)`. 매 essential property — CI loop safety. - **AST-based**: 매 token stream 의 parse → reformat. 매 regex 의 X. ### 매 linter vs formatter - **Formatter**: whitespace, line breaks, quotes (style only). 매 semantics 의 X-change. - **Linter**: bugs, anti-patterns, unused vars (semantics). 매 ESLint, Ruff check, golangci-lint. - **2026 trend**: Ruff (Python) 의 both 의 unify — `ruff format` + `ruff check` 의 매 single binary. Biome (JS/TS) 의 same path. ### 매 응용 1. **Pre-commit hook**: `pre-commit` (Python), `lefthook`, `husky` 의 매 staged file 의 format. 2. **CI gate**: `ruff format --check` / `prettier --check` — diff 가 있으면 fail. 3. **Editor on-save**: VS Code `editor.formatOnSave: true` + `defaultFormatter`. 4. **Mass migration**: `git ls-files | xargs ruff format` — 매 single PR 의 entire repo reformat. ## 💻 패턴 ### Prettier (JS/TS/JSON/MD/CSS) — 2026 v3 ```json // .prettierrc.json { "semi": false, "singleQuote": true, "trailingComma": "all", "printWidth": 100, "tabWidth": 2, "plugins": ["prettier-plugin-tailwindcss"] } ``` ```bash # format all files in repo npx prettier --write . # CI check npx prettier --check . ``` ### Ruff format (Python) — 2026 default Python formatter ```toml # pyproject.toml [tool.ruff] line-length = 100 target-version = "py312" [tool.ruff.format] quote-style = "double" indent-style = "space" docstring-code-format = true # format code in docstrings ``` ```bash ruff format . # write ruff format --check . # CI ruff check --fix . # lint + autofix ``` ### Black (Python, legacy but stable) ```toml [tool.black] line-length = 100 target-version = ["py312"] skip-string-normalization = false ``` ### gofmt / goimports (Go) — bundled with toolchain ```bash gofmt -w ./... goimports -w ./... # also organizes imports ``` ```go // before package main import("fmt" "os") func main(){fmt.Println(os.Args)} // after gofmt package main import ( "fmt" "os" ) func main() { fmt.Println(os.Args) } ``` ### rustfmt (Rust) ```toml # rustfmt.toml edition = "2024" max_width = 100 imports_granularity = "Crate" group_imports = "StdExternalCrate" ``` ```bash cargo fmt cargo fmt -- --check # CI ``` ### EditorConfig (cross-tool baseline) ```ini # .editorconfig — every editor respects this root = true [*] charset = utf-8 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true indent_style = space [*.{js,ts,tsx,json}] indent_size = 2 [*.py] indent_size = 4 [Makefile] indent_style = tab ``` ### Pre-commit hook (universal) ```yaml # .pre-commit-config.yaml repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.6.0 hooks: - id: ruff-format - id: ruff args: [--fix] - repo: https://github.com/pre-commit/mirrors-prettier rev: v4.0.0 hooks: - id: prettier types_or: [javascript, typescript, json, markdown] ``` ### CI gate (GitHub Actions) ```yaml - name: Check formatting run: | ruff format --check . ruff check . npx prettier --check . ``` ### Mass-format ignore (avoid blame churn) ``` # .git-blame-ignore-revs # Ruff format mass-apply 2026-04-15 abc123def456... ``` ```bash git config blame.ignoreRevsFile .git-blame-ignore-revs ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Python 신규 프로젝트 | Ruff format (Black-compatible, 100x faster) | | Python legacy | Black 유지 — Ruff 의 drop-in 의 가능 | | JS/TS | Prettier 또는 Biome (faster, Rust-based) | | Go | gofmt (no choice, no config) | | Rust | rustfmt | | 매 polyglot monorepo | dprint 또는 Trunk | | Team debate 중 | Opinionated formatter 의 즉시 채택 — 매 discussion close | **기본값**: Ruff (Python), Prettier 또는 Biome (web), gofmt (Go), rustfmt (Rust). 매 pre-commit + CI check. ## 🔗 Graph - 부모: [[Code Quality]] · [[Developer Experience]] - 변형: [[Linter]] · [[Static Analysis]] - 응용: [[153_pre-commit과_품질_게이트|Pre-commit Hooks]] - Adjacent: [[Prettier]] ## 🤖 LLM 활용 **언제**: Generated code 의 file write 후 항상 `ruff format` / `prettier --write` 의 run — LLM output 의 indent inconsistency 의 normalize. PR diff 의 minimize. **언제 X**: Format-only PR 의 logic change 와 mix 의 X — separate commit / PR 로 분리. Reviewer 의 noise 의 reduction. ## ❌ 안티패턴 - **Custom rules everywhere**: 매 team-specific style 의 invention. 매 onboarding cost 의 increase. 매 Black/Prettier default 의 accept. - **Format on commit only**: Editor save 의 X-format 의 경우 매 every commit 의 noise. Editor integration 의 essential. - **Format + logic 의 mixed PR**: Review impossible. 매 separate PR. - **No CI check**: Pre-commit 의 bypass 의 가능 (`-n`). 매 CI 의 source of truth. - **`tabWidth` debate**: 매 EditorConfig 의 fix — once and forget. ## 🧪 검증 / 중복 - Verified (Prettier docs 2026, Ruff docs 0.6+, Go style guide). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — formatters (Ruff, Prettier, gofmt, rustfmt) + CI/pre-commit patterns |