Skip to content

We need to clean cache for TaskInput::FullBuild #10269

Description

@shulaoda

We only need to check whether a tsconfig file has changed.

Agreed — but for a bare TaskInput::FullBuild that check cannot be answered: changed_files() is empty by construction, so changed_tsconfig is false even when a tsconfig did change. Concrete case:

  1. Start dev with tsconfig.json v1 = { "compilerOptions": { "target": "es5" } }. It's valid JSON, so find_tsconfig loads it into the caches you listed (tsconfigs_raw / tsconfigs_built), but the per-file merge rejects it ("Rolldown only supports ES2015 and above"). The initial build fails → coordinator state = FullBuildFailed.
  2. The user fixes the tsconfig (v2, "target": "esnext"). The change event arrives while in FullBuildFailed, and that arm of handle_file_changes pushes a bare TaskInput::FullBuild — the changed file name is dropped here.
  3. The task runs: changed_files() is empty → changed_tsconfig is false → no cache clear. The full scan calls find_tsconfig, which answers from tsconfigs_built with v1, the merge fails again → back to FullBuildFailed.
  4. Every subsequent edit repeats 2–3, because in FullBuildFailed every change becomes a bare FullBuild. Pressing r goes through trigger_full_build, which also produces a bare FullBuild — same result. The dev server can't recover without a restart, even though the tsconfig on disk has been correct since step 2.

The same erasure happens on two other paths: trigger_full_build clears queued_tasks (dropping a queued Hmr { [tsconfig] }), and merge_with has FullBuild absorb other inputs and discard their file lists.

So the || self.input.requires_full_rebuild() isn't about clearing for unrelated full builds — it's the fallback for exactly the inputs whose file list has already been erased, where "did a tsconfig change" is unanswerable. Since full builds only happen at startup, on r, and in failure recovery, the extra clears are cheap. The alternative would be to keep the changed-file info alive through those three coordinator paths, but that's a much bigger change to the state machine.

Originally posted by @h-a-n-a in #10261 (comment)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions