docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
---
|
||||
id: wiki-2026-0508-eslint-static-analysis
|
||||
title: ESLint Static Analysis
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [ESLint, JS linter, static analysis, custom rule, AST, biome, oxlint]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 1.0
|
||||
verification_status: applied
|
||||
tags: [software-engineering, static-analysis, eslint, javascript, typescript, ast, lint]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: JavaScript / TypeScript
|
||||
framework: ESLint 9 / Biome / oxlint
|
||||
---
|
||||
|
||||
# ESLint Static Analysis
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 JS / TS 의 AST-based static analysis"**. 매 syntax + style + bug pattern 의 catch. 매 modern (2024+): 매 flat config + 매 typescript-eslint + 매 fast alternative (Biome, oxlint). 매 custom rule = 매 enforcement.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 mechanism
|
||||
- 매 source → AST (espree / @typescript-eslint/parser).
|
||||
- 매 visitor pattern 의 rule traverse.
|
||||
- 매 violation 의 fix suggestion (autofix).
|
||||
|
||||
### 매 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.
|
||||
|
||||
### 매 응용
|
||||
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.
|
||||
|
||||
### 매 LLM era
|
||||
- **AI-assisted rule**: 매 LLM 의 rule generate.
|
||||
- **Hybrid**: 매 ESLint + Corgea / Snyk.
|
||||
- **Auto-fix**: 매 LLM 의 complex pattern.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Flat config
|
||||
```javascript
|
||||
// eslint.config.js
|
||||
import js from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
import stylistic from '@stylistic/eslint-plugin';
|
||||
|
||||
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'] }],
|
||||
},
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
### 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');
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### 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' });
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Type-aware rule (no-floating-promise)
|
||||
```typescript
|
||||
// 매 typescript-eslint 의 type info 의 use
|
||||
import { ESLintUtils } from '@typescript-eslint/utils';
|
||||
|
||||
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]]
|
||||
- 응용: [[CI CD]]
|
||||
- Adjacent: [[Prettier]] · [[TypeScript]] · [[Corgea]]
|
||||
|
||||
## 🤖 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