Skip to content

fix(extractor): compile vanilla-extract theme contracts across modules - #761

Draft
owjs3901 wants to merge 44 commits into
mainfrom
fix/vanilla-extract-themes
Draft

owjs3901 wants to merge 44 commits into
mainfrom
fix/vanilla-extract-themes

Conversation

@owjs3901

@owjs3901 owjs3901 commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Refs #690 (D: vanilla-extract 테마 및 모듈 값), #693 (K: DOC-09). 이 PR은 #757 위에 쌓인 변경이며, #757 및 그 기반 PR #750이 먼저 병합되어야 합니다. 병합 대상은 main이며 자동 병합하지 않습니다.

요약

현재 네 번째 검증 단계입니다. stylesheet와 static styling-data 일반 모듈의 테마/변수 검증, imported base D1, selector identity, default/aliased/forwarded exports, theme.css graph 및 consumer 타입을 수정했습니다. 혼합 application/runtime 모듈의 targeted exact-slice 평가는 다음 수정 대상입니다.

동작

  • 전체 계약과 값의 중첩 형태가 일치해야 합니다. 일부만 할당할 때에는 일치하는 하위 계약을 전달합니다.
  • fallbackVar의 마지막 값을 제외한 인자는 CSS 변수 참조여야 하며, 오른쪽부터 중첩 fallback을 구성합니다.
  • createGlobalThemeContract는 직접 지정하거나 mapper가 반환하는 이름을 문자열 그대로 검증합니다. null/숫자/object의 문자열 변환으로 잘못된 이름을 생성하지 않습니다.
  • vanilla-extract의 enumerable token 순회를 따라 상속된 enumerable 속성, non-enumerable shadowing, @layer object-rest 동작을 보존합니다.
  • .css.ts/.css.js의 imported base는 실제 producer가 출력한 typed atom metadata로 합성합니다. 뒤의 값이 동일 property/selector/breakpoint/layer의 앞선 값을 제거하며, 외부 class와 selector anchor는 유지합니다. 객체/base가 교차하거나 반복되는 순서도 보존합니다.
  • ./theme.css 및 TS path alias가 가리키는 .css.ts/.css.js를 module evaluator와 source graph가 같은 resolver로 찾습니다. graph의 source 범위와 기존 raw CSS/extension 조건은 유지합니다.
  • 중첩 계약 leaf는 CSS 변수 문자열로 매핑하고, inferred/existing-contract 및 global theme overload, assignVars, variants callback, vars style rule, debug IDs/property declaration의 타입을 실제 API에 맞춥니다.
  • styling runtime, 의존성 추가 및 커버리지 제외는 없습니다.

새로 생기는 오류

모든 오류는 원본 file:line:col, 원인 및 수정 방법을 표시합니다.

  • Tokens don't match contract: 누락/추가된 키, leaf/object 또는 빈 중첩 object 구조 불일치. 전체 계약과 일치하는 값을 제공하거나 일치하는 하위 계약을 전달합니다.
  • Invalid variable name: fallbackVar의 마지막 fallback 이전 인자가 var(--name) 참조가 아닙니다.
  • Invalid variable name for "nested.path": 전역 계약의 직접 이름 또는 mapper 반환값이 CSS 식별자 escaping으로 바뀌지 않는 유효한 문자열 이름이 아닙니다.
  • TypeError: Theme tokens must be an object: null/undefined/string/number/boolean을 테마 token object 대신 전달했습니다. token object 또는 계약과 일치하는 token object를 전달합니다. upstream의 @layer in tokens 오류 의미를 유지하면서 원인/수정 방법을 표시합니다.

남는 한계

