Skip to content

compile().warnings() is unreachable from a real build: 50 addWarning call sites, no Metro consumer #424

Description

@YevheniiKotyrlo

The compiler records warnings that nothing in a real build reads

StylesheetBuilder.addWarning accumulates three channels — properties, values, functions — reachable through compile(css).warnings(). In src/compiler/declarations.ts there are 47 addWarning("value", …) call sites feeding the values channel, plus 3 addWarning("property", …).

None of them reach anybody running expo start.

$ grep -rn "\.warnings()" src --include=*.ts --include=*.tsx | grep -v __tests__
src/compiler/compiler.ts:202:    warnings: () => builder.getWarnings(),
src/jest/index.ts:46:          warnings: compiled.warnings(),

compiler.ts:202 is the definition. src/jest/index.ts:46 is the only consumer, and it is behind a flag:

const debugDefault = Boolean(
  process.env.REACT_NATIVE_CSS_TEST_DEBUG &&
    typeof process.env.NODE_OPTIONS === "string" &&
    process.env.NODE_OPTIONS.includes("--inspect"),
);

src/metro/metro-transformer.ts — the path every real build takes — calls .stylesheet() and nothing else:

const productionJS = compile(css, {
  ...config.reactNativeCSS,
  filename: filePath,
  projectRoot: projectRoot,
}).stylesheet();

So the observable behaviour of an unsupported declaration is: nothing happens, silently. The compiler knew, wrote it down, and threw the note away.

Why it matters

The values channel is where "this value has no React Native equivalent" is recorded. That is exactly the class of problem a developer cannot diagnose from the outside — the class name is present, the rule compiled, and one declaration quietly did nothing. A build-time log line is the difference between a five-minute fix and an afternoon.

Reproduction

import { compile } from "react-native-css/compiler";

console.log(compile(`.a { float: left; }`).warnings());
// { properties: [ 'float' ] }

Run the same CSS through Metro and nothing is printed; the file transforms successfully.

Not a regression, and not new

This is how the channel has always worked — I am not reporting a break. I hit it while adding a warning for a new drop in #411 and found the new entries were as unreachable as the existing 47.

Possible shapes

  1. metro-transformer.ts calls .warnings() after .stylesheet() and logs a summary through Metro's reporter.
  2. The same, off by default behind a reactNativeCSS option, so an existing project does not suddenly gain a wall of output.
  3. Nothing, if the channel is meant only as a compiler API for tooling — in which case it is worth saying so, because the call sites read as user-facing diagnostics.

Happy to do (1) or (2) if you have a preference. I did not fold it into #411 because it is orthogonal to that fix and predates it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    auto-triagedIssue has been automatically triaged by the auto-triage workflowconfirmedBug reproduced and confirmed by triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions