Skip to content

fix(wasm): skip source-map generation in the no-map export - #771

Merged
owjs3901 merged 2 commits into
mainfrom
fix/wasm-skip-source-map
Oct 14, 2026
Merged

owjs3901 merged 2 commits into
mainfrom
fix/wasm-skip-source-map

Conversation

@owjs3901

@owjs3901 owjs3901 commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Refs #686, #682 (W48). origin/main의 11790bef에서 시작한 독립 PR이며 먼저 병합해야 하는 다른 PR은 없습니다.

요약

codeExtractWithoutSourceMap의 실제 WASM export가 이름과 달리 SourceMapMode::Generate를 전달하여 소스맵을 생성하던 버그를 수정합니다. native 테스트용 내부 함수는 이미 Skip을 사용하므로 기존 Rust 테스트만으로는 이 export 버그를 찾을 수 없었습니다.

프로덕션 변경은 export의 Generate를 Skip으로 바꾸는 한 줄입니다. WASM 및 회귀 테스트가 들어간 Next 패키지에 Patch changepack을 추가합니다.

동작

  • 실제 JS/WASM 호출에서 소스맵을 요청하지 않으면 map은 undefined이고 Oxc의 소스맵 생성 경로를 실행하지 않습니다. 모듈 resolver가 있는 경우와 없는 경우 모두 검증합니다.
  • 추출된 코드, CSS, CSS 파일명, 기본 스타일 변경 여부, 의존성은 Generate 경로와 바이트 단위로 같습니다. 기존 추출 스냅샷의 입력 683개를 실제 WASM으로 비교하여 성공 출력 682개 및 같은 오류 1개를 확인했습니다. 672개 Generate map에 대해 Skip map은 모두 없습니다.
  • 일반 codeExtract는 원본 소스가 들어 있는 v3 map을 그대로 생성합니다.
  • caller 조사 결과 Vite/Webpack/Rsbuild/Bun은 현재 일반 codeExtract를 사용합니다. Next는 sourceMap:false일 때 no-map export를 선택하지만 optional map을 복사/전달하므로 사전 확인을 거쳐 진행했습니다. 실제 coordinator HTTP 및 loader에서 prewarm 적중/미적중 모두 map 비활성화는 null, 활성화는 기존 map을 그대로 전달함을 검증했습니다. 플러그인 프로덕션 정책은 바꾸지 않습니다.

수정 전 main을 새로 WASM 빌드한 뒤 다음 입력을 실제 export에 전달하면 map이 v3 문자열이어서 map 부재 회귀 검증이 실패합니다. 수정 후 같은 호출은 다음 코드/CSS를 그대로 반환하면서 map을 반환하지 않습니다.

import { Box } from "@devup-ui/react"; export const box = <Box color="red" />;
import "./df/devup-ui-0.css";
export const box = <div className="a-a" />;
// .a-a{color:red}
// map: undefined

간단한 실제 앱 측정

기존 apps/next의 Next 16.3.6/Turbopack 프로덕션 빌드를 전후 각각 한 번 실행했습니다. 기존 vite-lib 앱 의존성을 먼저 빌드했으며 앱 소스는 수정하지 않았습니다.

측정 main 수정 후
전체 빌드 4.259초 12.257초
Next prewarm의 WASM 추출 (2파일) 30.71ms 20.61ms

공유 머신과 서로 다른 incremental 캐시 상태에서 얻은 단일 표본입니다. 전체 빌드가 빨라졌다는 주장이나 재현 가능한 성능 개선 수치로 해석하지 않습니다. 불필요한 map이 실제로 생성되지 않는 점은 시간 대신 회귀 테스트로 검증합니다.

새로 생기는 오류

없습니다. 기존 오류 및 source-map 활성화 동작은 유지됩니다.

남는 한계

다른 플러그인의 기존 source-map 선택 정책은 변경하지 않습니다. 로컬 normal-format Rust tarpaulin에는 기존 여러 줄 구문 계측 공백이 있으므로 전체 Rust 100% 판정은 CI의 기존 wide-format 설정과 --fail-under 100 결과를 기준으로 합니다. LSP는 TypeScript/Biome 미설치 및 Rust daemon timeout으로 이용할 수 없었으며 통과로 기록하지 않습니다.

