You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
vite/webpack/next/rsbuild/bun 플러그인과 WASM 바인딩의 문제들입니다. 확인 예: Bun이 생성한 CSS를 버림, Bun의 사전 검사가 alias·StyleX 파일을 건너뜀, Rsbuild가 오래된 CSS를 제공.
전체 계획과 결정 사항은 추적 이슈(#682)에 있습니다. 조사 기준 커밋: 77daad74 (현재 main d0b84255).
발견 항목
심각도: P0 = 흔한 사용에서 조용히 틀리거나 크래시, P1 = 흔한 패턴이 명시적 에러로 막히거나 드물게 조용히 틀림, P2 = 드문 경우·도구/문서 불일치, P3 = 있으면 좋음.
필수 (4)
PLG-01 (P0, WRONG) Bun discards generated CSS during bundling
근거: packages/bun-plugin/src/plugin.ts:74-80,127-138 resolves every generated stylesheet into { contents: '', loader: 'js' }. Bun 1.4.2 officially supports an onLoad result with loader: 'css', and JavaScript CSS imports are combined into emitted .css; the plugin instead turns the import into an empty JS module.
수정 방향: Return current sheet contents with loader:'css' for Bun.build, while using a separate runtime/test behavior if runtime imports truly need an empty module. Add an end-to-end Bun.build assertion for the emitted CSS asset.
PLG-02 (P0, CRASH) Bun's pre-parse gate skips every compatibility alias and StyleX
근거: compat-detection-probe.ts: hasDevupUI(...,'@devup-ui/react') returned false for @emotion/styled, @emotion/react/jsx-runtime, classic Emotion css-prop pragma, and @stylexjs/stylex. Direct codeExtract transformed Emotion styled and StyleX successfully, proving the gate—not the extractor—drops them. Published placeholders/aliases then execute at runtime or remain unc…
수정 방향: Make the cheap gate alias-aware (including native StyleX and JSX-runtime/css-prop needles), then parse only candidates. Pass the merged alias table to a gate API or perform the measured substring precheck in TypeScript.
PLG-03 (P0, WRONG) Rsbuild serves stale CSS after same-length/shorter edits and across plugin instances
근거: packages/rsbuild-plugin/src/plugin.ts:68 declares module-global globalCss; line 315 updates it only when globalCss.length < css.length; line 199 returns the cached value. red→tan or deleting declarations cannot update it, and a second build in the same process inherits the first build's longest sheet.
수정 방향: Remove the length heuristic/module global. Resolve CSS from getCss(...) at CSS load time and reset build state at setup/build boundaries; compare content, not length.
PLG-04 (P0, NONDET) Webpack and Rsbuild can snapshot shared CSS before extraction completes
근거: Webpack css-loader.ts:5-8 returns getCss whenever the generated CSS module is first built; the only final hook (plugin.ts:311-321) writes a disk file after compilation and cannot rewrite emitted assets. Prewarm is conditional and only scans src/, excluding included libraries. Rsbuild returns globalCss from its CSS transform and has no generateBundle equivalent. Vite…
수정 방향: Add a completion coordinator/final asset rewrite, or pre-extract the exact full compiled graph including dynamic and include modules before any CSS module is served.
권장 (26)
INF-06 (P1, WRONG) codeExtractWithoutSourceMap generates a source map — 재검증 후 P0→P1: 출력은 정상, source map을 불필요하게 생성
근거: public wrapper at bindings/devup-ui-wasm/src/lib.rs:572-596 calls SourceMapMode::Generate; declaration names it codeExtractWithoutSourceMap (pkg/index.d.ts:27).
수정 방향: pass SourceMapMode::Skip and add a JS-boundary assertion that map is absent.
INF-07 (P1, WRONG) Resolver errors are silently converted to unresolved modules
근거: call_module_resolver uses .ok()? for JS call/reflection/conversion (bindings/.../lib.rs:473-490).
수정 방향: distinguish resolver-returned null from thrown/malformed results and propagate contextual JS errors.
INF-08 (P1, CRASH) Rust panics can become opaque WASM traps
근거: no installed panic hook or catch boundary; optional console_error_panic_hook is unused.
수정 방향: remove reachable panic paths and install a documented panic hook; do not claim ordinary error conversion for panics.
NXT-04 (P1, WRONG) CSS loader reuses one app's coordinator port for every app
근거: css-loader.ts:23-30 stores a single cachedPort, not a map keyed by port-file path. css-port-cache.ts started two coordinators and observed {firstResult:"FIRST",secondResult:"FIRST",expectedSecond:"SECOND"}.
수정 방향: Cache by canonical port-file path, or re-read the tiny port file per compilation with health validation.
NXT-05 (P1, CRASH) Source loader cannot recover after coordinator restart
근거: loader.ts:29,43-49 permanently caches the first port for a path; connection errors at loader.ts:121 go straight to the callback. loader-stale-port.ts rewrote the same port file after restart and observed ECONNREFUSED instead of the second coordinator's output.
수정 방향: On connect failure, evict the cached port, re-read/health-check the current file, and retry within a bounded deadline.
NXT-06 (P1, ERR-gap) Coordinator HTTP clients can hang a build indefinitely
근거: loader.ts:78-124 and css-loader.ts:33-66 set no request/connect timeout, deadline, or abort handling. The coordinator's internal maxWaitMs cannot help if the process accepts a connection but never responds.
수정 방향: Set bounded request deadlines, destroy timed-out sockets, and return a contextual loader error; retry only idempotent startup/restart failures.
NXT-07 (P1, WRONG) One process-global coordinator makes two in-process apps mutually exclusive
근거: coordinator.ts:172,350-359 closes any previous server regardless of app/port path. two-coordinators.ts observed first health 200, then first ECONNREFUSED after starting the second while the second remained 200.
수정 방향: Registry coordinators by normalized project/dist key with reference-counted close; never replace an unrelated instance.
NXT-09 (P1, WRONG) Deleted or renamed files can leave active global CSS forever
근거: startup imports old sheet/maps (plugin.ts:240-250). Coordinator exposes only /health, /css, and /extract (coordinator.ts:396-663); there is no remove/invalidate operation or fresh-state rebuild in dev. A deleted file never posts its old filename again, so its stored atoms/globalCss remain.
수정 방향: Track the live module set and delete a file's sheet/map contribution on invalidation/removal; validate persisted state against current files at startup.
NXT-12 (P1, PERF) Production prewarm extracts unreachable files and can fail on dead source
근거: prewarm.ts:58-64,73-80 explicitly adds every graph source file, not just route-reachable files; plugin.ts:387-426 synchronously reads/extracts each without a per-file reachability check or fallback. plugin.test.ts:1033-1082 locks this behavior.
수정 방향: Prewarm the proven compiled closure plus specifically discovered MDX/template/package dependencies; add an explicit opt-in for conservative whole-tree prewarm rather than making it the default.
NXT-14 (P1, WRONG) Persisted sheet/class/file maps are restored non-transactionally
근거: one try imports sheet, then class map, then file map (plugin.ts:244-250). If class/file JSON is missing or corrupt after sheet import, the catch leaves a mixed in-memory state. Writes are separate files (coordinator.ts:573-578) and are not an atomic multi-file transaction.
수정 방향: Read and parse every snapshot first, validate a shared generation/version, then import all; write via generation directories plus atomic pointer/rename.
근거: incomplete buckets resolve after quiet time or maxWaitMs and still return HTTP 200 (coordinator.ts:319-342); base completion similarly fails open (coordinator.ts:229-259). Tests explicitly expect partial CSS at coordinator.test.ts:1380-1411,1544-1634.
수정 방향: In production, fail the CSS loader/build with missing filenames instead of serving partial output. Keep a separately labeled dev-only fallback if necessary.
NXT-19 (P1, WRONG) Turbopack does not transform MDX source files
근거: source rule *.{tsx,ts,jsx,js,mjs} at plugin.ts:573 excludes .mdx; prewarm.ts:7 excludes .mdx. The extra exclusion string passed at plugin.ts:265 does not add a loader rule. Devup components/compat APIs authored directly in MDX can therefore reach runtime placeholders.
수정 방향: Add an MDX-aware post-transform path/rule proven against Next's MDX loader ordering, and include MDX in graph/prewarm discovery.
PLG-05 (P1, WRONG) include package names are unsafe raw regular expressions
근거: createNodeModulesExcludeRegex interpolates names without regex escaping. Probe: include:['foo.bar'] incorrectly included node_modules/fooXbar; include:['pkg'] also included node_modules/@scope/pkg; foo+bar failed to include the literal package. Windows and Bun/pnpm store paths otherwise worked.
수정 방향: Parse the package segment after each node_modules, compare exact normalized package names, or escape every regex token and anchor unscoped/scoped package boundaries separately. Precompute once per plugin.
PLG-06 (P1, CRASH) Modern module extensions and MDX fall through untransformed
근거: filter-resolver-probe.ts: Vite/webpack/Rsbuild and import-graph accept only ts/tsx/js/jsx/mjs; Bun additionally skips ordinary local .js. All omit .mts, .cts, .cjs, raw .mdx; import graph omits the same modern TS modules. Devup placeholders or aliased APIs remain in emitted code.
수정 방향: Share one explicit extension set across transform filters, graph enumeration, resolver, and entry filtering. Add MDX integration after MDX compilation (not against raw MDX syntax).
PLG-07 (P1, WRONG) Removed/renamed modules leave stale styles during development
근거: Vite watchChange handles only devup.json; webpack persists sheet/class/file maps but has no deletion hook; Rsbuild/Bun register no removal handling. codeExtract removes/replaces styles only when called for the same filename; a deleted filename is never called again.
수정 방향: Add an engine remove-file API, call it on delete/rename, invalidate the corresponding generated CSS module, and persist the pruned maps in webpack watch mode.
PLG-08 (P1, WRONG) Theme inheritance dependencies are not watched; deletion is ignored
근거: loadDevupConfig* recursively reads extends, but plugins register/watch only devupFile. Vite hot hooks require the top-level file still to exist; webpack captures existence at apply; Rsbuild/Bun have no config watch hook. Editing a base theme or deleting devup.json leaves old CSS/types/default theme.
수정 방향: Return resolved config dependencies from the loader, register all of them, and treat deletion as an empty config followed by CSS/type regeneration and reload.
PLG-10 (P1, NONDET) Rsbuild cold-start CSS directory creation races its first write
근거: packages/rsbuild-plugin/src/plugin.ts:96-103 starts mkdir(cssDir) and writeFile(cssDir/devup-ui.css) in the same Promise.all. Vite has the same issue documented and fixed sequentially at vite plugin.ts:248-255.
수정 방향: Await recursive mkdir before starting any write, matching Vite.
PLG-11 (P1, WRONG) Resolver and graph ignore inherited tsconfig paths
근거: Probe fixture used tsconfig.json extending a base config containing baseUrl/paths; createModuleResolver('@base/value',...) was unresolved. readPathAliases parses only the immediate JSON (import-graph.ts:867-912). Atom/collapse reach and build-time imported constants therefore diverge from the bundler.
수정 방향: Resolve the tsconfig inheritance chain with cycle detection and TS-compatible merge semantics (or use the installed get-tsconfig/resolver stack).
PLG-12 (P1, WRONG) Module resolver selects the wrong conditional-export branch
근거: Probe package exports { browser:'./browser.js', import:'./import.js' }; resolver returned import.js. conditionTarget uses fixed import,module,default,require,node and has no client/server/development/react-server condition input (import-graph.ts:1007-1091).
수정 방향: Accept bundler-provided conditions and preserve exports object order; preferably delegate to each bundler resolver rather than maintain a partial resolver.
PLG-13 (P1, WRONG) Atom-hoist graph roots miss real source layouts
근거: Vite detects both src and app for file seeding but atomHoist picks only sourceDirs[0]; webpack and Rsbuild hardcode <cwd>/src. Root-level app/, projects with both roots, custom source roots, and included libraries are omitted.
수정 방향: Build a graph over all bundler entries and their resolved closures, or accept configured source roots; never pick only the first existing conventional directory.
근거: defaults are resolved when plugin constructors run; webpack graph/loader use process.cwd() rather than compiler.context; Rsbuild uses process.cwd(); only Vite's resolver/scan uses config.root, while its config/data paths still do not. Monorepo configs launched from a parent read/write the wrong devup.json/df and resolve imports under the wrong project.
수정 방향: Delay normalization until setup/configResolved and resolve every relative option against the bundler's resolved root/context; pass that root to loaders/resolvers explicitly.
PLG-19 (P1, ERR-gap) Config errors are either silent or recurse without a bound
근거: malformed JSON returns {} with no diagnostic (load-config.ts:48-57), silently clearing theme output. Recursive extends has no visited set (86-139), so a→b→a recurses until stack exhaustion/promise growth.
수정 방향: Return typed parse/load errors with file paths; track a canonical-path stack and report a readable cycle.
PLG-20 (P1, WRONG) Bun ignores imported build-time dependency tracking
근거: Bun loadSourceFile discards codeExtract().dependencies; Vite, webpack and Rsbuild register the same values with their watcher APIs. Changes to imported token/style modules can leave transformed output and CSS stale.
수정 방향: Return/register dependency watch files using Bun's current plugin API, or ensure the imported modules are explicit graph dependencies that invalidate the transformed importer.
PLG-21 (P1, WRONG) Rsbuild's shared CSS cache group silently does nothing under default splitChunks
근거: injector initializes optimization but only adds the group when splitChunks is already an object (plugin.ts:227-250). Its unit test explicitly confirms missing/false remains undefined. The option docs promise one shared CSS chunk so atom hoisting deduplicates MPA entries.
수정 방향: Compose a valid splitChunks object when absent; handle false explicitly (error or documented opt-out) instead of silently disabling the promised behavior.
PLG-22 (P1, CRASH) Library-mode demo emits runtime placeholders without documenting the consumer requirement
근거: allowed apps/vite-lib build produced dist/index.js importing Box/Flex/Text and rendering them directly because DevupUI({extractCss:false}) skips transform. It works only if every consuming app lists the published library in include; plugin READMEs do not document this library publishing/consuming contract.
수정 방향: Document and test the two supported modes: precompiled library with emitted CSS, or intentionally uncompiled library requiring consumer include. Consider emitting package metadata/helper config to make the latter automatic.
PLG-09 (P2, WRONG) Empty themes leave stale generated declaration files
근거: Vite plugin.ts:232-243, webpack plugin.ts:124-132, and Rsbuild plugin.ts:81-91 only write theme.d.ts when interfaceCode is truthy; none removes or overwrites a previous declaration when tokens disappear. Bun always writes and is not affected.
수정 방향: Always overwrite theme.d.ts with the generated empty augmentation, or remove it atomically when no interface is needed.
선택 (11)
NXT-10 (P2, MISMATCH) debug is a public option but does nothing under Turbopack
근거: DevupUIBasePluginOptions exposes debug (plugin-utils/shared.ts:96-107), but Turbo destructuring omits it (plugin.ts:134-145) and the loaded WASM functions omit setDebug (plugin.ts:209-228). Webpack receives it via {...options}.
수정 방향: Destructure debug, include it in the setup cache key, and call setDebug(debug ?? false) before imports/extraction.
NXT-11 (P2, WRONG) Turbopack does not watch theme data files
근거: coordinator mode returns at loader.ts:145-194 after adding only the port file; theme/state dependencies are added only in non-coordinator mode (loader.ts:209-227). css-loader.ts:83-120 likewise fetches coordinator CSS without adding themeFile. Theme registration occurs only during config setup (plugin.ts:252-257).
수정 방향: Add the resolved config and all extends files as loader dependencies; reload/register theme and invalidate generated CSS when they change.
NXT-13 (P2, PERF) Shared RSC/client modules are re-extracted in development
근거: dev has no prewarmed-output cache (plugin.ts:371), and every POST invokes WASM (coordinator.ts:462-483). Next may compile a shared module separately in server and client graphs and does not guarantee order: https://nextjs.org/docs/app/guides/server-and-client-boundary
수정 방향: Add a bounded content-hash transform cache in the coordinator and invalidate by source/options/dependency changes.
NXT-18 (P2, WRONG) Graph/prewarm planning failures are silently downgraded
근거: the broad catch at plugin.ts:352-359 discards the exception and silently leaves identity canonical mapping, no atom hoist, and idle completion. No warning reaches Next's terminal/overlay.
수정 방향: Catch only recognized optional-resolution failures; otherwise throw in production or emit a contextual warning naming the file/phase and disabled guarantees.
근거: plugin.ts:573 and prewarm.ts:7 omit .mts, .cts, and .cjs, although imported application modules can use those extensions.
수정 방향: Extend rule, graph parser, and prewarm filters together; add fixtures for each extension to prevent coordinator waits on untransformable graph members.
PLG-23 (P2, PERF) Atom-hoist setup reparses every source tree twice (webpack can do a third pass)
근거: plugin-utils explicitly supports one buildStaticImportGraph shared by builders (import-graph.ts:80-116), but Vite/webpack/Rsbuild call buildCanonicalMap then computeFileReach without graph, causing two full list/read/parse/resolve passes. Webpack then listSourceFiles+read+codeExtract prewarm.
수정 방향: Build one graph and pass it to both consumers; reuse its sorted files/external imports for prewarm.
PLG-24 (P2, PERF) Bun performs quadratic, blocking stylesheet I/O
근거: every matching module synchronously serializes and writes the entire growing global sheet (bun plugin.ts:92-107). With N modules, early rules are rewritten O(N) times and synchronous disk I/O blocks all module loading.
수정 방향: Serve CSS from the loader and write once in an end/finalization hook; for runtime watch, debounce/coalesce revisions without synchronous writes.
근거: Vite seed and atom prepass, webpack graph/prewarm, and Rsbuild atom prepass use empty catches or comments only. A resolver/parser/I/O defect silently falls back to arrival-order IDs or disables requested atomHoist, producing a successful but different build.
수정 방향: Fail builds for requested atomHoist/setup invariants; for optional seeding fallback, emit one structured warning with the root cause and deterministic impact.
PLG-29 (P2, MISMATCH) Bun unconditionally enables debug output
근거: packages/bun-plugin/src/plugin.ts:125 calls setDebug(true) and exposes no debug option, unlike all sibling plugins whose default is false. This changes class naming/output size and makes Bun output differ for identical source.
수정 방향: Add debug?:boolean default false and set it on every initialization.
NXT-17 (P3, MAINT) Exit cleanup claims to flush async writes but cannot await them
근거: plugin.ts:488-491 calls synchronous close from process.on('exit'); coordinator.ts:673-680 fire-and-forgets flushPendingWrites(). Node's exit event cannot keep the event loop alive for asynchronous work: https://nodejs.org/api/process.html#event-exit
수정 방향: Await drain during a pre-exit lifecycle hook/build completion path; keep exit cleanup synchronous and best-effort only.
PLG-28 (P3, PERF) createNodeModulesExcludeRegex is rebuilt for every transformed module
근거: Vite line 530 and Rsbuild line 260 call the regex factory inside hot transform callbacks although include is immutable.
수정 방향: Compile once when constructing/setuping the plugin (after fixing PLG-05).
vite/webpack/next/rsbuild/bun 플러그인과 WASM 바인딩의 문제들입니다. 확인 예: Bun이 생성한 CSS를 버림, Bun의 사전 검사가 alias·StyleX 파일을 건너뜀, Rsbuild가 오래된 CSS를 제공.
전체 계획과 결정 사항은 추적 이슈(#682)에 있습니다. 조사 기준 커밋:
77daad74(현재 maind0b84255).발견 항목
심각도: P0 = 흔한 사용에서 조용히 틀리거나 크래시, P1 = 흔한 패턴이 명시적 에러로 막히거나 드물게 조용히 틀림, P2 = 드문 경우·도구/문서 불일치, P3 = 있으면 좋음.
필수 (4)
packages/bun-plugin/src/plugin.ts:74-80,127-138resolves every generated stylesheet into{ contents: '', loader: 'js' }. Bun 1.4.2 officially supports anonLoadresult withloader: 'css', and JavaScript CSS imports are combined into emitted.css; the plugin instead turns the import into an empty JS module.loader:'css'for Bun.build, while using a separate runtime/test behavior if runtime imports truly need an empty module. Add an end-to-endBun.buildassertion for the emitted CSS asset.compat-detection-probe.ts:hasDevupUI(...,'@devup-ui/react')returnedfalsefor@emotion/styled,@emotion/react/jsx-runtime, classic Emotion css-prop pragma, and@stylexjs/stylex. DirectcodeExtracttransformed Emotion styled and StyleX successfully, proving the gate—not the extractor—drops them. Published placeholders/aliases then execute at runtime or remain unc…packages/rsbuild-plugin/src/plugin.ts:68declares module-globalglobalCss; line 315 updates it only whenglobalCss.length < css.length; line 199 returns the cached value.red→tanor deleting declarations cannot update it, and a second build in the same process inherits the first build's longest sheet.getCss(...)at CSS load time and reset build state at setup/build boundaries; compare content, not length.css-loader.ts:5-8returnsgetCsswhenever the generated CSS module is first built; the only final hook (plugin.ts:311-321) writes a disk file after compilation and cannot rewrite emitted assets. Prewarm is conditional and only scanssrc/, excluding included libraries. Rsbuild returnsglobalCssfrom its CSS transform and has nogenerateBundleequivalent. Vite…권장 (26)
bindings/devup-ui-wasm/src/lib.rs:572-596callsSourceMapMode::Generate; declaration names itcodeExtractWithoutSourceMap(pkg/index.d.ts:27).SourceMapMode::Skipand add a JS-boundary assertion thatmapis absent.call_module_resolveruses.ok()?for JS call/reflection/conversion (bindings/.../lib.rs:473-490).console_error_panic_hookis unused.css-loader.ts:23-30stores a singlecachedPort, not a map keyed by port-file path.css-port-cache.tsstarted two coordinators and observed{firstResult:"FIRST",secondResult:"FIRST",expectedSecond:"SECOND"}.loader.ts:29,43-49permanently caches the first port for a path; connection errors atloader.ts:121go straight to the callback.loader-stale-port.tsrewrote the same port file after restart and observedECONNREFUSEDinstead of the second coordinator's output.loader.ts:78-124andcss-loader.ts:33-66set no request/connect timeout, deadline, or abort handling. The coordinator's internalmaxWaitMscannot help if the process accepts a connection but never responds.coordinator.ts:172,350-359closes any previous server regardless of app/port path.two-coordinators.tsobserved first health200, then firstECONNREFUSEDafter starting the second while the second remained200.plugin.ts:240-250). Coordinator exposes only/health,/css, and/extract(coordinator.ts:396-663); there is no remove/invalidate operation or fresh-state rebuild in dev. A deleted file never posts its old filename again, so its stored atoms/globalCss remain.prewarm.ts:58-64,73-80explicitly adds every graph source file, not just route-reachable files;plugin.ts:387-426synchronously reads/extracts each without a per-file reachability check or fallback.plugin.test.ts:1033-1082locks this behavior.tryimports sheet, then class map, then file map (plugin.ts:244-250). If class/file JSON is missing or corrupt after sheet import, the catch leaves a mixed in-memory state. Writes are separate files (coordinator.ts:573-578) and are not an atomic multi-file transaction.maxWaitMsand still return HTTP 200 (coordinator.ts:319-342); base completion similarly fails open (coordinator.ts:229-259). Tests explicitly expect partial CSS atcoordinator.test.ts:1380-1411,1544-1634.*.{tsx,ts,jsx,js,mjs}atplugin.ts:573excludes.mdx;prewarm.ts:7excludes.mdx. The extra exclusion string passed atplugin.ts:265does not add a loader rule. Devup components/compat APIs authored directly in MDX can therefore reach runtime placeholders.includepackage names are unsafe raw regular expressionscreateNodeModulesExcludeRegexinterpolates names without regex escaping. Probe:include:['foo.bar']incorrectly includednode_modules/fooXbar;include:['pkg']also includednode_modules/@scope/pkg;foo+barfailed to include the literal package. Windows and Bun/pnpm store paths otherwise worked.node_modules, compare exact normalized package names, or escape every regex token and anchor unscoped/scoped package boundaries separately. Precompute once per plugin.filter-resolver-probe.ts: Vite/webpack/Rsbuild and import-graph accept only ts/tsx/js/jsx/mjs; Bun additionally skips ordinary local.js. All omit.mts,.cts,.cjs, raw.mdx; import graph omits the same modern TS modules. Devup placeholders or aliased APIs remain in emitted code.watchChangehandles onlydevup.json; webpack persists sheet/class/file maps but has no deletion hook; Rsbuild/Bun register no removal handling.codeExtractremoves/replaces styles only when called for the same filename; a deleted filename is never called again.loadDevupConfig*recursively readsextends, but plugins register/watch onlydevupFile. Vite hot hooks require the top-level file still to exist; webpack captures existence atapply; Rsbuild/Bun have no config watch hook. Editing a base theme or deletingdevup.jsonleaves old CSS/types/default theme.packages/rsbuild-plugin/src/plugin.ts:96-103startsmkdir(cssDir)andwriteFile(cssDir/devup-ui.css)in the samePromise.all. Vite has the same issue documented and fixed sequentially atvite plugin.ts:248-255.tsconfig.jsonextending a base config containingbaseUrl/paths;createModuleResolver('@base/value',...)was unresolved.readPathAliasesparses only the immediate JSON (import-graph.ts:867-912). Atom/collapse reach and build-time imported constants therefore diverge from the bundler.get-tsconfig/resolver stack).{ browser:'./browser.js', import:'./import.js' }; resolver returnedimport.js.conditionTargetuses fixedimport,module,default,require,nodeand has no client/server/development/react-server condition input (import-graph.ts:1007-1091).srcandappfor file seeding but atomHoist picks onlysourceDirs[0]; webpack and Rsbuild hardcode<cwd>/src. Root-levelapp/, projects with both roots, custom source roots, and included libraries are omitted.process.cwd()rather thancompiler.context; Rsbuild usesprocess.cwd(); only Vite's resolver/scan usesconfig.root, while its config/data paths still do not. Monorepo configs launched from a parent read/write the wrongdevup.json/dfand resolve imports under the wrong project.{}with no diagnostic (load-config.ts:48-57), silently clearing theme output. Recursiveextendshas no visited set (86-139), soa→b→arecurses until stack exhaustion/promise growth.loadSourceFilediscardscodeExtract().dependencies; Vite, webpack and Rsbuild register the same values with their watcher APIs. Changes to imported token/style modules can leave transformed output and CSS stale.splitChunksoptimizationbut only adds the group whensplitChunksis already an object (plugin.ts:227-250). Its unit test explicitly confirms missing/false remains undefined. The option docs promise one shared CSS chunk so atom hoisting deduplicates MPA entries.falseexplicitly (error or documented opt-out) instead of silently disabling the promised behavior.apps/vite-libbuild produceddist/index.jsimportingBox/Flex/Textand rendering them directly becauseDevupUI({extractCss:false})skips transform. It works only if every consuming app lists the published library ininclude; plugin READMEs do not document this library publishing/consuming contract.include. Consider emitting package metadata/helper config to make the latter automatic.plugin.ts:232-243, webpackplugin.ts:124-132, and Rsbuildplugin.ts:81-91only writetheme.d.tswheninterfaceCodeis truthy; none removes or overwrites a previous declaration when tokens disappear. Bun always writes and is not affected.theme.d.tswith the generated empty augmentation, or remove it atomically when no interface is needed.선택 (11)
debugis a public option but does nothing under TurbopackDevupUIBasePluginOptionsexposesdebug(plugin-utils/shared.ts:96-107), but Turbo destructuring omits it (plugin.ts:134-145) and the loaded WASM functions omitsetDebug(plugin.ts:209-228). Webpack receives it via{...options}.debug, include it in the setup cache key, and callsetDebug(debug ?? false)before imports/extraction.loader.ts:145-194after adding only the port file; theme/state dependencies are added only in non-coordinator mode (loader.ts:209-227).css-loader.ts:83-120likewise fetches coordinator CSS without addingthemeFile. Theme registration occurs only during config setup (plugin.ts:252-257).extendsfiles as loader dependencies; reload/register theme and invalidate generated CSS when they change.plugin.ts:371), and every POST invokes WASM (coordinator.ts:462-483). Next may compile a shared module separately in server and client graphs and does not guarantee order: https://nextjs.org/docs/app/guides/server-and-client-boundaryplugin.ts:352-359discards the exception and silently leaves identity canonical mapping, no atom hoist, and idle completion. No warning reaches Next's terminal/overlay.plugin.ts:573andprewarm.ts:7omit.mts,.cts, and.cjs, although imported application modules can use those extensions.buildStaticImportGraphshared by builders (import-graph.ts:80-116), but Vite/webpack/Rsbuild callbuildCanonicalMapthencomputeFileReachwithoutgraph, causing two full list/read/parse/resolve passes. Webpack thenlistSourceFiles+read+codeExtractprewarm.bun plugin.ts:92-107). With N modules, early rules are rewritten O(N) times and synchronous disk I/O blocks all module loading.atomHoist, producing a successful but different build.packages/bun-plugin/src/plugin.ts:125callssetDebug(true)and exposes no debug option, unlike all sibling plugins whose default is false. This changes class naming/output size and makes Bun output differ for identical source.debug?:booleandefault false and set it on every initialization.plugin.ts:488-491calls synchronousclosefromprocess.on('exit');coordinator.ts:673-680fire-and-forgetsflushPendingWrites(). Node'sexitevent cannot keep the event loop alive for asynchronous work: https://nodejs.org/api/process.html#event-exitexitcleanup synchronous and best-effort only.createNodeModulesExcludeRegexis rebuilt for every transformed moduleincludeis immutable.