3-18. minify 격차 추격과 Module Federation — 0.1.0은 아직 preview
기간: 2026년 5월 13일 ~ 5월 19일 (7일, 5/19는 오전까지) PR: zntc 약 217개 (5/13 12 · 5/14 26 · 5/15 50 · 5/16 44 · 5/17 49 · 5/18 36) — 두 AI 병행 머지 핵심: RN 런타임 회귀 커밋단위 리뷰(#3156), TS 파서 D 시리즈 + TSC conformance audit, "minify가 esbuild/rolldown/rspack보다 크다"는 단 하나의 격차를 mangler Phase A 1-char pool 잠식까지 루트커즈 추격 (M/N/K 시리즈 — rxjs 누적 −12%대·esbuild −751B), Codex 트랙의 코드 스플리팅 P3 → Module Federation(웹 P1~P4 + mf-manifest/remoteEntry/shareScope 런타임, RN 자체 C/JSI 로더 설계), Ed25519/SHA-256 청크 무결성 sidecar, CLI 옵션 갭 보강(
--version/--no-config/--color), Zig 인라인 test 분리(#3497~3499) 진행 중 / 배포 안 함 — 이 구간에 새 npm publish는 없었다. 5/12의 "0.1.0 publish 직전"이 그대로 public preview 취급으로 유지됐고, 무게중심은 배포가 아니라 (a) minify 크기 격차 좁히기 (b) Module Federation 구현으로 옮겨갔다.
이 편의 위치
3-17은 5/8~5/12 — 플러그인 통일, 대규모 파일 분리, 배포 파이프라인 세팅, 그리고 "세팅만 다 해주세요 실 배포는 하지말고" — 으로 끝났다. 이 편은 그 뒤 7일이다. "배포 직전"에서 한 발 더 갈 줄 알았는데, 실제로 일어난 건 두 가지를 끝까지 파고드는 것이었다: 미니파이 결과물이 경쟁 번들러보다 크다는 단 하나의 사실, 그리고 Module Federation이라는 새 에픽.
이 7일의 성격은 3-17과 또 다르다. 3-17이 "배포 가능한 모양 만들기"였다면, 이 편은 **"배포해도 부끄럽지 않은 품질 만들기"**다. 그리고 두 AI의 역할 분담이 가장 선명해진 구간이기도 하다 — Claude는 파서·minify 루트커즈, Codex는 Module Federation·청크 에픽.
5/13 — RN 런타임 회귀, 커밋 하나하나
5/12까지 0.1.0 prep을 끝냈는데, RN 런타임 회귀(#3156 계열)가 남아 있었다. 다운레벨링·Metro 네이티브 라이브러리 로딩 순서까지 건드린 큰 PR이었다.
"커밋 하나하나마다 반복 검증" — PR 단위가 아니라 커밋 단위 리뷰. 그 과정에서 단일 책임 위반이 잡힌다:
한 커밋에 메모리 누수 fix와 프로퍼티명 fix가 섞여 있던 것을 별도 커밋으로 분리. 결과적으로 #3144~3157이 머지됐다 — metadata/resolve/graph_io audit, disableHierarchicalLookup Metro 호환, tslib UMD comptime drift guard.
5/14 — TS 파서 D 시리즈, 그리고 "15초"
이날은 TS 파서 정합성(.d.ts ambient, implicit strict module, await-as-identifier 등 D 시리즈)과 TSC conformance audit 인프라(#3175~3201)가 대량으로 들어갔다. 시작은 늘 그렇듯 "이게 해결된 거야 아니야"부터:
그리고 이날의 진짜 주제는 체감 속도였다. 디스크 캐시 최적화가 콜드 스타트엔 무력하다는 의심을 본인이 먼저 제기한다:
측정이 추상적 벤치가 아니라 **사용자 실경로(45MB RN 번들, napi 릴리즈 빌드, 15초)**와 일치해야 한다는 강제. 이건 3-17까지 반복된 "measure-first"의 5월 버전이다.
파서 엣지(blob-util parse error 등)에서 막히면 표준 해법은 정해져 있다:
레퍼런스 정독 — babel flow parser, rolldown, swc. 그리고 두 수정안 중 장기적으로 나은 쪽을 다시 확인하고("B가 자익적으론 낫다는거죠?"), 테스트 동반을 작업 전제로 못박는다("반드시 테스트 케이스로 확인하면서 진행해야해요").
5/15 — minify 격차, 이 편의 중심축
이 편 전체를 관통하는 단 하나의 질문이 이날 오전 시작된다.
수정보다 진단이 먼저, 그리고 진단도구 자체의 신뢰도부터:
mangle 2-char 잔존율이 라이브러리마다 다르다는 게 루트커즈의 첫 단서였다. 그리고 이 편의 반복 모토가 나온다:
파서/번들러가 어려운 케이스를 "보수적으로 거부"하는 것을 거부한다 — 3-13에서 CLAUDE.md에 박은 "근본 수정 원칙"의 5월 재확인. 비교 베이스라인도 esbuild 단독에서 넓힌다:
루트커즈로 확정된 것: mangler Phase A가 cross-module top-level 심볼을 전역 단일 1-char(54개) pool로 소진 → Phase B의 nested 바인딩이 짧은 이름을 못 받는다. 이 추격으로 M/N/K 시리즈 PR(#3223~3273)이 대량 머지됐다 — rxjs 누적 −12%대, esbuild 산출물 −751B.
한편 Codex 트랙에서는 출시 후 계획이 논의된다 — 하지만 이게 "배포했다"가 아니다:
AI 답변은 **"0.1.0 public preview 시점"**을 전제로 출시 후 P0(SECURITY.md / 이슈 템플릿 / Discussions / release-canary)만 논의했다. 실제 npm publish나 버전 bump는 이 구간 어디에도 없다.
5/16 — 추격의 장기화, 그리고 Module Federation의 시작
minify 격차 추격이 길어지면서 자동 루프(매 PR /simplify → 오토머지 → 루트커즈)로 굴러간다. three.js가 rspack 대비 1.55배 같은 비교표가 등장한다:
임시 fix가 아니라 근본 재설계 채택. 그리고 같은 날, Codex 트랙에서 이 편의 두 번째 축이 열린다:
Module Federation을 웹뿐 아니라 RN까지. RN은 단일 번들 제약이 있으니 자체 C/JSI 로더 + TurboModule 한정으로 간다는 설계 결정. 이날 Codex 쪽은 P3-B 청크 인프라 PR(#33243371)을 대량 머지했다 — 이건 2026-05-16 today-commit의 #33423371 P3 시리즈와 정확히 겹친다.
Claude 트랙은 emit 아키텍처 전면 개편 가능성까지 타진한다:
5/17 — 천장, 그리고 격리된 스파이크
minify 격차에는 천장이 있었다 — rspack이 three.js에서 압도적으로 작은 건 GLSL strip 같은 도메인 특화 최적화 때문이다.
추상 분석이 아니라 실제 산출물 diff로 근본을 찾으라는 압박. 그리고 위험한 emit 오버홀은 메인에 바로 넣지 않는다:
chunk 재파싱이 증분/병렬 빌드와 상충하므로, emit 스파이크는 별도 브랜치로 격리. bundle-context export const coalescing RFC(#3411)가 이 흐름에서 머지됐다.
Codex 쪽은 Module Federation 스파이크 S0S5 + webpack/rspack 호환 3450). 표준 구현체를 직접 클론해 테스트 갭을 봉인:mf-manifest.json·remoteEntry·shareScope 런타임을 P1 전 단계까지 머지한다(#3375
5/18 — MF 웹 완성, CLI 갭, Zig 테스트 분리
Module Federation 웹 구현이 완성도로 들어간다 — strictVersion fail-fast, named shareScope 다중, expose CSS, 무결성 sidecar(Ed25519/SHA-256), 사용자 가이드·예제앱·레시피(#3464~3500). 무결성 sidecar는 사용자가 직접 제기한 요구에서 나왔다:
RN MF 사용자 API 형태(@zntc/react-native/module-federation/register)를 사용자가 직접 제안하고, CodePush 공존성·repack 한계까지 추궁한다. CLI 옵션 표면은 4개 경쟁 번들러와 갭 분석:
→ --version/-v/--no-config/--color 추가(#3489/#3490). react-query v5 ES5 다운레벨 회귀(class async optional-chaining temp hoist)도 이날 우선 수정. 그리고 코드베이스 청결:
Zig 인라인 test를 *_test.zig로 분리(#3497/#3498), 그리고 "테스트 위해 pub 노출"이라는 안티패턴을 금지로 박제(#3499).
5/19 (오전까지) — TDD 마무리, 문서 전수조사
Zig 테스트 분리 후속 + es5 다운레벨 정합성(#3509대)을 babel 동작 기준으로 TDD 마무리, 핵심만 선처리하고 나머지는 백로그화. Codex 쪽은 MF 레시피 문서·예제를 GitHub Pages에 배포(=문서 배포, npm 아님)하고, 문서 vs 실제 기능 전수 대조를 했다:
결과 — 문서는 정확했고, 에이전트가 보고한 불일치 4건은 전부 거짓양성(Zig 바이너리로 잘못 테스트한 것 — 사용자 실경로는 npm Node.js CLI)이었다.
7일간 관통한 것들
"배포 직전"에서 한 발도 안 나갔다 — 의도적으로
3-17의 마지막에 더했던 다섯 문장에, 이 7일이 다섯을 더한다:
- "배포 직전"은 생각보다 오래 머무는 상태다 — 5/12에 "publish 직전"이었는데 5/19에도 publish는 안 됐다. 그 사이 217개 PR이 머지됐는데도. 배포를 늦추는 게 게으름이 아니라 "minify가 경쟁사보다 큰 채로 내보낼 순 없다"는 품질 기준이었다.
- 단 하나의 격차가 일주일을 먹는다 — "minify가 rolldown보다 크다"는 한 문장이 5/15~18 수십 개 PR을 만들었다. 그리고 그 루트커즈는 의외로 깊은 곳(mangler Phase A의 전역 1-char pool 설계)에 있었다.
- 두 AI를 쓰면 에픽을 병렬로 굴릴 수 있다 — Claude가 minify를 일주일 파는 동안 Codex가 Module Federation 풀스택을 동시에 진행했다. 한 트랙이 한 우물을 깊게 파도 다른 트랙이 새 기능을 넓힌다.
- "근본 수정"은 한 번 박으면 계속 인용된다 — 3-13에서 CLAUDE.md에 넣은 그 원칙이 5/15 "보수적 거부 말고 루트커즈"로 그대로 돌아왔다. 규칙은 한 번 세우면 본인이 본인에게 강제한다.
- 천장이 있는 격차도 있다 — three.js에서 rspack이 작은 건 GLSL strip 같은 도메인 최적화 때문이고, 그건 따라간다고 따라잡히는 종류가 아니다. 모든 격차가 루트커즈로 0이 되는 건 아니라는 것도 측정이 알려준다.
3-17 끝에 "다음 편은 npm publish가 눌리고 나면"이라고 썼는데, 7일이 더 지나도 그 버튼은 안 눌렸다. 대신 그 7일은 "눌러도 되는 상태"를 만드는 데 쓰였다 — minify를 경쟁권으로, Module Federation을 추가 무기로. publish는 여전히 다음 편의 몫이다.