검증

  • 수정 전 새 WASM에서 실제 map 부재 회귀가 실패, 수정 후 실제 WASM/resolver/Next loader 회귀 7개 통과.
  • cargo fmt --all, Rust 1.99 clippy --workspace --all-targets -- -D warnings 통과.
  • INSTA_FORCE_PASS를 해제한 cargo test --workspace: 2,395개 통과, 0 실패. 기존 스냅샷 및 .snap.new 변경 없음.
  • 새 WASM 빌드, 루트 빌드, verify:dist, 실제 Next 앱 빌드 통과.
  • 전체 Bun: 5,505개 통과, 0 실패, 함수/라인 커버리지 100%, 스냅샷 89개.
  • bun lint: 0 오류, 기존 경고 2개만 존재.
  • 두 커밋 모두 전체 파일을 stage하여 실제 테스트한 트리와 커밋 트리를 일치시켰고 hook의 lint/tarpaulin/Bun 테스트를 통과했습니다. stash, hook 우회, amend, force-push 없음.
  • 최종 metadata hook은 Windows Job Object로 모든 하위 프로세스를 묶어 매초 private memory를 검사하는 foreground watchdog에서 통과했습니다 (최대 약 3.20GB, 제한 12GB, 강제 중단 없음). 일반 빌드/테스트 제한 6GB, Rust jobs 2, 동시 compiler/server lane 1개를 사용했습니다.
  • 코드 게이트 재검토 APPROVE. Linux CI와 100% Rust/Bun 커버리지를 확인하여 draft를 ready로 전환합니다. 병합하지 않습니다.

Linux CI 37909481974: success, head 1a606ef3f5e75a842df19950b76fb42e60acf670.

  • publish, benchmark, landing-next-e2e, vinext-rsc-css-e2e 모두 success.
  • Linux tarpaulin: 100.00%, 9,890/9,890 lines covered. Bun: 5,505 pass / 0 fail, 함수/라인 100%.
  • 추가한 실제 WASM 및 Next coordinator/loader 회귀 7개도 Linux에서 통과.
  • Landing/Next/RSC의 기존 per-file 및 singleCss e2e 게이트, 배포 tarball 검증, Codecov 업로드와 patch check 통과. 워크플로 및 스냅샷 기준선 변경이나 재실행은 없습니다.

owjs3901 and others added 2 commits October 9, 2026 17:41
Refs #686

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

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

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

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

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Changepacks

@devup-ui/wasm@1.0.83 → 1.0.84 - bindings/devup-ui-wasm/package.json

Patch

  • style-order-range only checks styleOrder where the build reads it: a prop of a Devup UI component and a top-level key of a style object passed to css/globalCss/keyframes. A styleOrder key in nested data, in a prop value such as an element passed as a prop, or in a call of a function sharing a name with an Object.prototype member is no longer reported. The array, typography and media rules already skip non-style data, and css-utils-literal-only accepts a css()/keyframes() result held in a const inside a function. No new build errors.
  • Tailwind classes in a className: each class compiles on its own and every class Tailwind does not define (custom, plugin and analytics classes) stays as written, where any recognized class used to rebuild the whole className without them and could rewrite part of another class; a class touching a template interpolation (icon-${name}) is left as written, and template classNames no longer get spaces inserted around interpolations. A class whose variant is not understood stays as written instead of applying unconditionally; variants follow Tailwind v4: stacked variants compose (hover:focus: matches the element itself), hover is guarded by @media (hover: hover), group-/peer- use the group/peer marker classes (and group-hover/name), and data-, aria-, has-, nth-, , **, supports-[…] and [&…]/[@media …] variants compile. Utilities emit all their declarations (size-, rounded-t-, truncate, sr-only, not-sr-only, text-sm with its line height, text-sm/6, leading-), translate/rotate/scale/skew compose through Tailwind's individual properties and registered variables (@Property) with negative values kept negative, and arbitrary values follow Tailwind's grammar: spaces for underscores except in url() and var() names, _ for an underscore, spaces around math operators, type hints, [property:value] and (--variable) shorthands. Words that only share a utility's prefix (select-wrapper, order-summary, cursor-foo) are no longer compiled
  • Skip source-map generation in the codeExtractWithoutSourceMap WASM export while preserving extracted code, CSS and dependencies. Add real WASM and Next loader regressions for map-enabled and map-disabled extraction. No new build errors.

@devup-ui/bun-plugin@1.0.22 → 1.0.23 - packages/bun-plugin/package.json

Patch

  • Bun plugin works with Bun.build: DevupUI() (from @devup-ui/bun-plugin/register) serves the generated stylesheet to the bundler's CSS loader once every other module is loaded, so the build emits a CSS output with the styles of the whole bundle instead of an empty module; class names are short there and readable under the runtime (debug option). Files importing the packages Devup UI takes the place of (@emotion/react, @emotion/styled, styled-components, @vanilla-extract/css), @stylexjs/stylex, or a subpath or re-export of these or @devup-ui/react, are compiled instead of skipped

@devup-ui/components@0.1.60 → 0.1.61 - packages/components/package.json

Patch

  • Auto-update: depends on '@devup-ui/vite-plugin' via a local workspace dependency

@devup-ui/eslint-plugin@1.0.22 → 1.0.23 - packages/eslint-plugin/package.json

Patch

  • style-order-range only checks styleOrder where the build reads it: a prop of a Devup UI component and a top-level key of a style object passed to css/globalCss/keyframes. A styleOrder key in nested data, in a prop value such as an element passed as a prop, or in a call of a function sharing a name with an Object.prototype member is no longer reported. The array, typography and media rules already skip non-style data, and css-utils-literal-only accepts a css()/keyframes() result held in a const inside a function. No new build errors.

@devup-ui/next-plugin@1.0.90 → 1.0.91 - packages/next-plugin/package.json

Patch

  • Skip source-map generation in the codeExtractWithoutSourceMap WASM export while preserving extracted code, CSS and dependencies. Add real WASM and Next loader regressions for map-enabled and map-disabled extraction. No new build errors.

@devup-ui/plugin-utils@1.0.17 → 1.0.18 - packages/plugin-utils/package.json

Patch

  • Webpack and Rsbuild builds hold every style in their stylesheets: a stylesheet module is built on its first import, so styles extracted later (the global styles of files webpack or Rsbuild reached late, often outside src) were missing from the output. The files the entries reach under src are now extracted before the build, the shared base on disk is kept current, and when a stylesheet still changed during the build it is compiled once more, writing only the complete result. Rsbuild serves each stylesheet from the current sheet instead of a module-wide string kept only when it grew, which left edits that shortened the CSS and later builds in the same process stale. plugin-utils adds computeReachableFiles

@devup-ui/rsbuild-plugin@1.0.67 → 1.0.68 - packages/rsbuild-plugin/package.json

Patch

  • Webpack and Rsbuild builds hold every style in their stylesheets: a stylesheet module is built on its first import, so styles extracted later (the global styles of files webpack or Rsbuild reached late, often outside src) were missing from the output. The files the entries reach under src are now extracted before the build, the shared base on disk is kept current, and when a stylesheet still changed during the build it is compiled once more, writing only the complete result. Rsbuild serves each stylesheet from the current sheet instead of a module-wide string kept only when it grew, which left edits that shortened the CSS and later builds in the same process stale. plugin-utils adds computeReachableFiles

@devup-ui/vite-plugin@1.0.73 → 1.0.74 - packages/vite-plugin/package.json

Patch

  • Auto-update: depends on '@devup-ui/plugin-utils' via a local workspace dependency

@devup-ui/webpack-plugin@1.0.71 → 1.0.72 - packages/webpack-plugin/package.json

Patch

  • Webpack and Rsbuild builds hold every style in their stylesheets: a stylesheet module is built on its first import, so styles extracted later (the global styles of files webpack or Rsbuild reached late, often outside src) were missing from the output. The files the entries reach under src are now extracted before the build, the shared base on disk is kept current, and when a stylesheet still changed during the build it is compiled once more, writing only the complete result. Rsbuild serves each stylesheet from the current sheet instead of a module-wide string kept only when it grew, which left edits that shortened the CSS and later builds in the same process stale. plugin-utils adds computeReachableFiles

@codecov

codecov Bot commented Oct 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
bindings/devup-ui-wasm/src/lib.rs 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
owjs3901 marked this pull request as ready for review October 9, 2026 09:26
@owjs3901
owjs3901 merged commit b54a8f1 into main Oct 14, 2026
5 checks passed
@owjs3901
owjs3901 deleted the fix/wasm-skip-source-map branch October 14, 2026 06:29
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