Repository navigation
fix(extractor): read constants in Emotion rules as px and compose mixins and inline css() by styles - #740
Merged
Conversation
…ins and inline css() by styles Refs #688, #690 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Contributor
Changepacks@devup-ui/wasm@1.0.83 → 1.0.84 - bindings/devup-ui-wasm/package.jsonPatch
@devup-ui/bun-plugin@1.0.22 → 1.0.23 - packages/bun-plugin/package.jsonPatch
@devup-ui/components@0.1.60 → 0.1.61 - packages/components/package.jsonPatch
@devup-ui/eslint-plugin@1.0.22 → 1.0.23 - packages/eslint-plugin/package.jsonPatch
@devup-ui/next-plugin@1.0.90 → 1.0.91 - packages/next-plugin/package.jsonPatch
@devup-ui/plugin-utils@1.0.17 → 1.0.18 - packages/plugin-utils/package.jsonPatch
@devup-ui/react@1.0.44 → 1.0.45 - packages/react/package.jsonPatch
@devup-ui/reset-css@1.0.31 → 1.0.32 - packages/reset-css/package.jsonPatch
@devup-ui/rsbuild-plugin@1.0.67 → 1.0.68 - packages/rsbuild-plugin/package.jsonPatch
@devup-ui/vite-plugin@1.0.73 → 1.0.74 - packages/vite-plugin/package.jsonPatch
@devup-ui/webpack-plugin@1.0.71 → 1.0.72 - packages/webpack-plugin/package.jsonPatch
|
Codecov Report✅ All modified and coverable lines are covered by tests.
🚀 New features to boost your workflow:
|
This was referenced Oct 3, 2026
owjs3901
added a commit
that referenced
this pull request
Oct 8, 2026
Refs #690 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
owjs3901
added a commit
that referenced
this pull request
Oct 18, 2026
Preserve the updated parent guards and local-style features while capturing conditional rule controllers once and retaining static theme path checks. Refs #707 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>
Refs #690 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…e Emotion number fixes Refs #690 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #690, #688 (Emotion 계열 규칙의 숫자와 조합). #730 위에 쌓인 브랜치입니다. #706 #707 #710 #711 #722 #727 #728 #729 #730이 먼저 병합되어야 합니다.
요약
Emotion, styled-components, vanilla-extract로 쓴 규칙에서
cssprop 밖에 남아 있던 세 가지 어긋남을 고칩니다.const gap = 8; css({ padding: gap })은px가 아니라 Devup의 간격 스케일(32px)이 되었습니다. 리터럴8만 사전 패스(LibraryNumbers)에서"8px"로 바뀌고, 상수는 나중에 인라인되면서(inline_constants)cssprop 안에서만px를 받았기 때문입니다.css`${mixin}; color: red;`가 mixin의 클래스와 템플릿의 클래스를 이어 붙이기만 해서, 뒤의 선언이 mixin의 선언을 대체하지 못하던 문제.css(css({ color: 'red' }), { color: 'blue' }),css(cond && css({ ... }), base)처럼css()인자 안의css()호출이 먼저 자기 클래스로 컴파일되어 정적 조합이 되지 않던 문제.동작
1. 상수의
px. 사전 패스가 규칙 안의 값과 규칙 자체가 놓인 위치(상수가 대신 설 수 있는 표현식)의 소스 범위를 기록해Aliased.px로 넘기고,inline_constants는 그 위치에서 상수를 인라인할 때 리터럴과 똑같이 처리합니다. 숫자는px문자열이 되고, 상수 객체(css(rules),...rules,'&:hover': rules)는 안쪽 숫자까지px가 됩니다. 단위 없는 속성(keeps_bare_number)은 맨 숫자를 유지하고,0은0이며,p·mx같은 Devup 단축 속성은 간격 스케일을 유지합니다.vars아래와@devup-ui/react의css는 건드리지 않습니다. 지역 상수, 가져온 상수,-gap·gap * 2·cond ? gap : 4·gap || 3·(gap)같은 식,css(),styled.div()/styled()(),Global styles,ClassNames의css, vanilla-extractstyle()에 적용됩니다.2. 템플릿 안의 mixin.
template_parts로 텍스트를 mixin 앞뒤로 나누고(cssprop과 같은 경로), 스타일을 아는 클래스(css()/css템플릿 상수)가 mixin이면known_parts/composed_class로 스타일 단위로 조합합니다. 뒤의 선언이 이깁니다.css템플릿 상수도 이제 스타일을 아는 클래스라서 이후css(a, b)나 다른 템플릿이 이를 스타일로 조합합니다. 스타일을 모르는 mixin(런타임 인자 등)은 이전처럼 클래스를 잇습니다(CSS 캐스케이드).3. 중첩된 인라인
css(). 방문 전에css()인자(와 템플릿 mixin) 안의 인라인css()호출을 자신이 조합하는 것들의 배열로 펼치고, 배열·조건·&&/||/??를 따라 내려갑니다. 그 뒤cssprop·ClassNames와 같은 정적 조합 경로로 합쳐 뒤가 이깁니다. 템플릿 안의 인라인css`...`는 클래스가 CSS 텍스트로 읽히지 않도록 배열로 감쌉니다.known_side가ClassNames밖에서도 배열을 읽어cond && [css(...), {...}]가 조합됩니다.새로 생기는 오류
없습니다. 이전에 컴파일되던 입력은 같은 스타일을 더 정확한 순서로 냅니다. 이전에 오류였던 입력(런타임 값, 펼침 인자 등)은 같은 오류를 그대로 냅니다.
남는 한계
css(css`color: red;`, { color: 'blue' })처럼 인자로 들어간 태그드 템플릿css는 여전히 먼저 클래스로 컴파일되어 클래스로 이어집니다(캐스케이드). 템플릿 mixin 안의 인라인css`...`도 같습니다. 호출 형태(css({...}))만 스타일 단위로 조합됩니다.css(...rest)처럼 펼침 인자를 가진 인라인 호출은 펼치지 않고 이전처럼 컴파일하며, 같은 오류를 냅니다.css(cond && [{ ... }, { ... }], { ... })처럼 인라인css()가 없고 규칙 객체 배열만 있는 호출은 이전처럼 일반 경로에서Cannot compose오류입니다(이 PR의 범위 밖).검증
vars·css/styled/Global/ClassNames/style/@devup-ui/react의css(변경 없음 확인), 템플릿 mixin(스타일을 아는/모르는/조건부/중첩), 중첩·조건부 인라인css()(배열,&&,||, 삼항, 3중 중첩, 펼침 인자,@devup-ui/react). 기존template_interpolations스냅샷의 한 항목(css`${mixin} ...`)이`a-e ${mixin}`에서 같은 클래스를 정적으로 합친"a-a a-e"로 바뀌었습니다.cargo fmt --all,cargo +1.99 clippy --workspace --all-targets -- -D warnings,cargo test --workspace통과. CI와 같은 넓은 rustfmt 설정으로cargo tarpaulin --engine llvm을 돌려 이 PR의 줄이 모두 덮이는 것을 확인했습니다(로컬 Windows에서 남는 줄은 모두 이전부터 있던 다른 코드입니다).bun run build,bun test(5487 pass, 0 fail, 커버리지 100%),bun lint(이전부터 있던 경고 2개만).2026-10-08 main 11790bef를 병합하여 업데이트했습니다. 충돌 없이 갱신된 부모 PR의 변경과 main의 변경을 모두 보존했습니다.
W62d 최신 부모 및 정적 fallback 통합
녹색인 최신 #730
c3bfe034901640dcb538095231376b604c1e1579를 기존 headb3f0ac46에 실제 두 부모 merge93fe24a4877d11a14f30a7a1fd914eefe6f3b8e4로 통합했습니다. maina6ecc125가 부모에 포함되어 별도 중복 merge나 sibling #738/#763 merge는 하지 않았습니다. 숫자 px marks와 부모의 namespace·fallback·companion 오류·원본 위치·dead property 검증을 함께 유지하고, template 검증은 mixin 합성보다 먼저 실행합니다. 원래 11개 경로 밖의 부모 파일은 바이트 동일합니다.실제 WASM에서
const A=1,B=2; css({padding:[A,B]})가 리터럴[1,2]와 달리 Devup의4px/8px반응형으로 나오는 통합 버그를 발견해 수정했습니다. 이미 부모가 처리하는 정확히 정적인 다중 문자열/숫자 fallback 포맷을 상수 인라이닝 뒤에도 재사용하여 같은 level0의padding:1px;padding:2px를 만듭니다. Native Devup의 반응형·배율, unitless·zero·vars, 기존 비fallback 배열과 알 수 없는 값의 위치 있는 오류는 변경하지 않았으며 동적 배열·런타임·새 evaluator를 추가하지 않았습니다.4,547개 통과 / 0개 실패, fmt·Rust 1.99 strict clippy를 통과했고 snapshot 후보는 0개입니다.5,922개 통과 / 0개 실패 / 함수·라인 100%, lint 오류 0개와 기존 경고 9개입니다. 실제 public WASM 118개 비교와 Chromium 12개 검사가 두 CSS 모드 및 desktop/mobile에서 모두 통과했습니다. 상수 fallback의 padding은 모든 화면에서2px, 알려진 template/inline mixin은 최종 파랑·margin1px임을 실제 computed style로 확인했습니다.97.78% (19,989/20,443), Bun5,922/0/100%, 자식 전체 최대 4.684GB 및 종료 후 0개입니다. Windows 값을 Linux 100%로 주장하지 않으며 새 head의 CI 결과를 별도로 기록합니다.W62d 최종 CI
최종 head
93fe24a4877d11a14f30a7a1fd914eefe6f3b8e4의 CI 38940537637이 전체 성공했습니다. Linux Rust100.00% (14,310/14,310), Bun5,922개 통과 / 0개 실패 / 함수·라인 100%, preload 회귀 8개 통과이며 publish·benchmark·Next landing·vinext RSC CSS의 4개 검증 job이 모두 성공했습니다. 실제 checkout66d47959731fcbb2a2d02932e9d3c5beccebd940의 전체 트리와 테스트·push한 merge 트리의 일치를 확인했습니다. 정적 상수 fallback 수정 외에 새 거부 정책이나 추가 한계 없이 부모의 오류·배열·캡처 계약을 유지했습니다.W62l 최신 main 통합
main
7188d5ff(#730, #736, #792가 병합된 상태)를 실제 두 부모 mergecaa3339acc43ab7d5bedd435482090d5008a936f로 통합했습니다. 먼저 병합된 #730 최신 head18e496f1을 합치고(c6f460ca) Linux 줄 단위 커버리지가 비던px_rules의 도달하지 않는 분기를 구조 변경으로 없앤 뒤(a2932bc4), main을 합쳤습니다. 이번 통합의 충돌은 세 군데로,px_rules는 #730의 반복형(깊은 중첩에서도 기본 스택을 쓰지 않음)에 이 PR의vars제외와 규칙 배열 처리를 합쳤고,Inline.class_names는 #730의SymbolId방식을 따르며 이 PR의 px marks와 위치 구분을 유지했고, #736의imported_styled.rs는 가져온 모듈을 읽을 때 그 모듈 자신의 px marks를inline_constants에 넘기도록 맞췄습니다. 스냅샷 3개는 main의 컴포넌트 표식 클래스(a--a)와 이 PR의 정적 합성("a-a a-e")이 함께 나온 결과이며 CSS 선언은 이전과 같습니다.새로 생기는 오류는 없습니다. Rust
5,841개 통과 / 0개 실패, fmt·clippy 통과, Bun6,631개 통과 / 0개 실패 / 함수·라인 100%, lint 오류 0개와 기존 경고 20개입니다. Windows hook의 Rust97.95%는 Linux 100%가 아닙니다. CI 39390101296이 headcaa3339a에서 전체 성공했고, Linux Rust100.00% (15,688/15,688), Bun6,631개 통과 / 0개 실패 / 함수·라인 100%이며 publish·release-compat·benchmark·wasm-size·react-18·landing-next-e2e·vinext-rsc-css-e2e·webpack-extends-theme가 모두 성공했습니다. 앞선 headc6f460ca의 CI 39371550589는 Linux 줄 하나(px_rules의_ => {})가 비어 publish만 실패했고 위 구조 변경으로 고쳤습니다.