[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -2,60 +2,232 @@
|
||||
id: wiki-2026-0508-eslint-static-analysis
|
||||
title: ESLint Static Analysis
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AI-ESLint-STATIC]
|
||||
aliases: [ESLint, JS linter, static analysis, custom rule, AST, biome, oxlint]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 1.0
|
||||
tags: [SoftwareEngineering, StaticAnalysis, ESLint, CodingStandard]
|
||||
verification_status: applied
|
||||
tags: [software-engineering, static-analysis, eslint, javascript, typescript, ast, lint]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-04-20
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
|
||||
tech_stack:
|
||||
language: JavaScript / TypeScript
|
||||
framework: ESLint 9 / Biome / oxlint
|
||||
---
|
||||
|
||||
# [[ESLint-Static-Analysis|ESLint-Static-Analysis]] (ESLint 정적 분석)
|
||||
# ESLint Static Analysis
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
> "코드를 실행해보지 않고도 미래의 버그를 예언하는 엄격한 사서." 소스 코드를 읽어 문법 에러, 코딩 컨벤션 위반, 잠재적 위험 패턴을 자동으로 찾아내어, 개발자가 실수하기 전에 미리 경고를 날려주는 현대 웹 개발의 수문장이다.
|
||||
## 매 한 줄
|
||||
> **"매 JS / TS 의 AST-based static analysis"**. 매 syntax + style + bug pattern 의 catch. 매 modern (2024+): 매 flat config + 매 typescript-eslint + 매 fast alternative (Biome, oxlint). 매 custom rule = 매 enforcement.
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
- **AST (Abstract Syntax Tree)**: 코드를 나무 구조로 분석하여 특정 패턴(예: `eval()` 사용)이 나타나는지 물리적으로 감지함.
|
||||
- **Rules & Plugins**:
|
||||
- **Recommended Rules**: 보편적으로 권장되는 안전한 코딩 수칙.
|
||||
- **[[Prettier|Prettier]] Integration**: 코드의 '의미'는 ESLint가, '모양([[Formatting|Formatting]])'은 Prettier가 담당하도록 협업.
|
||||
- **Automation**: Git Commit 시점에 검사하거나([[Husky|Husky]]), IDE에서 실시간으로 밑줄을 그어 교정을 강제함.
|
||||
## 매 핵심
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
- 설정이 너무 까다로우면(Strict) 개발자의 창의성과 생산성을 저해하여 "eslint-disable" 주석이 남용되는 역효과(Security Theater)를 낳는다. 팀의 수준과 프로젝트의 성격에 맞는 '품질의 적정선'을 설정하는 거버넌스가 중요하다. 최근에는 AI가 복잡한 린트 에러를 자동으로 고쳐주는 기능이 도입되고 있다.
|
||||
### 매 mechanism
|
||||
- 매 source → AST (espree / @typescript-eslint/parser).
|
||||
- 매 visitor pattern 의 rule traverse.
|
||||
- 매 violation 의 fix suggestion (autofix).
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
- Related: [[SAST (Static Application Security Testing)|SAST (Static Application Security [[Testing]])]] , [[Dry-Principle|Dry-Principle]]
|
||||
- Tools: [[Prettier|Prettier]] , Husky-Git-Hooks
|
||||
### 매 modern (2024+)
|
||||
- **Flat config** (eslint.config.js): 매 .eslintrc legacy out.
|
||||
- **typescript-eslint v8**: 매 type-aware lint.
|
||||
- **Biome**: 매 Rust-based 25x faster.
|
||||
- **oxlint**: 매 even faster (50-100x).
|
||||
- **Stylistic plugin**: 매 ESLint core 의 style rule 의 spin off.
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
### 매 응용
|
||||
1. **Coding standard**: 매 team consistency.
|
||||
2. **Bug prevention**: 매 no-undef, no-shadow.
|
||||
3. **Performance**: 매 react-hooks rules.
|
||||
4. **Security**: 매 eslint-plugin-security.
|
||||
5. **Custom**: 매 team-specific anti-pattern.
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(TODO)*
|
||||
### 매 LLM era
|
||||
- **AI-assisted rule**: 매 LLM 의 rule generate.
|
||||
- **Hybrid**: 매 ESLint + Corgea / Snyk.
|
||||
- **Auto-fix**: 매 LLM 의 complex pattern.
|
||||
|
||||
**언제 쓰면 안 되는가:**
|
||||
- *(TODO)*
|
||||
## 💻 패턴
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
### Flat config
|
||||
```javascript
|
||||
// eslint.config.js
|
||||
import js from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
import stylistic from '@stylistic/eslint-plugin';
|
||||
|
||||
- **정보 상태:** needs_review
|
||||
- **출처 신뢰도:** A
|
||||
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
|
||||
export default tseslint.config(
|
||||
js.configs.recommended,
|
||||
...tseslint.configs.recommendedTypeChecked,
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: { project: './tsconfig.json' },
|
||||
},
|
||||
plugins: { '@stylistic': stylistic },
|
||||
rules: {
|
||||
'@stylistic/semi': ['error', 'always'],
|
||||
'@typescript-eslint/no-floating-promises': 'error',
|
||||
'no-console': ['warn', { allow: ['warn', 'error'] }],
|
||||
},
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
## 🧬 중복 검사 (Duplicate Check)
|
||||
### Custom rule (no console.log)
|
||||
```javascript
|
||||
// .eslint-rules/no-console-log.js
|
||||
export default {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: { description: 'Disallow console.log (use logger)' },
|
||||
fixable: 'code',
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
'CallExpression[callee.object.name="console"][callee.property.name="log"]'(node) {
|
||||
context.report({
|
||||
node,
|
||||
message: 'Use logger.info instead of console.log',
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(node.callee, 'logger.info');
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
|
||||
- **처리 방식:** UPDATE (자동 정규화)
|
||||
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
|
||||
### Custom — forbid hardcoded URL
|
||||
```javascript
|
||||
export default {
|
||||
meta: { type: 'problem' },
|
||||
create(context) {
|
||||
return {
|
||||
Literal(node) {
|
||||
if (typeof node.value === 'string' && /^https:\/\/internal\./.test(node.value)) {
|
||||
context.report({ node, message: 'Use env var for internal URL' });
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## 🕓 변경 이력 (Changelog)
|
||||
### Type-aware rule (no-floating-promise)
|
||||
```typescript
|
||||
// 매 typescript-eslint 의 type info 의 use
|
||||
import { ESLintUtils } from '@typescript-eslint/utils';
|
||||
|
||||
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|
||||
|------|-----------|-----------|--------|
|
||||
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
|
||||
export const noUnsafePromise = ESLintUtils.RuleCreator(name => name)({
|
||||
name: 'no-unsafe-promise',
|
||||
meta: { type: 'problem', docs: { description: '...' }, schema: [], messages: { msg: '...' } },
|
||||
defaultOptions: [],
|
||||
create(context) {
|
||||
const services = ESLintUtils.getParserServices(context);
|
||||
const checker = services.program.getTypeChecker();
|
||||
return {
|
||||
AwaitExpression(node) {
|
||||
const type = checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(node.argument));
|
||||
// 매 type-based logic
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### CI integration (GitHub Actions)
|
||||
```yaml
|
||||
- run: npx eslint . --max-warnings 0 --format json -o eslint.json
|
||||
- uses: ataylorme/eslint-annotate-action@v3
|
||||
with: { report-json: eslint.json }
|
||||
```
|
||||
|
||||
### Pre-commit (lint-staged)
|
||||
```json
|
||||
{
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx}": ["eslint --fix", "prettier --write"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Migrate to Biome (faster)
|
||||
```json
|
||||
// biome.json
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": { "recommended": true, "complexity": { "noForEach": "error" } }
|
||||
},
|
||||
"formatter": { "enabled": true, "indentWidth": 2 }
|
||||
}
|
||||
// 매 npx @biomejs/biome lint .
|
||||
```
|
||||
|
||||
### oxlint (Rust, fastest)
|
||||
```bash
|
||||
npx oxlint@latest . --deny correctness --deny perf
|
||||
# 매 50-100x faster than ESLint
|
||||
```
|
||||
|
||||
### Disable inline (justified)
|
||||
```typescript
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- 매 third-party type 의 incomplete
|
||||
const data = response as any;
|
||||
```
|
||||
|
||||
### LLM-generated rule
|
||||
```python
|
||||
def llm_generate_rule(description):
|
||||
prompt = f"""Generate an ESLint custom rule.
|
||||
|
||||
Description: {description}
|
||||
|
||||
Output JS module with meta + create."""
|
||||
return llm.generate(prompt)
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Tool |
|
||||
|---|---|
|
||||
| Standard JS/TS | ESLint flat config |
|
||||
| Speed-critical CI | Biome / oxlint |
|
||||
| Type-aware | typescript-eslint |
|
||||
| Custom team rule | ESLint custom rule |
|
||||
| Format only | Prettier / Biome |
|
||||
| Security | + eslint-plugin-security / Snyk Code |
|
||||
|
||||
**기본값**: 매 ESLint flat + 매 typescript-eslint + 매 Biome (format) + 매 lint-staged + 매 CI annotate.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Static-Analysis]] · [[Code-Quality]]
|
||||
- 변형: [[Custom-ESLint-Rules-Development]] · [[Biome]] · [[oxlint]]
|
||||
- 응용: [[Pre-commit-Hooks]] · [[CI-CD]]
|
||||
- Adjacent: [[Prettier]] · [[TypeScript]] · [[Corgea]] · [[Snyk]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 codebase standard. 매 team scale. 매 anti-pattern enforce.
|
||||
**언제 X**: 매 prototype throwaway.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Disable everything**: 매 lint 의 useless.
|
||||
- **Old .eslintrc legacy** (post-2024): 매 flat config 의 migrate.
|
||||
- **No type-aware in TS**: 매 false confidence.
|
||||
- **Lint at PR only**: 매 friction → 매 pre-commit.
|
||||
- **No autofix**: 매 manual fatigue.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (ESLint v9 docs, typescript-eslint, Biome).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-04-20 | Auto-reinforced |
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — flat config + custom rule + Biome / oxlint + CI / pre-commit code |
|
||||
|
||||
Reference in New Issue
Block a user