Skip to content

fix(extractor): compile imported styled retargets without redundant imports - #806

Merged
owjs3901 merged 3 commits into
mainfrom
fix/imported-retarget-relevance
Nov 2, 2026
Merged

owjs3901 merged 3 commits into
mainfrom
fix/imported-retarget-relevance

Conversation

@owjs3901

@owjs3901 owjs3901 commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Refs #689 (styled/compat). main 기준의 독립 PR이며, 다른 PR의 선행 병합이 필요하지 않습니다.

요약

다른 프로젝트 모듈에서 가져온 styled 컴포넌트에 .withComponent(...)만 호출하는 파일이, 직접적인 스타일링 패키지 import가 없다는 이유로 추출에서 제외되는 문제를 수정합니다.

통합한 MAIN SETTLED: 7de627104afa3cc36f5b328f0937d8b901d07887 (#893 포함). 기존 imported-styled 사용 탐색과 정의 해석을 재사용하며, 새 런타임 helper/method shim이나 별도 callback 복제 경로는 추가하지 않습니다. 기존 컴포넌트 생성 방식은 변경하지 않습니다. settled main 대비 이 PR 자체의 의존성, 설정, 임계값, 예산, lockfile 변경은 없습니다.

// Base.tsx
import styled from '@emotion/styled'
export const Dyn = styled.button`font-size: ${(p) => (p.big ? '20px' : '10px')};`

// Retargeted.tsx — 불필요한 styled import 없이 동작
import { Dyn } from '@/Base'
export const Retargeted = Dyn.withComponent('a')

동작

  • 텍스트는 withComponent와 import가 모두 있는지 확인하는 저비용 사전 필터에만 사용합니다. 실제 허용 여부는 root binding의 semantic symbol과 기존 module resolver가 읽은 styled 정의로 결정합니다.
  • named import, reexport, namespace member와 정적 literal-bracket member를 같은 경로로 판정합니다. shadowing, type-only, 동적인 namespace lookup, 일반 객체, 해석 불가/읽을 수 없는 정의는 기존 경계를 유지합니다.
  • 추출기의 이른 반환과 마지막 unchanged guard를 모두 수정하고, imported styled 정의가 있을 때 visitor의 semantic scoping도 활성화합니다. 먼저 읽은 정의는 실제 추출에서 재사용합니다.
  • has_devup_ui_with와 공개 WASM hasDevupUI도 같은 판정을 사용합니다. Bun의 사전 필터가 이 입력을 통과시키며 Vite, Next webpack/Turbopack, webpack, Rsbuild의 기존 공통 extraction 진입점에도 적용됩니다. TypeScript 플러그인별 별도 heuristic은 추가하지 않았습니다.
  • public API 테스트는 실제 tsconfig @/* -> src/*, Next withModuleResolver, 원래 Base/Dyn fixture를 사용합니다. 완전한 emitted module을 평가하고 실제 React forwardRef renderer의 출력과 emitted CSS를 확인합니다.
실제 관찰 수정 전 수정 후 (두 CSS 모드)
패키지 import 없는 consumer 평가 TypeError: Dyn.withComponent is not a function 정상 평가
target / ref / children 평가 실패로 관찰 불가 a / 같은 ref 객체 / child
big=false / big=true의 font-size 평가 실패로 관찰 불가 emitted CSS와 CSS 변수에서 10px / 20px
사용하지 않는 styled import만 추가한 control 정상 동작 정상 동작

새로 생기는 오류

새 오류 종류는 없습니다. 새로 인식되는 known-styled 호출의 인수가 기존 지원 조건을 벗어나면 기존 withComponent 빌드 오류 규칙을 그대로 따릅니다. 일반 객체의 동명 메서드를 styled 호출로 판단하지 않습니다.

남는 한계

  • resolver가 없거나 정의를 정적으로 읽을 수 없는 import와 동적인 namespace lookup은 기존 경계를 유지합니다. 이 PR은 알려진 styled 정의의 relevance 누락만 수정합니다.
  • 기능 회귀 자체는 브라우저 computed-style 측정으로 표현하지 않습니다. 이번 main 통합에서는 별도로 landing-dev 브라우저 검증을 vinext와 Next에서 각각 13/13 통과했습니다. 새 회귀 테스트는 실제 emitted ESM 평가, React renderer 출력, emitted CSS/변수의 값을 검증하며 브라우저 computed-style 측정으로 표현하지 않습니다.
  • Rust LSP 요청은 daemon timeout, TypeScript LSP는 기존 설치 거절 상태로 사용할 수 없었습니다. compiler/clippy, workspace tests, 빌드, coverage와 CI로 검증합니다.
  • 아래 microbenchmark는 같은 머신에서 저장한 수정 전/후 WASM을 번갈아 실행한 수치이며 전체 앱 빌드 성능을 의미하지 않습니다. 무트리거 파일은 추가 parse/resolver 호출이 없습니다. 작은 시간 차이는 숨기지 않고 함께 기록합니다.

검증

최신 main 통합 (2026-11-02)

  • #893이 포함된 공지 MAIN SETTLED 7de627104afa3cc36f5b328f0937d8b901d07887 를 충돌 없이 true merge했습니다. 최종 head는 25b44b5458454e62b5562788d290e68b5601f61e, 실제 parent는 9c684a01a9910877a7d1bbd48f0aab2950e112d2 + 7de627104afa3cc36f5b328f0937d8b901d07887, tested/staged/committed tree는 모두 0927aa5213999d5a858e63cb2774077340aeb77a 입니다. 이전 head 대비 main 소유 JS·테스트·설정 13경로만 통합했으며 Rust/의존성 입력은 이전 검증 head와 같습니다.
  • frozen install, fresh WASM-first root build, verify:dist, fmt/clippy -D warnings 및 TS6-preload ESLint가 통과했습니다. root와 Vite의 실제 coverage 표는 모두 functions/lines 100.00/100.00이며, landing-dev는 vinext 13/13, Next 13/13입니다. CI/RUST_MIN_STACK/INSTA_*는 제거하고 기본 Rust stack, Bun 1.4.4, Node 26.12.0, jobs2를 사용했습니다.
  • ONE 정상 hook, ONE push로 완료했습니다. hook은 약 864초, peak Job commit 6,416,011,264 bytes이며 root/Vite 100을 다시 통과했습니다. 두 부모와 정확한 tree, owned Job empty, clean 작업 트리 및 MERGE_HEAD 제거를 확인했습니다. 테스트 생성 파일의 EOL-only 상태는 raw backup과 동일 canonical blob 확인 후 작업 바이트만 복원했으며 commit tree는 바뀌지 않았습니다.
  • 정확한 head의 CI 41394638378는 첫 실행에서 SUCCESS입니다. publish(Linux Rust 100% gate 포함), benchmark, release-compat, landing-next-e2e, vinext-rsc-css-e2e, react-18, webpack-extends-theme, wasm-size가 모두 success이며 release/deploy-pages만 PR 조건에 따라 skipped입니다. REST jobs API filter=all, 모든 페이지(1페이지)로 확인했고 rerun은 없습니다.
  • 새 오류 종류나 지원 범위 변경은 없습니다. 아래 이전 head의 외부 GitHub API 403 실패 기록은 역사적 기록이며 현재 head의 결과가 아닙니다.

이전 main 통합 (2026-11-01)

  • 공지된 MAIN SETTLED **7af8166487851bdfc884d735ec16160c9930443e**를 true merge했습니다. 검증된 snapshot ac79df39와 main의 merge-tree에는 새 충돌이 없었고, 실제 merge 상태에서 원래 두 충돌을 검증된 결과로 복원했습니다. 최종 **5056586598b5171987d1369b665f42f7616c887f**는 libs/packages/bindings/Cargo 입력 모두 검증된 snapshot과 동일합니다. settled main 대비 원래 11경로만 변경합니다.

  • main의 import semantic guard, checked parser, 단일 allocator, 같은 Program의 Rc scoping 및 origin-owned staged renderer를 보존했습니다. #806의 저비용 relevance 사전 필터, 두 skip-guard 예외 및 이미 읽은 Reading 재사용도 유지합니다. callback 복제나 별도 런타임 helper는 없습니다. 정적 literal-bracket namespace와 dot의 동등성, 혼합 shadow occurrence, 원본 standalone Base/Dyn 및 retarget을 두 CSS 모드에서 실제 React로 검증합니다.

  • Bun 1.4.4, Node 26.12.0, default Rust stack, CI unset, jobs2 (workspace --jobs1). frozen install 1191 installs / 1433 packages, no changes, fresh WASM/root build/verify:dist와 full fmt/clippy -D warnings/TS6-preload ESLint 통과. focused imported-styled 87/0, workspace 10,891/0/0 ignored, 실제 emitted-module React 파일 16/0, 473 assertions; root 6,774/0, Vite 870/0, 양쪽 실제 All files 100.00% functions / 100.00% lines입니다. 새 snapshot을 생성/승인하지 않았습니다.

  • ONE 정상 훅 / ONE push. 훅 872.934초, peak 6,366,941,184 bytes (12 GB 상한), heartbeat 실패 0, 정확한 owned job 종료/empty. 훅 root 6,774/0, Vite 870/0, 양쪽 100.00/100.00. Windows Rust tarpaulin **97.66% (31842/32605)**는 Linux 100%로 표현하지 않습니다. 검토/tested/staged/commit tree가 모두 50565865, 새 head 9c684a01a9910877a7d1bbd48f0aab2950e112d2, 실제 parent fa4d6635 + 7af81664, clean 작업 트리를 확인했습니다.

  • 정확한 head 9c684a01a9910877a7d1bbd48f0aab2950e112d2의 CI 41277398065 FAILURE, attempt 2. publish: failure / benchmark: success / release-compat: success / landing-next-e2e: success / vinext-rsc-css-e2e: success / react-18: success / webpack-extends-theme: success / wasm-size: success. main 전용 release/deploy-pages는 PR 조건에 따라 skipped입니다.

  • 아래 이전 head 검증 당시에는 전체 CI가 green이 아니었습니다. 이 외부 API 실패는 #893을 포함한 최신 main 통합 후 아래 새 run에서 해소되었습니다. main의 #891에서 추가된 vinext dev-navigation lane이 외부 GitHub API 403으로 실패했습니다. 최초 시도는 /team의 인증 없는 서버 요청을 포함해 5개 실패, 허용된 publish job 단 한 번의 재실행에서도 / 및 /ko의 StarButton 브라우저 요청 403으로 2개가 실패했습니다. 추출기/coverage/benchmark 실패로 표현하지 않으며, 별도 main 기반 테스트·workflow 수정으로 해결할 때까지 완료로 간주하지 않습니다.

  • 새 head의 Linux 실제 tarpaulin: 100.00% coverage, 22299/22299 lines covered, +0.00% change in coverage. root/Vite 실제 All files와 landing/benchmark 수치도 이 새 run의 로그로 확인했으며, 아래 최초 제출 당시의 수치와 구분합니다.

최초 제출 당시 검증 (아래 성능과 CI는 이전 head의 역사적 기록)

  • main RED: 원래 fixture를 변경하지 않고 별도 테스트를 추가한 뒤 6 pass / 2 fail, 두 실패 모두 module 평가 중 Dyn.withComponent is not a function. 불필요한 import만 추가한 두 control은 이미 target/ref/children/10px/20px 검증을 통과했습니다.
  • GREEN: 같은 public-API 파일 8 pass / 0 fail. 이후 정상 hook의 전체 테스트에서도 filter-first 판정과 두 CSS 모드 검증이 통과했습니다.
  • Rust: 새 relevance 테스트 20개 (positive/control 4, unchanged negative 15, no-resolver 1). cargo test --workspace 전체 통과. 기존 snapshot 변경 없음; 새 snapshot 4개는 named/reexport/namespace/control의 실제 emitted code와 dependency 목록입니다.
  • cargo fmt --all -- --check 통과. WASM bun run build 및 루트 bun run build 통과.
  • standalone bun lint는 새 helper의 wildcard import를 지적하여 explicit import로 수정했습니다. 첫 hook은 이후 추가한 테스트 줄의 CRLF formatting을 지적해 해당 테스트 파일만 scoped fix했습니다. 최종 정상 hook은 fmt/clippy -D warnings와 ESLint 0 errors / 기존 warnings 20개로 통과했습니다. hook 우회/수정, amend는 하지 않았습니다.
  • private Bun 1.4.4 루트 bun test --coverage: 6252 pass / 0 fail, 168 files, 89 snapshots, 23247 assertions, 254.67초.
All files | 100.00 | 100.00 |
  • 정상 commit hook 전체 통과: 928.30초. shared Bun 1.4.3 루트 6252 pass / 0 fail, Vite 868 pass / 0 fail, 양쪽 함수/줄 100.00%. Rust tarpaulin은 Windows 기준 **98.07% (24087/24562)**이며 100%라고 주장하지 않습니다. 변경한 Rust 줄과 uncovered 목록의 교집합은 없음; 새 relevance 모듈 27/27 실행 줄 covered. Linux CI의 wide-format 100% gate는 별도 확인합니다.
  • 최종 hook 직전 free memory 10,779,380 KiB (요구 기준 7,340,032 KiB 이상), CARGO_BUILD_JOBS=2. 공유 Bun/설정은 변경하지 않았습니다. 첫 commit 명령은 clone의 author identity 부재로 hook 이전에 종료되어, 인증된 계정의 identity를 그 명령의 환경 변수에만 지정했습니다.

성능 (12쌍 AB/BA 교차 실행의 중앙값, µs/호출)

corpus extract 전 → 후 hasDevupUI 전 → 후
작은 일반 모듈 3.121 → 2.930 2.006 → 2.081
일반 import + JSX 5.804 → 6.051 4.564 → 4.626
큰 일반 import + JSX 88.382 → 85.731 85.122 → 84.397
기존 직접 스타일 import 21.631 → 21.679 2.175 → 2.203
known imported retarget 5.403 (잘못된 skip) → 82.974 (실제 compile) 3.626 → 37.019
unknown imported retarget 6.262 → 11.725 4.324 → 10.190

무트리거 corpus의 resolver 호출 수는 전후 동일(작은 모듈/직접 스타일 0, 일반 import 1)하며 sample 범위는 겹칩니다. trigger가 있는 파일만 의미 분석과 기존 styled reader 비용을 지불합니다. known retarget의 정상 추출은 relevance에서 읽은 정의를 재사용하여 불필요한 두 번째 styled resolve를 하지 않습니다. 두 trigger corpus의 resolver 호출은 기존 barrel 확인 1회에서 styled 확인을 포함한 2회로 증가합니다.

CI 완료

Publish Package to npm — 40025554388, head fa4d6635b7de18e832035efe3f739fd2d5f947dc: success, 첫 실행에서 완료, rerun 없음.

Linux wide-format 후 tarpaulin: 100.00% (17059/17059), 새 relevance 모듈 15/15. --fail-under 100 gate 통과. 배포/release는 PR 이벤트 조건에 따라 skipped입니다.

Job 결과 소요 시간
publish success 20m15s
landing-next-e2e success 8m07s
benchmark success 15m46s
wasm-size success 5m32s
react-18 success 2m33s
vinext-rsc-css-e2e success 3m47s
release-compat success 6m40s
webpack-extends-theme success 4m34s
deploy-pages skipped —
release skipped —

Refs #689

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@codecov

codecov Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
libs/extractor/src/imported_styled.rs 100.00% <ø> (ø)
libs/extractor/src/imported_styled/relevance.rs 100.00% <100.00%> (ø)
libs/extractor/src/lib.rs 100.00% <100.00%> (ø)
libs/extractor/src/visit.rs 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

owjs3901 and others added 2 commits November 1, 2026 14:18
Refs #689

Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Refs #689

Integrate settled main containing #893 while preserving the imported styled retarget repair.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
@owjs3901
owjs3901 merged commit 675f7e2 into main Nov 2, 2026
11 checks passed
@owjs3901
owjs3901 deleted the fix/imported-retarget-relevance branch November 2, 2026 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant