Conversation
|
ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughRefactors Uniwind’s bundler: central UniwindBundlerConfig, platform Tailwind→CSS compilers, Metro/Vite adapter entries under bundler/adapters, moved constants/types to src/common, path/alias and Jest mappings, widespread import/type-only cleanup, and test/build wiring updates. ChangesBundler Architecture & Configuration Refactor
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts (1)
77-85:⚠️ Potential issue | 🟠 Major | ⚡ Quick winResync immediately when the Uniwind context changes.
Lines 77-85 resubscribe on
uniwindContextchanges but never recompute the current value. After a provider swap, this hook keeps the old context's variable values untilThemeorVariablesemits again.Suggested fix
useLayoutEffect(() => { const updateValue = () => setValue(getCSSVariable(nameRef.current, uniwindContext)) + updateValue() const dispose = UniwindListener.subscribe( updateValue, [StyleDependency.Theme, StyleDependency.Variables], )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts` around lines 77 - 85, The hook currently resubscribes on uniwindContext change but doesn't recompute the variable value immediately; inside the useLayoutEffect in useCSSVariable, call updateValue() (which uses getCSSVariable(nameRef.current, uniwindContext) and setValue) right before creating the subscription (or immediately after) so the value reflects the new uniwindContext immediately, then create the UniwindListener.subscribe(...) and return dispose as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/uniwind/src/bundler/adapters/metro/transformer.ts`:
- Around line 33-35: The path comparisons in the isCss check and the
metro-injected.js check are brittle across platforms; normalize and resolve both
sides before comparing. Concretely, compute normalized absolute paths (e.g.,
cssEntryPath = path.normalize(path.resolve(process.cwd(),
config.uniwind.cssEntryFile)) and normalizedFilePath =
path.normalize(path.resolve(projectRoot, filePath))) and use strict equality
(cssEntryPath === normalizedFilePath) instead of joining then comparing; for the
injected file replace the endsWith('/components/web/metro-injected.js') test
with the same normalized-resolved comparison against
path.normalize(path.resolve(projectRoot, 'components', 'web',
'metro-injected.js')) so matching works on Windows and in monorepos while
keeping the options.type !== 'asset' check.
In `@packages/uniwind/src/bundler/adapters/vite/vite.ts`:
- Around line 81-84: The injected Uniwind.__reinit call is concatenated directly
to the transformed module text (variable code), which can break when the
original ends with comments or relies on ASI; update the return in the
normalizedId branch so you add an explicit statement boundary before calling
Uniwind.__reinit (e.g., prepend a semicolon or newline+semicolon to the injected
snippet) when building the code string that uses
bundlerConfig.stringifiedThemes, ensuring the injected call is always a separate
statement.
In `@packages/uniwind/src/bundler/config.ts`:
- Around line 67-69: The stringifiedThemes getter emits raw single-quoted theme
names which can break when a theme contains quotes or backslashes; replace its
manual quoting with a proper JSON serialization by returning
JSON.stringify(this.themes) from the stringifiedThemes getter (i.e., update the
stringifiedThemes getter that references this.themes to use JSON.stringify to
produce a safe JS array literal).
- Around line 45-47: The cssPath getter currently uses process.cwd() which
breaks monorepos; update UniwindBundlerConfig to accept and store an explicit
project root (e.g., projectRoot or root) via its constructor or factory, replace
process.cwd() in the cssPath getter with that stored property so cssPath returns
path.join(this.projectRoot, this.config.cssEntryFile), and ensure callers that
construct UniwindBundlerConfig are updated to pass the correct app root.
In `@packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts`:
- Around line 24-26: The code that builds serializedScopedVars interpolates
scopedVarsName directly into a JS string literal, which breaks/permits injection
if the key contains " or \; update the serialization in compileNativeCSS.ts so
scopedVarsName is escaped before embedding (e.g., use
JSON.stringify(scopedVarsName) or an escape helper) when constructing
serializedScopedVars, keeping the same output shape (`"name": ({ ... }),`) and
preserving the trailing comma; ensure you apply this change where
serializedScopedVars is computed so both quotes and backslashes are properly
escaped.
In `@packages/uniwind/src/bundler/css-compiler/compileTailwind.ts`:
- Line 8: The compileTailwind code currently uses blocking I/O via
fs.readFileSync when loading bundlerConfig.cssPath; change this to non-blocking
fs.promises.readFile and await the result (e.g., await
fs.promises.readFile(bundlerConfig.cssPath, 'utf-8')) so the function does not
block the event loop—ensure the surrounding function (e.g., compileTailwind) is
async or already awaits this call and replace the sync variable assignment
(const css = fs.readFileSync(...)) with the awaited promise-based read.
In `@packages/uniwind/tsconfig.json`:
- Around line 13-19: tsconfig.json contains broken path aliases "@/metro" and
"@/utils/*" that point to non-existent targets; update the "paths" section so
"@/metro" either points to the actual metro adapter entry (replace the current
target) or remove the "@/metro" alias and import via "@/bundler/adapters/metro",
and either remove or correct the "@/utils/*" alias to point to a real utils
directory (or create a re-export shim if you prefer keeping the alias); ensure
the "@/bundler/*" mapping remains correct and run type-checking to confirm the
fixes.
---
Outside diff comments:
In `@packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts`:
- Around line 77-85: The hook currently resubscribes on uniwindContext change
but doesn't recompute the variable value immediately; inside the useLayoutEffect
in useCSSVariable, call updateValue() (which uses
getCSSVariable(nameRef.current, uniwindContext) and setValue) right before
creating the subscription (or immediately after) so the value reflects the new
uniwindContext immediately, then create the UniwindListener.subscribe(...) and
return dispose as before.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a1fba412-f33d-4235-8134-8f7501a66b47
📒 Files selected for processing (69)
packages/uniwind/build.config.tspackages/uniwind/jest.config.native.jspackages/uniwind/jest.config.web.jspackages/uniwind/src/bundler/adapters/metro/index.d.tspackages/uniwind/src/bundler/adapters/metro/index.tspackages/uniwind/src/bundler/adapters/metro/metro.tspackages/uniwind/src/bundler/adapters/metro/patches.tspackages/uniwind/src/bundler/adapters/metro/resolvers.tspackages/uniwind/src/bundler/adapters/metro/transformer.tspackages/uniwind/src/bundler/adapters/vite/index.d.tspackages/uniwind/src/bundler/adapters/vite/index.tspackages/uniwind/src/bundler/adapters/vite/vite.tspackages/uniwind/src/bundler/artifacts/css/extraUtilities.tspackages/uniwind/src/bundler/artifacts/css/index.tspackages/uniwind/src/bundler/artifacts/css/insets.tspackages/uniwind/src/bundler/artifacts/css/overwrite.tspackages/uniwind/src/bundler/artifacts/css/themes.tspackages/uniwind/src/bundler/artifacts/css/variants.tspackages/uniwind/src/bundler/artifacts/dts.tspackages/uniwind/src/bundler/config.tspackages/uniwind/src/bundler/css-compiler/compileCSS.tspackages/uniwind/src/bundler/css-compiler/compileNativeCSS.tspackages/uniwind/src/bundler/css-compiler/compileTailwind.tspackages/uniwind/src/bundler/css-compiler/compileWebCSS.tspackages/uniwind/src/bundler/css-compiler/index.tspackages/uniwind/src/bundler/css-processor/addMetaToStylesTemplate.tspackages/uniwind/src/bundler/css-processor/color.tspackages/uniwind/src/bundler/css-processor/css.tspackages/uniwind/src/bundler/css-processor/functions.tspackages/uniwind/src/bundler/css-processor/index.tspackages/uniwind/src/bundler/css-processor/mq.tspackages/uniwind/src/bundler/css-processor/processor.tspackages/uniwind/src/bundler/css-processor/rn.tspackages/uniwind/src/bundler/css-processor/serialize.tspackages/uniwind/src/bundler/css-processor/types.tspackages/uniwind/src/bundler/css-processor/units.tspackages/uniwind/src/bundler/css-processor/utils.tspackages/uniwind/src/bundler/css-processor/var.tspackages/uniwind/src/bundler/css-visitor/function-visitor.tspackages/uniwind/src/bundler/css-visitor/index.tspackages/uniwind/src/bundler/css-visitor/rule-visitor.tspackages/uniwind/src/bundler/css-visitor/visitor.tspackages/uniwind/src/bundler/logger.tspackages/uniwind/src/bundler/types.tspackages/uniwind/src/common/consts.tspackages/uniwind/src/components/web/rnw.tspackages/uniwind/src/core/config/config.common.tspackages/uniwind/src/core/config/config.native.tspackages/uniwind/src/core/config/config.tspackages/uniwind/src/core/listener.tspackages/uniwind/src/core/native/runtime.tspackages/uniwind/src/core/native/store.tspackages/uniwind/src/core/types.tspackages/uniwind/src/core/web/cssListener.tspackages/uniwind/src/hoc/withUniwind.native.tsxpackages/uniwind/src/hooks/useCSSVariable/useCSSVariable.tspackages/uniwind/src/hooks/useUniwind.tspackages/uniwind/src/index.tspackages/uniwind/src/metro/compileVirtual.tspackages/uniwind/src/metro/index.tspackages/uniwind/src/metro/injectThemes.tspackages/uniwind/src/metro/metro-transformer.tspackages/uniwind/src/metro/processor/index.tspackages/uniwind/src/metro/utils/index.tspackages/uniwind/src/types.tspackages/uniwind/src/utils/stringifyThemes.tspackages/uniwind/tests/e2e/global-setup.tspackages/uniwind/tests/setup.native.tspackages/uniwind/tsconfig.json
💤 Files with no reviewable changes (8)
- packages/uniwind/src/metro/utils/index.ts
- packages/uniwind/src/utils/stringifyThemes.ts
- packages/uniwind/src/metro/injectThemes.ts
- packages/uniwind/src/metro/processor/index.ts
- packages/uniwind/src/metro/index.ts
- packages/uniwind/src/types.ts
- packages/uniwind/src/metro/compileVirtual.ts
- packages/uniwind/src/metro/metro-transformer.ts
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (2)
packages/uniwind/src/bundler/adapters/metro/transformer.ts (1)
35-37:⚠️ Potential issue | 🟠 Major | ⚡ Quick winNormalize/resolve paths before matching special files.
Current comparisons are brittle across Windows and some monorepo layouts, which can skip both CSS compilation and
metro-injected.jshandling.Proposed fix
- const isCss = options.type !== 'asset' && path.join(process.cwd(), config.uniwind.cssEntryFile) === path.join(projectRoot, filePath) + const normalizedFilePath = path.normalize(path.resolve(projectRoot, filePath)) + const cssEntryPath = path.normalize(path.resolve(process.cwd(), config.uniwind.cssEntryFile)) + const injectedPath = path.normalize(path.resolve(projectRoot, 'components', 'web', 'metro-injected.js')) + const isCss = options.type !== 'asset' && normalizedFilePath === cssEntryPath - if (filePath.endsWith('/components/web/metro-injected.js')) { + if (normalizedFilePath === injectedPath) {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/uniwind/src/bundler/adapters/metro/transformer.ts` around lines 35 - 37, The path comparisons are brittle; normalize and resolve both sides before matching: for the CSS check (isCss) resolve/normalize config.uniwind.cssEntryFile against process.cwd() and resolve/normalize projectRoot + filePath (or resolve filePath) before comparing, and for the special file check resolve/normalize the target string (e.g., path.join('components','web','metro-injected.js')) and compare it against a resolved/normalized filePath instead of using filePath.endsWith(...); update the logic around the isCss computation and the if that references '/components/web/metro-injected.js' to use these normalized/resolved paths so comparisons work cross-platform and in monorepos.packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts (1)
24-26:⚠️ Potential issue | 🟠 Major | ⚡ Quick winEscape
scopedVarsNamebefore embedding generated JS.
scopedVarsNameis interpolated raw into a quoted key, so keys containing"or\can produce invalid/generated-injectable code.Proposed fix
const serializedScopedVars = Object.entries(scopedVars) - .map(([scopedVarsName, scopedVars]) => `"${scopedVarsName}": ({ ${scopedVars} }),`) + .map(([scopedVarsName, scopedVars]) => `${JSON.stringify(scopedVarsName)}: ({ ${scopedVars} }),`) .join('')🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts` around lines 24 - 26, The generated JS embeds scopedVarsName raw into a quoted key which can break if the name contains `"` or `\`; update the serializedScopedVars construction in compileNativeCSS.ts (the const serializedScopedVars) to escape scopedVarsName before embedding (e.g., use JSON.stringify(scopedVarsName) or explicitly replace `\` and `"` with `\\`/`\"`) so the produced key is a valid JS string literal and cannot inject invalid code.
🧹 Nitpick comments (3)
context.md (2)
157-158: ⚡ Quick winConsider varying sentence structure.
Two consecutive sentences begin with "Web wrappers", which slightly impacts readability.
✨ Suggested improvement
- Web wrappers import from `react-native` as resolved by bundler aliases. -- Web wrappers map `className` to RNW CSS style markers through `toRNWClassName`. -- Web wrappers pass generated `dataSet` so data attribute variants can match. +- The `className` prop is mapped to RNW CSS style markers through `toRNWClassName`. +- Generated `dataSet` is passed so data attribute variants can match.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@context.md` around lines 157 - 158, Two consecutive sentences both starting with "Web wrappers" reduce readability; rephrase one to vary sentence structure and improve flow. For example, transform the first sentence that mentions mapping into an active clause referencing the function name toRNWClassName (e.g., "toRNWClassName maps className to RNW CSS style markers") and rework the second to lead with the outcome or purpose mentioning dataSet (e.g., "They also pass the generated dataSet so data attribute variants can match"), or combine them into a single sentence that includes both toRNWClassName and dataSet for clarity.
120-121: ⚡ Quick winConsider varying sentence structure.
Three consecutive sentences begin with "Vite", which slightly impacts readability. Consider varying the structure for better flow.
✨ Suggested improvement
- Vite aliases `react-native` to Uniwind web components, except imports from Uniwind internals resolve back to `react-native-web`. -- Vite replaces RNW `createOrderedCSSStyleSheet` with Uniwind's ordered stylesheet implementation. -- Vite uses Lightning CSS with `UniwindCSSVisitor`. -- Vite generates artifacts on `buildStart` and `generateBundle`. +- The RNW `createOrderedCSSStyleSheet` is replaced with Uniwind's ordered stylesheet implementation. +- Lightning CSS is used with `UniwindCSSVisitor`. +- Artifacts are generated on `buildStart` and `generateBundle`.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@context.md` around lines 120 - 121, The three consecutive sentences that begin with "Vite" (the lines stating "Vite uses Lightning CSS with `UniwindCSSVisitor`." and "Vite generates artifacts on `buildStart` and `generateBundle`.") make the paragraph repetitive; rephrase one or two of them to vary sentence openings and improve flow (for example, start one sentence with the technology or a gerund/passive phrase like "Using Lightning CSS, Vite..." or "Artifacts are generated during `buildStart` and `generateBundle`"), or combine related ideas into a single sentence to avoid repeating the subject.packages/uniwind/src/bundler/adapters/vite/vite.ts (1)
87-91: ⚡ Quick winAvoid regenerating the same artifacts in both build hooks.
Vite calls
buildStartduring both serve and build, while output-generation hooks likegenerateBundleonly run during build. With the current wiring,vite buildwill executebundlerConfig.generateArtifacts(cssArtifactPath)twice for the same output. Prefer running it inbuildStartonly forserveand ingenerateBundleonly forbuild, or guard it with a once-per-run flag. (vite.dev)♻️ Possible adjustment
export const uniwind = (config: UniwindConfig): Plugin => { const bundlerConfig = UniwindBundlerConfig.fromViteConfig(config) + let command: 'serve' | 'build' return { name: 'uniwind', enforce: 'pre', + config: (_, env) => { + command = env.command + return { + css: { + transformer: 'lightningcss', + lightningcss: { + visitor: bundlerConfig.cssVisitor, + }, + }, + optimizeDeps: { + exclude: ['uniwind', 'react-native'], + esbuildOptions: { + plugins: [{ + name: 'uniwind-esbuild-plugin', + setup: build => { + build.onResolve( + { filter: /^\.\/createOrderedCSSStyleSheet$/ }, + args => { + if (normalizePath(args.importer).includes('react-native-web/dist/exports/StyleSheet')) { + return { path: styleSheetPath } + } + }, + ) + }, + }], + }, + }, + resolve: { + alias: [ + { + find: /^react-native$/, + replacement: componentPath, + customResolver: { + resolveId(_, importer) { + if (importer !== undefined && normalizePath(importer).includes('uniwind/dist')) { + return this.resolve('react-native-web') + } + + return componentPath + }, + }, + }, + ], + }, + } + }, - config: () => ({ - css: { - transformer: 'lightningcss', - lightningcss: { - visitor: bundlerConfig.cssVisitor, - }, - }, - optimizeDeps: { - exclude: ['uniwind', 'react-native'], - esbuildOptions: { - plugins: [{ - name: 'uniwind-esbuild-plugin', - setup: build => { - build.onResolve( - { filter: /^\.\/createOrderedCSSStyleSheet$/ }, - args => { - if (normalizePath(args.importer).includes('react-native-web/dist/exports/StyleSheet')) { - return { path: styleSheetPath } - } - }, - ) - }, - }], - }, - }, - resolve: { - alias: [ - { - find: /^react-native$/, - replacement: componentPath, - customResolver: { - resolveId(_, importer) { - if (importer !== undefined && normalizePath(importer).includes('uniwind/dist')) { - return this.resolve('react-native-web') - } - - return componentPath - }, - }, - }, - ], - }, - }), transform: (code, id) => { const normalizedId = normalizePath(id) if (normalizedId.includes('uniwind/dist') && normalizedId.includes('config/config.js')) { return { code: `${code}\n;Uniwind.__reinit(() => ({}), ${bundlerConfig.stringifiedThemes})`, } } }, buildStart: async () => { - await bundlerConfig.generateArtifacts(cssArtifactPath) + if (command === 'serve') { + await bundlerConfig.generateArtifacts(cssArtifactPath) + } }, generateBundle: async () => { - await bundlerConfig.generateArtifacts(cssArtifactPath) + if (command === 'build') { + await bundlerConfig.generateArtifacts(cssArtifactPath) + } }, } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/uniwind/src/bundler/adapters/vite/vite.ts` around lines 87 - 91, The plugin currently calls bundlerConfig.generateArtifacts(cssArtifactPath) in both buildStart and generateBundle causing duplicate work; modify the Vite hooks so artifacts are generated only once per run by either 1) adding a module-scoped boolean flag (e.g., artifactsGenerated) that buildStart and generateBundle check/set before calling bundlerConfig.generateArtifacts(cssArtifactPath), or 2) moving the call to buildStart for dev/serve and to generateBundle only for actual builds (use the presence of this.getWatchMode() or hook semantics to distinguish serve vs build); update the buildStart and generateBundle handlers (the functions named buildStart and generateBundle) accordingly to ensure a single invocation per process.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@context.md`:
- Line 82: Update the phrasing in the documentation string containing
Uniwind.setTheme(theme | 'system') to hyphenate the compound adjective: change
"system adaptive light/dark" to "system-adaptive light/dark" so the description
reads that Uniwind.setTheme switches explicit themes or returns to
system-adaptive light/dark.
- Line 117: The phrase in the documentation for uniwind(config) uses "pre Vite
plugin" and should be hyphenated; update the text that says "`uniwind(config)`
returns a pre Vite plugin." to read "`uniwind(config)` returns a pre-Vite
plugin." ensuring the compound adjective "pre-Vite" is hyphenated wherever this
wording appears.
- Around line 129-130: Update the phrasing describing scoped CSS variables to
use correct compound modifier hyphenation: change the phrase "theme and platform
scoped variables" (in the description of scopedVars) to "theme- and
platform-scoped variables" so that "platform-scoped" is hyphenated and the
shared "scoped" modifier is applied correctly to both "theme" and "platform".
---
Duplicate comments:
In `@packages/uniwind/src/bundler/adapters/metro/transformer.ts`:
- Around line 35-37: The path comparisons are brittle; normalize and resolve
both sides before matching: for the CSS check (isCss) resolve/normalize
config.uniwind.cssEntryFile against process.cwd() and resolve/normalize
projectRoot + filePath (or resolve filePath) before comparing, and for the
special file check resolve/normalize the target string (e.g.,
path.join('components','web','metro-injected.js')) and compare it against a
resolved/normalized filePath instead of using filePath.endsWith(...); update the
logic around the isCss computation and the if that references
'/components/web/metro-injected.js' to use these normalized/resolved paths so
comparisons work cross-platform and in monorepos.
In `@packages/uniwind/src/bundler/css-compiler/compileNativeCSS.ts`:
- Around line 24-26: The generated JS embeds scopedVarsName raw into a quoted
key which can break if the name contains `"` or `\`; update the
serializedScopedVars construction in compileNativeCSS.ts (the const
serializedScopedVars) to escape scopedVarsName before embedding (e.g., use
JSON.stringify(scopedVarsName) or explicitly replace `\` and `"` with `\\`/`\"`)
so the produced key is a valid JS string literal and cannot inject invalid code.
---
Nitpick comments:
In `@context.md`:
- Around line 157-158: Two consecutive sentences both starting with "Web
wrappers" reduce readability; rephrase one to vary sentence structure and
improve flow. For example, transform the first sentence that mentions mapping
into an active clause referencing the function name toRNWClassName (e.g.,
"toRNWClassName maps className to RNW CSS style markers") and rework the second
to lead with the outcome or purpose mentioning dataSet (e.g., "They also pass
the generated dataSet so data attribute variants can match"), or combine them
into a single sentence that includes both toRNWClassName and dataSet for
clarity.
- Around line 120-121: The three consecutive sentences that begin with "Vite"
(the lines stating "Vite uses Lightning CSS with `UniwindCSSVisitor`." and "Vite
generates artifacts on `buildStart` and `generateBundle`.") make the paragraph
repetitive; rephrase one or two of them to vary sentence openings and improve
flow (for example, start one sentence with the technology or a gerund/passive
phrase like "Using Lightning CSS, Vite..." or "Artifacts are generated during
`buildStart` and `generateBundle`"), or combine related ideas into a single
sentence to avoid repeating the subject.
In `@packages/uniwind/src/bundler/adapters/vite/vite.ts`:
- Around line 87-91: The plugin currently calls
bundlerConfig.generateArtifacts(cssArtifactPath) in both buildStart and
generateBundle causing duplicate work; modify the Vite hooks so artifacts are
generated only once per run by either 1) adding a module-scoped boolean flag
(e.g., artifactsGenerated) that buildStart and generateBundle check/set before
calling bundlerConfig.generateArtifacts(cssArtifactPath), or 2) moving the call
to buildStart for dev/serve and to generateBundle only for actual builds (use
the presence of this.getWatchMode() or hook semantics to distinguish serve vs
build); update the buildStart and generateBundle handlers (the functions named
buildStart and generateBundle) accordingly to ensure a single invocation per
process.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f6a86f50-ca6f-4933-bcd7-4302fdb8f667
📒 Files selected for processing (83)
context.mdpackages/uniwind/.oxlintrc.jsonpackages/uniwind/build.config.tspackages/uniwind/src/bundler/adapters/metro/patches.tspackages/uniwind/src/bundler/adapters/metro/resolvers.tspackages/uniwind/src/bundler/adapters/metro/transformer.tspackages/uniwind/src/bundler/adapters/vite/vite.tspackages/uniwind/src/bundler/artifacts/css/extraUtilities.tspackages/uniwind/src/bundler/css-compiler/compileCSS.tspackages/uniwind/src/bundler/css-compiler/compileNativeCSS.tspackages/uniwind/src/bundler/css-compiler/compileTailwind.tspackages/uniwind/src/bundler/css-compiler/compileWebCSS.tspackages/uniwind/src/bundler/css-processor/addMetaToStylesTemplate.tspackages/uniwind/src/bundler/css-processor/color.tspackages/uniwind/src/bundler/css-processor/css.tspackages/uniwind/src/bundler/css-processor/functions.tspackages/uniwind/src/bundler/css-processor/mq.tspackages/uniwind/src/bundler/css-processor/processor.tspackages/uniwind/src/bundler/css-processor/types.tspackages/uniwind/src/bundler/css-processor/units.tspackages/uniwind/src/bundler/css-processor/var.tspackages/uniwind/src/bundler/css-visitor/function-visitor.tspackages/uniwind/src/bundler/css-visitor/rule-visitor.tspackages/uniwind/src/bundler/css-visitor/visitor.tspackages/uniwind/src/components/ScopedTheme/ScopedTheme.native.tsxpackages/uniwind/src/components/native/ActivityIndicator.tsxpackages/uniwind/src/components/native/Button.tsxpackages/uniwind/src/components/native/FlatList.tsxpackages/uniwind/src/components/native/Image.tsxpackages/uniwind/src/components/native/ImageBackground.tsxpackages/uniwind/src/components/native/InputAccessoryView.tsxpackages/uniwind/src/components/native/KeyboardAvoidingView.tsxpackages/uniwind/src/components/native/Modal.tsxpackages/uniwind/src/components/native/Pressable.tsxpackages/uniwind/src/components/native/RefreshControl.tsxpackages/uniwind/src/components/native/SafeAreaView.tsxpackages/uniwind/src/components/native/ScrollView.tsxpackages/uniwind/src/components/native/SectionList.tsxpackages/uniwind/src/components/native/Switch.tsxpackages/uniwind/src/components/native/Text.tsxpackages/uniwind/src/components/native/TextInput.tsxpackages/uniwind/src/components/native/TouchableHighlight.tsxpackages/uniwind/src/components/native/TouchableNativeFeedback.tsxpackages/uniwind/src/components/native/TouchableOpacity.tsxpackages/uniwind/src/components/native/TouchableWithoutFeedback.tsxpackages/uniwind/src/components/native/View.tsxpackages/uniwind/src/components/native/VirtualizedList.tsxpackages/uniwind/src/components/native/useAccentColor.tspackages/uniwind/src/components/native/useStyle.tspackages/uniwind/src/components/web/ActivityIndicator.tsxpackages/uniwind/src/components/web/Button.tsxpackages/uniwind/src/components/web/FlatList.tsxpackages/uniwind/src/components/web/Image.tsxpackages/uniwind/src/components/web/ImageBackground.tsxpackages/uniwind/src/components/web/KeyboardAvoidingView.tsxpackages/uniwind/src/components/web/Modal.tsxpackages/uniwind/src/components/web/Pressable.tsxpackages/uniwind/src/components/web/RefreshControl.tsxpackages/uniwind/src/components/web/SafeAreaView.tsxpackages/uniwind/src/components/web/ScrollView.tsxpackages/uniwind/src/components/web/SectionList.tsxpackages/uniwind/src/components/web/Switch.tsxpackages/uniwind/src/components/web/Text.tsxpackages/uniwind/src/components/web/TextInput.tsxpackages/uniwind/src/components/web/TouchableHighlight.tsxpackages/uniwind/src/components/web/TouchableOpacity.tsxpackages/uniwind/src/components/web/TouchableWithoutFeedback.tsxpackages/uniwind/src/components/web/View.tsxpackages/uniwind/src/components/web/VirtualizedList.tsxpackages/uniwind/src/core/config/config.common.tspackages/uniwind/src/core/config/config.native.tspackages/uniwind/src/core/config/config.tspackages/uniwind/src/core/native/store.tspackages/uniwind/src/core/types.tspackages/uniwind/src/core/web/getWebStyles.tspackages/uniwind/src/hoc/types.tspackages/uniwind/src/hoc/withUniwind.native.tsxpackages/uniwind/src/hoc/withUniwind.tsxpackages/uniwind/src/hooks/useCSSVariable/getVariableValue.native.tspackages/uniwind/src/hooks/useCSSVariable/useCSSVariable.tspackages/uniwind/src/hooks/useResolveClassNames.tspackages/uniwind/src/hooks/useUniwind.tspackages/uniwind/tsconfig.json
✅ Files skipped from review due to trivial changes (70)
- packages/uniwind/src/components/native/useStyle.ts
- packages/uniwind/src/components/native/useAccentColor.ts
- packages/uniwind/src/components/web/ImageBackground.tsx
- packages/uniwind/src/bundler/css-processor/units.ts
- packages/uniwind/src/components/ScopedTheme/ScopedTheme.native.tsx
- packages/uniwind/src/hooks/useResolveClassNames.ts
- packages/uniwind/src/components/web/TextInput.tsx
- packages/uniwind/src/hooks/useCSSVariable/getVariableValue.native.ts
- packages/uniwind/src/bundler/css-processor/functions.ts
- packages/uniwind/src/components/web/TouchableOpacity.tsx
- packages/uniwind/src/components/native/ImageBackground.tsx
- packages/uniwind/src/components/native/View.tsx
- packages/uniwind/src/bundler/artifacts/css/extraUtilities.ts
- packages/uniwind/src/components/native/ActivityIndicator.tsx
- packages/uniwind/src/hoc/withUniwind.native.tsx
- packages/uniwind/src/components/native/KeyboardAvoidingView.tsx
- packages/uniwind/src/components/native/Button.tsx
- packages/uniwind/src/components/native/TouchableWithoutFeedback.tsx
- packages/uniwind/src/components/native/ScrollView.tsx
- packages/uniwind/src/components/web/Image.tsx
- packages/uniwind/src/components/web/View.tsx
- packages/uniwind/src/components/web/VirtualizedList.tsx
- packages/uniwind/src/bundler/css-visitor/visitor.ts
- packages/uniwind/src/components/web/Button.tsx
- packages/uniwind/src/hoc/types.ts
- packages/uniwind/src/components/native/Image.tsx
- packages/uniwind/src/components/native/TouchableOpacity.tsx
- packages/uniwind/src/components/native/TouchableHighlight.tsx
- packages/uniwind/src/components/web/KeyboardAvoidingView.tsx
- packages/uniwind/src/components/native/VirtualizedList.tsx
- packages/uniwind/src/components/native/Text.tsx
- packages/uniwind/src/components/native/SectionList.tsx
- packages/uniwind/src/core/native/store.ts
- packages/uniwind/src/components/web/ScrollView.tsx
- packages/uniwind/src/components/native/SafeAreaView.tsx
- packages/uniwind/src/components/native/InputAccessoryView.tsx
- packages/uniwind/src/hoc/withUniwind.tsx
- packages/uniwind/src/bundler/css-processor/css.ts
- packages/uniwind/src/bundler/css-processor/processor.ts
- packages/uniwind/src/bundler/css-visitor/rule-visitor.ts
- packages/uniwind/src/components/web/ActivityIndicator.tsx
- packages/uniwind/src/components/web/Switch.tsx
- packages/uniwind/src/bundler/css-processor/var.ts
- packages/uniwind/src/components/web/TouchableWithoutFeedback.tsx
- packages/uniwind/src/components/native/TouchableNativeFeedback.tsx
- packages/uniwind/src/components/web/FlatList.tsx
- packages/uniwind/src/components/native/FlatList.tsx
- packages/uniwind/src/bundler/css-compiler/compileTailwind.ts
- packages/uniwind/src/bundler/css-visitor/function-visitor.ts
- packages/uniwind/src/components/web/RefreshControl.tsx
- packages/uniwind/src/components/native/TextInput.tsx
- packages/uniwind/src/components/native/Pressable.tsx
- packages/uniwind/src/bundler/adapters/metro/patches.ts
- packages/uniwind/src/components/web/SafeAreaView.tsx
- packages/uniwind/src/components/web/SectionList.tsx
- packages/uniwind/src/components/web/Modal.tsx
- packages/uniwind/src/core/web/getWebStyles.ts
- packages/uniwind/src/components/native/Modal.tsx
- packages/uniwind/src/components/native/RefreshControl.tsx
- packages/uniwind/src/core/config/config.common.ts
- packages/uniwind/src/components/web/Pressable.tsx
- packages/uniwind/src/bundler/css-processor/addMetaToStylesTemplate.ts
- packages/uniwind/.oxlintrc.json
- packages/uniwind/src/core/config/config.ts
- packages/uniwind/src/bundler/css-processor/mq.ts
- packages/uniwind/src/hooks/useUniwind.ts
- packages/uniwind/src/bundler/adapters/metro/resolvers.ts
- packages/uniwind/src/components/native/Switch.tsx
- packages/uniwind/src/components/web/TouchableHighlight.tsx
- packages/uniwind/src/components/web/Text.tsx
🚧 Files skipped from review as they are similar to previous changes (8)
- packages/uniwind/src/core/config/config.native.ts
- packages/uniwind/src/bundler/css-compiler/compileCSS.ts
- packages/uniwind/src/bundler/css-processor/color.ts
- packages/uniwind/src/bundler/css-processor/types.ts
- packages/uniwind/src/bundler/css-compiler/compileWebCSS.ts
- packages/uniwind/src/core/types.ts
- packages/uniwind/build.config.ts
- packages/uniwind/src/hooks/useCSSVariable/useCSSVariable.ts
|
|
||
| Shared runtime: | ||
|
|
||
| - `Uniwind.setTheme(theme | 'system')` switches explicit themes or returns to system adaptive light/dark. |
There was a problem hiding this comment.
Fix compound adjective hyphenation.
The compound adjective should be hyphenated for clarity: "system-adaptive light/dark" instead of "system adaptive light/dark".
📝 Proposed fix
-- `Uniwind.setTheme(theme | 'system')` switches explicit themes or returns to system adaptive light/dark.
+- `Uniwind.setTheme(theme | 'system')` switches explicit themes or returns to system-adaptive light/dark.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - `Uniwind.setTheme(theme | 'system')` switches explicit themes or returns to system adaptive light/dark. | |
| - `Uniwind.setTheme(theme | 'system')` switches explicit themes or returns to system-adaptive light/dark. |
🧰 Tools
🪛 LanguageTool
[grammar] ~82-~82: Use a hyphen to join words.
Context: ...hes explicit themes or returns to system adaptive light/dark. - `Uniwind.currentT...
(QB_NEW_EN_HYPHEN)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@context.md` at line 82, Update the phrasing in the documentation string
containing Uniwind.setTheme(theme | 'system') to hyphenate the compound
adjective: change "system adaptive light/dark" to "system-adaptive light/dark"
so the description reads that Uniwind.setTheme switches explicit themes or
returns to system-adaptive light/dark.
|
|
||
| Vite integration: | ||
|
|
||
| - `uniwind(config)` returns a pre Vite plugin. |
There was a problem hiding this comment.
Fix compound adjective hyphenation.
The compound adjective should be hyphenated: "pre-Vite plugin" instead of "pre Vite plugin".
📝 Proposed fix
-- `uniwind(config)` returns a pre Vite plugin.
+- `uniwind(config)` returns a pre-Vite plugin.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - `uniwind(config)` returns a pre Vite plugin. | |
| - `uniwind(config)` returns a pre-Vite plugin. |
🧰 Tools
🪛 LanguageTool
[grammar] ~117-~117: Use a hyphen to join words.
Context: ...tion: - uniwind(config) returns a pre Vite plugin. - Vite aliases `react-nativ...
(QB_NEW_EN_HYPHEN)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@context.md` at line 117, The phrase in the documentation for uniwind(config)
uses "pre Vite plugin" and should be hyphenated; update the text that says
"`uniwind(config)` returns a pre Vite plugin." to read "`uniwind(config)`
returns a pre-Vite plugin." ensuring the compound adjective "pre-Vite" is
hyphenated wherever this wording appears.
| - A `Style` record stores entries, breakpoint bounds, orientation, theme, RTL, native flag, dependencies, source index, class name, important properties, selector complexity, pseudo states, and data attributes. | ||
| - CSS variables live in `vars`; theme and platform scoped variables live in `scopedVars` with internal prefixes. |
There was a problem hiding this comment.
Fix compound modifier hyphens.
Two compound modifiers should be hyphenated for clarity and correctness.
📝 Proposed fix
-- A `Style` record stores entries, breakpoint bounds, orientation, theme, RTL, native flag, dependencies, source index, class name, important properties, selector complexity, pseudo states, and data attributes.
-- CSS variables live in `vars`; theme and platform scoped variables live in `scopedVars` with internal prefixes.
+- A `Style` record stores entries, breakpoint bounds, orientation, theme, RTL, native flag, dependencies, source index, class name, important properties, selector complexity, pseudo-states, and data attributes.
+- CSS variables live in `vars`; theme and platform-scoped variables live in `scopedVars` with internal prefixes.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - A `Style` record stores entries, breakpoint bounds, orientation, theme, RTL, native flag, dependencies, source index, class name, important properties, selector complexity, pseudo states, and data attributes. | |
| - CSS variables live in `vars`; theme and platform scoped variables live in `scopedVars` with internal prefixes. | |
| - A `Style` record stores entries, breakpoint bounds, orientation, theme, RTL, native flag, dependencies, source index, class name, important properties, selector complexity, pseudo-states, and data attributes. | |
| - CSS variables live in `vars`; theme and platform-scoped variables live in `scopedVars` with internal prefixes. |
🧰 Tools
🪛 LanguageTool
[grammar] ~129-~129: Use a hyphen to join words.
Context: ... properties, selector complexity, pseudo states, and data attributes. - CSS varia...
(QB_NEW_EN_HYPHEN)
[grammar] ~130-~130: Use a hyphen to join words.
Context: ...ables live in vars; theme and platform scoped variables live in scopedVars wi...
(QB_NEW_EN_HYPHEN)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@context.md` around lines 129 - 130, Update the phrasing describing scoped CSS
variables to use correct compound modifier hyphenation: change the phrase "theme
and platform scoped variables" (in the description of scopedVars) to "theme- and
platform-scoped variables" so that "platform-scoped" is hyphenated and the
shared "scoped" modifier is applied correctly to both "theme" and "platform".
Summary by CodeRabbit
New Features
Refactor
Chores