static styling-data 일반 모듈은 지원하지만, JSX/host/runtime 코드가 섞인 application 모듈과 ordinary dependency의 unrelated runtime exports는 아직 targeted slice가 필요합니다. 해당 경로는 새 full evaluation을 선택하지 않으며 완료로 주장하지 않습니다. recipes/sprinkles(#718), StyleX(#758), 문서 페이지(W23)는 범위 밖입니다.

검증

  • 베이스 fix(extractor): locate diagnostics and enforce deterministic evaluation #757 6d0c9c837598a08103051f51effda5ea65ffb2fc에서 case-058/059를 .ts, .tsx, .js, .jsx, .mjs, .css.ts, .css.js 각각 real WASM probe로 재현했습니다. imported fixture는 --modules와 실제 theme.css.ts/tokens.ts를 사용합니다.
  • 수정 전 semantic regressions: 37개 중 27개 실패. 수정 후 evaluator focused tests: 72 passed, 0 failed(새 semantic cases 47개 포함).
  • WASM 및 root package build 성공. 실제 WASM probe에서 잘못된 계약/fallback/전역 이름이 located 오류로 바뀌고, 유효한 assignVars의 CSS 선언이 유지되는 것을 확인했습니다.
  • 첫 커밋 9b36c0d9fcb8ca9370632007cf57c9f97ebe91e2는 전체 파일을 stage한 exact-tree로 실제 pre-commit hooks를 통과했습니다: fmt/clippy/ESLint(기존 경고 2개), Rust tests 3,180 passed/0 failed, Bun tests 5,504 passed/0 failed.
  • 로컬 Windows tarpaulin은 **97.90%(18,931/19,337)**이며 100% 달성을 주장하지 않습니다. 새 semantic modules는 각각 contracts 73/73, traversal 34/34, fallback 19/19입니다. 최종 Linux --fail-under 100 결과를 기준으로 후속 테스트를 보완합니다. Bun aggregate는 100%지만 Vite plugin의 개별 line coverage는 99.63%(303행)였으므로 이것도 최종 CI 결과와 구분합니다.
  • 머신 전체 LSP daemon 장애는 coordinator가 확인했습니다. 재시도하지 않고 compiler/clippy/tests/hooks 및 Linux CI를 증거로 사용합니다.
  • 두 번째 exact-tree 커밋은 foreground에서 Rust 1.99 clippy 0 warnings, extractor 2,504 unit + 4 integration tests, consumer typecheck, WASM/root build, shimmed ESLint, plugin-utils 147 tests/100% source coverage를 확인한 뒤 실제 hooks를 통과했습니다. Windows coverage는 97.89%이며 Linux 결과와 구분합니다.
  • 첫 Linux run 37307304947은 Rust 99.99%에서 parent split_layer의 한 줄만 미실행이라 실패했습니다. 나머지 landing-next-e2e/benchmark/vinext-rsc-css-e2e는 성공했습니다. 해당 경로는 단순 coverage padding 대신 실제 non-object token 오류로 수정하고 10개 negative regressions를 추가했습니다.
  • 최종 전체 gates, 새 commit, Linux CI 및 아래 before/after 출력은 후속 검증 후 갱신합니다.
  • 세 번째 커밋 6fb817185bab67fdf3fcc23d539454915b4a9c38: foreground Rust1.99 clippy, extractor2,517unit+4integration, root/WASM build 및 실제probe 성공 후 exact-tree hooks 통과(Rust3,240/Bun5,511,0fail). selector identity는 declaration-free marker로 유지하며 atomic property를 다시 붙이지 않습니다. 원본 export/local mapping을 읽고 initializer를 재실행하지 않습니다.
  • Run 37365809758의 모든4jobs는 runner미할당/zero steps로 cancelled였습니다. coordinator가 GitHub-hosted runner incident를 확인했으므로 workflow변경/반복rerun 없이 기록합니다. 복구 후 coordinator가 재시도합니다.

추가 Imported 값 Probe 수정

imported selector before: a b:focus{opacity:.5}; a b:hover .e{background:yellow}
after: .f0_0:focus{opacity:.5}; .f0_0:hover .c{background:yellow}

default/aliased export before: producer의 export가 사라져 consumer 4:66에서 undefined-object 오류
after: export { __ve_export_2__ as "base" }; export { __ve_export_3__ as "default" };
consumer: background:var(--colors-bg-0-0);color:blue;padding:8px

실제 Probe: Stylesheet 두 종류

동일 fixture를 .css.ts 및 .css.js로 각각 fresh process에서 실행했습니다. imported case는 실제 theme.css.ts/tokens.ts와 --modules를 사용했습니다.

case-058 before/after (.css.ts 및 .css.js 동일):
export const box = "a";
export const light = "theme-0-1";
.theme-0-1{--colors-bg-0-0:white}
.a{background:var(--colors-bg-0-0)}

case-059 before (.css.ts 및 .css.js 동일):
export const button = "c d" + " a b";
.c{color:blue}.d{margin:var(--space-0-1)}

case-059 after (.css.ts 및 .css.js 동일):
export const button = "b c d";
.d{color:blue}.c{margin:var(--space-0-1)}.b{padding:8px}

일반 .ts/.tsx/.js/.jsx/.mjs의 수정 전에는 case-058의 vars.colors.bg(6:20), case-059의 vars.space(7:23)가 모두 같은 located 오류였습니다. 네 번째 commit 099830a71b382bb114ced10aec0a7e9c9a8446f5의 real WASM probe에서는 모든7종류가 동일하게 아래 결과를 출력했습니다(--modules 사용):

case-058 after (7종류 동일):
export const box = "f0_0 a";
export const light = "theme-0-1";
.theme-0-1{--colors-bg-0-0:white}.a{background:var(--colors-bg-0-0)}

case-059 after (7종류 동일):
export const button = "f0_0 f1_0 a c d";
.d{color:blue}.c{margin:var(--space-0-1)}.a{padding:8px}

theme-only.ts before: WASM unreachable trap
after: export const theme="theme-0-0";export const vars={colors:{bg:"var(--colors-bg-0-1)"}};
.theme-0-0{--colors-bg-0-1:white}

Namespace all16 API fixture 및 assignVars 일반-module fixture도 실제 WASM에서 오류 없이 컴파일했습니다. Foreground14focused/2,531unit+4integration/clippy/rootbuild와 exact-tree hooks(Rust3,254/Bun5,511,0fail)를 확인했습니다. 혼합 application 모듈 slice는 아직 완료가 아닙니다.

owjs3901 and others added 30 commits October 1, 2026 21:16
…rations

css(a, b) composing classes whose styles the build knows, bound to css() in the file or exported by another module, merges their atoms per property, selector, breakpoint and layer, conditions included, instead of joining classes whose winner the stylesheet order picked. vanilla-extract style([...]) passes each composed style as its own argument, keeping a style composed again later.

Refs #688

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #688

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #688

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #688

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

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

Refs #688

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…JSX spreads win

Refs #688

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…led order and JSX element className

Refs #688

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #689

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…uate shouldForwardProp at build time

Refs #689

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

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

Refs #689

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #691

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #690

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
… and conditional styles

Refs #690

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…h Emotion

Refs #690

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #690

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…ed parameters

Refs #690

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #690

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…ead through namespaces

Refs #695

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…akes from the visitor

Refs #695

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…eclared after their use

Refs #695, #686

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #695

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #695

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

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

Refs #695

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #695

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #695

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #695

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #695

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
owjs3901 and others added 14 commits October 5, 2026 06:31
Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #685, #694

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

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

Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #685, #694

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #690

Refs #693

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #690, #693

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #690, #693

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

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

Refs #690, #693

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
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