build(web): silence rollup's "use client" directive warnings in the nitro pass #166

Merged
enricobuehler merged 1 commits from build/web-silence-rollup-directive-warnings into main 2026-08-11 20:29:38 +00:00
Owner

The noise

Every web console build ends with a wall of rollup warnings — ~150 locally, ~800 in CI:

node_modules/framer-motion/dist/es/utils/use-force-update.mjs (1:0): Module level directives
cause errors when bundled, "use client" in ".../use-force-update.mjs" was ignored.

They all come from one place: the Nitro server bundle. The vite client and ssr passes are clean — the warnings start immediately after Building Nitro Server (preset: bun).

Why

web/vite.config.ts sets noExternals: true on nitroV2Plugin, so rollup re-bundles the entire dependency tree into the server output. Every React package that ships a "use client" banner — @tanstack/react-router, radix-ui, framer-motion under @unom/ui — then earns one MODULE_LEVEL_DIRECTIVE line. Nothing filtered them: vite's ignore-list is only CIRCULAR_DEPENDENCY / THIS_IS_UNDEFINED, and nitro's own onwarn adds just EVAL and source-map comments.

Why ignoring is correct

Not a bug being papered over. This bundle is the Bun/Nitro server, not an RSC module graph, and TanStack Start splits client from server with its own transform — nothing downstream ever consults the banner. "Ignored" is the right outcome; only the reporting was wrong.

The change

A rollupConfig.onwarn passed through nitroV2Plugin that drops MODULE_LEVEL_DIRECTIVE.

One trap worth knowing, and it's called out in the comment: supplying onwarn replaces nitro's own handler (nitro defu-merges ours over its default), so nitro's three filters — CIRCULAR_DEPENDENCY, EVAL, "Unsupported source map comment" — are restated. Drop them and that noise comes back instead.

Verification

  • bun run build: 148 directive lines → 0 (343 → 195 log lines), exit 0.
  • Diffed both logs: no delta beyond build timings, so nothing else got swallowed.
  • tsc --noEmit clean, biome check clean.

Not included

docs-site uses the same nitro plugin and @unom/ui, so it may carry the same noise — but it does not set noExternals, and its build currently fails before it ever reaches nitro, for an unrelated pre-existing reason:

[vite]: Rollup failed to resolve import "@scalar/api-reference-react/style.css?url"
from "docs-site/src/routes/api/index.tsx"

Left untouched rather than guessing at a fix I couldn't verify.

## The noise Every web console build ends with a wall of rollup warnings — ~150 locally, ~800 in CI: ``` node_modules/framer-motion/dist/es/utils/use-force-update.mjs (1:0): Module level directives cause errors when bundled, "use client" in ".../use-force-update.mjs" was ignored. ``` They all come from **one** place: the Nitro server bundle. The vite client and ssr passes are clean — the warnings start immediately after `Building Nitro Server (preset: bun)`. ## Why `web/vite.config.ts` sets `noExternals: true` on `nitroV2Plugin`, so rollup re-bundles the entire dependency tree into the server output. Every React package that ships a `"use client"` banner — `@tanstack/react-router`, `radix-ui`, `framer-motion` under `@unom/ui` — then earns one `MODULE_LEVEL_DIRECTIVE` line. Nothing filtered them: vite's ignore-list is only `CIRCULAR_DEPENDENCY` / `THIS_IS_UNDEFINED`, and nitro's own `onwarn` adds just `EVAL` and source-map comments. ## Why ignoring is correct Not a bug being papered over. This bundle is the Bun/Nitro **server**, not an RSC module graph, and TanStack Start splits client from server with its own transform — nothing downstream ever consults the banner. "Ignored" is the right outcome; only the reporting was wrong. ## The change A `rollupConfig.onwarn` passed through `nitroV2Plugin` that drops `MODULE_LEVEL_DIRECTIVE`. One trap worth knowing, and it's called out in the comment: supplying `onwarn` **replaces** nitro's own handler (nitro defu-merges ours over its default), so nitro's three filters — `CIRCULAR_DEPENDENCY`, `EVAL`, `"Unsupported source map comment"` — are restated. Drop them and that noise comes back instead. ## Verification - `bun run build`: **148 directive lines → 0** (343 → 195 log lines), exit 0. - Diffed both logs: no delta beyond build timings, so nothing else got swallowed. - `tsc --noEmit` clean, `biome check` clean. ## Not included `docs-site` uses the same nitro plugin and `@unom/ui`, so it may carry the same noise — but it does **not** set `noExternals`, and its build currently fails before it ever reaches nitro, for an unrelated pre-existing reason: ``` [vite]: Rollup failed to resolve import "@scalar/api-reference-react/style.css?url" from "docs-site/src/routes/api/index.tsx" ``` Left untouched rather than guessing at a fix I couldn't verify.
enricobuehler added 1 commit 2026-08-11 19:01:39 +00:00
build(web): silence rollup's "use client" directive warnings in the nitro pass
ci / bun-nix (pull_request) Successful in 31s
ci / docs-site (pull_request) Successful in 1m17s
ci / web (pull_request) Successful in 1m19s
ci / rust-arm64 (pull_request) Successful in 2m52s
ci / rust (pull_request) Successful in 7m9s
1009e14a44
The nitro server build re-bundles the whole dep tree (`noExternals: true`), so
every React package shipping a `"use client"` banner earns a MODULE_LEVEL_DIRECTIVE
warning — ~150 locally, ~800 in CI — which buries the warnings worth reading.

Ignoring the banner is correct rather than papered over: this bundle is the
Bun/Nitro server, not an RSC module graph, and TanStack Start splits client from
server with its own transform, so nothing downstream consults it.

Supplying `onwarn` replaces nitro's own handler, so its three filters
(CIRCULAR_DEPENDENCY, EVAL, "Unsupported source map comment") are restated.

Verified: `bun run build` drops from 148 such lines to 0 with no other log
delta; `tsc --noEmit` and `biome check` clean.
enricobuehler merged commit c946fcdcb5 into main 2026-08-11 20:29:38 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unom/punktfunk#166