Repository navigation
feat(metro): surface compiler warnings during a build - #430
Merged
danstepanov merged 2 commits intoOct 31, 2026
Merged
Conversation
This was referenced Aug 15, 2026
Contributor
Author
No device frameThe change is terminal output, and the description shows the block a build prints. This PR's cases —
|
| suite | fail on main |
fail here |
|---|---|---|
compiler/warnings.test.ts, new |
4 of 8 | 0 of 8 |
metro/metro-transformer.test.ts, new |
3 of 7 | 0 of 7 |
metro/warnings.test.ts, new |
does not load: src/metro/warnings.ts is not on main |
0 of 23 |
Run through the repo's jest on Ubuntu with Node 22.18.0.
YevheniiKotyrlo
added a commit
to YevheniiKotyrlo/react-native-css
that referenced
this pull request
Sep 22, 2026
This branch's first commit added a local logWarnings to the metro transformer, using picocolors directly. PR nativewind#430 adds the same feature to the same file through an extracted ./warnings module, so the two conflict and whichever lands second rewrites the other. Nothing here needs it: the compiler suites assert compiled.warnings() directly, and all 277 tests across the three border suites pass without it. It also left this branch changing a metro source with no metro test, which is the only reason that plane looked uncovered.
YevheniiKotyrlo
force-pushed
the
feat/metro-compiler-warnings
branch
from
October 11, 2026 12:36
156af1b to
61f8ef1
Compare
This was referenced Oct 11, 2026
YevheniiKotyrlo
marked this pull request as draft
October 17, 2026 07:38
YevheniiKotyrlo
marked this pull request as ready for review
October 17, 2026 12:05
YevheniiKotyrlo
marked this pull request as draft
October 27, 2026 21:19
YevheniiKotyrlo
force-pushed
the
feat/metro-compiler-warnings
branch
from
October 27, 2026 21:44
edf60a3 to
d23edad
Compare
YevheniiKotyrlo
marked this pull request as ready for review
October 27, 2026 22:44
sammoore
approved these changes
Oct 30, 2026
sammoore
left a comment
Contributor
There was a problem hiding this comment.
This is a solid improvement and default for consumers of react-native-css, but probably not something we want to ship in nativewind by default.
We should follow this up with a PR to nativewind (once a new version of react-native-css is published, so that it has the new warnings config key defined) that updates its call to withReactNativeCSS to configure warnings: 'none' by default.
cc @danstepanov
The compiler records every declaration it could not translate, but nothing read compile().warnings() during a build, so a dropped float or z-index: auto was silent. The Metro transformer now prints one block per CSS file: capped in summary mode, listed in full in verbose mode, and printed again only when the file's warnings change. The warnings option sets the level, and none silences it. lightningcss also warns about input it cannot parse, such as an unknown at-rule or pseudo-element. Those warnings reach a new syntax channel, kept apart from what React Native cannot express, and the block counts them as syntax warnings; this package's own @nativeMapping is not reported. Every recorded value is text, so CompilerWarnings.values is Record<string, string[]>; the one number, a percentage line-height, is recorded as the ratio it resolved to.
The section showed only dropped declarations, while the block also counts the warnings lightningcss gives for CSS it cannot parse and lists them under syntax:.
danstepanov
force-pushed
the
feat/metro-compiler-warnings
branch
from
October 31, 2026 01:11
8f005fa to
ffe65c8
Compare
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.
Problem
Closes #424.
On
main,compile(css).warnings()collects everything the compiler could not translate, butsrc/metro/metro-transformer.tscalls.stylesheet()and discards the rest of the compile result. So a droppedfloatorz-index: autois silent in every build.lightningcss also warns about input it cannot parse, such as an unknown at-rule or an unrecognised pseudo-element. lightningcss passes the rule through, the visitor finds nothing in it, and the rule disappears. The compiler never reads those warnings.
Solution
The transformer hands
.warnings()toreportCompilerWarnings, which prints one block per stylesheet:A file's block prints when its set of warnings changes, so an incremental rebuild that changes nothing about them stays quiet. Warnings never fail a build.
A
warningsoption onwithReactNativeCSSsets how much is printed. Issue compile().warnings() is unreachable from a real build: no Metro consumer #424 offered three shapes, and this PR implements option 1 with option 2's escape hatch:"summary"(the default) caps each channel at ten entries;"verbose"lists everything;"none"prints nothing.An opt-in default would leave the channel unseen by anyone who doesn't read the docs. If you'd rather it defaulted to
"none", that's a one-word change.lightningcss's parse warnings from the first pass go to a new
syntaxchannel. It is kept apart from what React Native cannot express, because the fix for it is in the author's stylesheet. The block counts them as syntax warnings and quotes each message, since a warning does not say what became of its rule: one message covers every repeat of a mistake, and with fix(compiler): recover from a rule lightningcss cannot parse #493's error recovery a media query whose feature value lightningcss refuses still compiles. This package's own@nativeMappingis not reported.Every recorded value is text, so
CompilerWarnings.valuesisRecord<string, string[]>. The one number the compiler recorded, a percentageline-height, is recorded as the ratio it resolved to.The README documents the option and the syntax warnings.
mainrefuses@react-nativeblocks outright, so the filter for this package's own at-rules covers only@nativeMapping.Tests
src/__tests__/metro/warnings.test.tsbuilds its fixtures from realcompile()results and covers:syntaxclause, which counts warnings rather than the rules they name;src/__tests__/metro/metro-transformer.test.tsdrives the transformer with a stand-in for Expo's transform worker, and checks that the level and the file reach the report. It also checks that web and non-CSS files never print.src/__tests__/compiler/warnings.test.tscovers thesyntaxchannel: an unknown at-rule and an unrecognised pseudo-element, each dropping its rule; a correctly spelled control; this package's own at-rule, and a misspelling of it, which is reported; and a repeated mistake.main, 7 of the 15 cases in the files that load there fail;warnings.test.tsexercises the new module. Each of 33 mutations fails its own cases.yarn example expo export --platform androidprints the block for the example'sglobal.css: 42 declarations from Tailwind's preflight.mainat 101.5 ms and 103.2 ms.Verification
Every
ci.ymljob, with this branch merged intomain: the Linux jobs on Ubuntu with Node 22.18.0,yarn testat 1379 passed, andbuild-ios-devon macOS with Xcode 27.1, whereci.ymlpins 26.6.This PR's cases, run on
mainand here: #430 (comment)Merge order
#379 changes the same lines of
metro/metro-transformer.ts; whichever lands second rebases.#493 is stacked on this branch.