Skip to content

Root tsconfig.node.json emits build artifacts next to every source — 5,838 files, none of them gitignored #3549

Description

@yinlianghui

Observation-class finding, tripped over while implementing #3515. Nothing a user hits today — no script anywhere runs this config. Recording it because it silently corrupts the commit of whoever does run it, and #3515's own body invites exactly that: it names the root tsconfig.node.json as "the only program that does contain" the four root setup files, which is a standing invitation to go run it.

What happens

tsconfig.node.json is three lines:

{
  "extends": "./tsconfig.base.json",
  "compilerOptions": { "lib": ["ES2020"] }
}

tsconfig.base.json sets "declaration": true, "declarationMap": true, "sourceMap": true — and no noEmit, no outDir. tsconfig.node.json also declares no include, so it defaults to the whole repository. Running it once, on a clean origin/main worktree:

$ ./node_modules/.bin/tsc -p tsconfig.node.json
...21616 errors...
$ git status --porcelain | wc -l
5838

5,838 emitted .js / .js.map / .d.ts / .d.ts.map files, written next to every input across packages/, apps/, examples/, scripts/ and the repo root.

Why it is worth recording

None of the emitted shapes is gitignored:

path git check-ignore
packages/components/src/lib/utils.js NOT ignored
packages/components/src/lib/utils.d.ts NOT ignored
vitest.setup.dom.js NOT ignored
scripts/vite-crypto-stub.js NOT ignored

So the next git add -A commits all of them. That is not hypothetical — it happened during #3515: a throwaway git add -A && git commit swallowed 402,729 insertions across 5,838 files. The knock-on is worse than the noise, because the emitted .js files carry JSX (they came from .tsx inputs), and rolldown then reads src/lib/utils.js in preference to src/lib/utils.tsx:

@object-ui/components:build: Build failed with 165 errors:
@object-ui/components:build: [builtin:vite-transform] Unexpected JSX expression
@object-ui/components:build:     ╭─[ src/context/gridFieldAuthoring.js:22:13 ]
@object-ui/components:build:     Help: JSX syntax is disabled and should be enabled via the parser options

A package that built fine ten minutes earlier now fails 165 times, and the failure reads as "your change broke the build" while having nothing to do with any change. Recovering means noticing that src/*.js files exist at all.

The repo already knows this shape. apps/console/tsconfig.node.json carries a comment saying so in as many words — "Left at the default it writes .js/.d.ts next to every input (apps/console/vite.config.js, scripts/vite-*.d.ts, …), and that untracked litter is a large part of why this project was never wired into a gate (objectui#3305)". The root file of the same name never got the same treatment.

Shape of a fix (not prescribing — the options differ in blast radius)

  1. "noEmit": true. Legal here because the project is standalone — nothing references it, so TS6310 does not apply. Same argument tsconfig.scripts.json and tsconfig.vitest-setup.json each make for themselves. Cheapest, and fixes the cause.
  2. An outDir under node_modules/.cache/tsc/, mirroring what apps/console/tsconfig.node.json was forced into. More machinery than this file needs, since it has no TS6310 constraint.
  3. Add the emitted shapes to .gitignore. Weakest: it treats the symptom, and it would also hide genuinely-stray artifacts from every other source.
  4. Delete the file, if nothing uses it. Measure first — editors may be picking it up as the ambient project for root-level files, which is the only reason it plausibly still exists.

Worth noting for whoever picks this up: the same run reports 21,616 errors. That backlog is not part of this finding, and #3515 explicitly rejected "widen the root config and give it a runner" (its route 3) for exactly that reason. Fixing the emit is independent of, and much smaller than, deciding what to do about the errors.

Related: #3515 (the coverage gap next door), #3494 / PR #3498 (tsconfig.scripts.json), #3305 (apps/console's node project and its litter), #3476 / PR #3513.


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions