feat: establish TypeScript-aware frontend tooling
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
# VD-01: TypeScript 7과 ESLint 10의 점진적 전환 도구
|
||||
|
||||
- 상태: Accepted
|
||||
- 결정일: 2026-07-26
|
||||
- 적용 브랜치: `feature-frontend-typescript-tooling-foundation`
|
||||
|
||||
## 배경
|
||||
|
||||
저장소는 TypeScript `7.0.2`와 ESLint `10.8.0`을 고정하고 있다. 첫 전환
|
||||
브랜치는 compiler를 변경하거나 production source를 일괄 변환하지 않고
|
||||
JS/JSX/TS/TSX가 같은 품질 게이트를 통과하게 해야 한다.
|
||||
|
||||
결정 시점의 package peer contract는 다음과 같다.
|
||||
|
||||
- `typescript-eslint@8.65.0`과 canary는 TypeScript `<6.1.0`을 요구한다.
|
||||
- `eslint-plugin-jsx-a11y@6.10.2`는 ESLint `<=9`를 요구한다.
|
||||
- `eslint-plugin-react-hooks@7.1.1`은 ESLint 10을 지원한다.
|
||||
- Babel 8 ESLint parser는 ESLint 10을 지원하고 Node `>=24.11.0`을 요구한다.
|
||||
|
||||
호환되지 않는 peer dependency를 강제 설치하면 lockfile 검증은 통과하더라도
|
||||
지원되지 않는 parser와 rule 조합을 플랫폼 계약으로 만들게 된다.
|
||||
|
||||
## 결정
|
||||
|
||||
1. TypeScript `7.0.2`와 ESLint `10.8.0`을 유지한다.
|
||||
2. TypeScript/TSX의 ESLint syntax parsing에는
|
||||
`@babel/eslint-parser`와 TypeScript/JSX syntax plugin을 사용한다.
|
||||
3. TypeScript의 이름 해석, unused 진단과 type semantics는 `tsc`가 소유한다.
|
||||
Babel parser가 TypeScript scope manager를 제공하지 않으므로 TS 파일의
|
||||
core `no-undef`와 `no-unused-vars`는 끄고 분리된 app/node/test TypeScript
|
||||
project를 필수 게이트로 실행한다.
|
||||
4. React Hook 규칙은 호환되는 `eslint-plugin-react-hooks`로 즉시 적용한다.
|
||||
5. JSX 접근성은 현재의 semantic component contract, Testing Library,
|
||||
axe 기반 cross-browser gate와 수동 검토 계약이 계속 담당한다. 호환되지 않는
|
||||
`eslint-plugin-jsx-a11y`는 설치하지 않는다.
|
||||
6. Babel 8의 지원 범위에 맞춰 Node engine 하한을 `24.11.0`으로 명시한다.
|
||||
7. production source의 대량 rename은 이 결정에 포함하지 않는다.
|
||||
|
||||
## 검증
|
||||
|
||||
- `check:types`는 app, Node scripts/config, tests project를 모두 검사한다.
|
||||
- JS invalid-call, TS invalid port, TS discriminated-union fixture는 실패해야 한다.
|
||||
- ESLint와 dependency-cruiser는 TS/TSX architecture fixture를 검사한다.
|
||||
- registry scanner는 TS registry의 required field, uniqueness와 reference를
|
||||
검증한다.
|
||||
- browser security gate는 TSX의 금지된 raw HTML fixture를 거절한다.
|
||||
|
||||
## 후속 검토와 제거
|
||||
|
||||
`typescript-eslint`가 TypeScript 7을, JSX 접근성 plugin이 ESLint 10을 공식
|
||||
지원하면 별도 dependency 브랜치에서 peer metadata와 전체 negative fixture를
|
||||
재검증한다. 교체할 때는 Babel parser package와 TS 전용 ESLint override를
|
||||
함께 제거한다. compiler downgrade나 `--force` 설치는 이 ADR의 rollback
|
||||
방법이 아니다.
|
||||
@@ -36,7 +36,8 @@ TypeScript 전환 목적은 확장자 변경이 아니라 이 계약을 컴파
|
||||
다음 변경이 첫 브랜치에서 완료되기 전에는 source rename을 시작하지 않는다.
|
||||
|
||||
1. ESLint가 `js`, `jsx`, `mjs`, `ts`, `tsx`, `mts`를 모두 검사한다.
|
||||
2. `typescript-eslint`, React Hooks, JSX accessibility 규칙을 추가한다.
|
||||
2. React Hooks 규칙을 추가하고 TypeScript/ESLint parser와 JSX accessibility
|
||||
도구는 설치된 compiler/linter의 공식 peer 범위 안에서 선택한다.
|
||||
3. dependency-cruiser의 extension과 resolver가 TS/TSX를 포함한다.
|
||||
4. `scripts/check-registries.mjs`가 TS/TSX를 검색한다.
|
||||
5. `config/contracts/registry-governance.json`의 경로 갱신 절차를 만든다.
|
||||
@@ -77,6 +78,13 @@ tsconfig.json # project references only
|
||||
확정한다. 옵션을 한꺼번에 켜서 수백 개 예외를 만들지 말고, 각 단계에서 새
|
||||
예외를 금지한다.
|
||||
|
||||
현재 저장소의 VD-01 결정은
|
||||
[TypeScript 7과 ESLint 10의 점진적 전환 도구](./decisions/VD-01-typescript-lint-tooling.md)에
|
||||
기록돼 있다. app, Node scripts/config, tests는 각각 독립된 project로
|
||||
typecheck하며 JS에는 `checkJs`, TS에는 `strict`를 적용한다. TypeScript 7을
|
||||
아직 지원하지 않는 parser plugin을 강제 설치하지 않고 Babel parser는 lint
|
||||
syntax/import/security 검사, `tsc`는 type semantics를 소유한다.
|
||||
|
||||
### 2.3 전환 순서
|
||||
|
||||
| 단계 | 대상 | 이유 | 종료 조건 |
|
||||
|
||||
@@ -69,12 +69,12 @@ field/documentation 단계를 구성한다.
|
||||
|
||||
### 2.3 확인된 공백
|
||||
|
||||
#### 테스트 TypeScript가 typecheck 대상이 아니다
|
||||
#### 테스트 TypeScript typecheck 기반
|
||||
|
||||
현재 `check:types`는 `tsconfig.json`의 include 범위에 의존하며 tests 전체의
|
||||
callback, mock, fixture, custom matcher type을 별도 프로젝트로 검사하지 않는다.
|
||||
TypeScript 전환 뒤 Vitest가 test file을 변환해 실행할 수 있다는 사실은
|
||||
`tsc` typecheck를 대체하지 않는다.
|
||||
`check:types`는 app, Node scripts/config, tests project를 순서대로 검사한다.
|
||||
테스트 project는 JS/JSX/TS/TSX의 callback, mock, fixture와 config type을
|
||||
검사하되 실패를 의도한 `tests/fixtures`는 별도 negative command가 소유한다.
|
||||
Vitest의 변환 성공을 TypeScript typecheck의 대체물로 취급하지 않는다.
|
||||
|
||||
#### 실제 bootstrap integration test가 없다
|
||||
|
||||
|
||||
Reference in New Issue
Block a user