The BuilderProgram and BuilderState system provides the infrastructure for incremental compilation in TypeScript. This system tracks what has changed between builds, caches diagnostics and type signatures, and determines which files need to be re-checked or re-emitted. It is the foundation for both the --incremental compiler flag and the tsc --build mode.
For information about the tsc --build command-line interface, see tsbuild Command. For information about up-to-date checking logic, see Up-To-Date Checking. For general information about the Program interface, see Program and Compilation.
Sources: src/compiler/builder.ts1-100 src/compiler/builderState.ts1-100
The builder system consists of two main layers:
BuilderState with cached semantic/emit diagnostics, emit tracking, and the associated Program instance.The following diagram illustrates the relationship between the core compiler entities and the builder state.
Sources: src/compiler/builder.ts7-92 src/compiler/builderState.ts38-98 src/compiler/builder.ts1557-1626
BuilderState tracks file-level information and dependencies. It is defined in src/compiler/builderState.ts62-98
| Property | Type | Purpose |
|---|---|---|
fileInfos | Map<Path, FileInfo> | Version and signature for each file |
referencedMap | ReadonlyManyToManyPathMap? | Which files reference which other files (module emit only) |
useFileVersionAsSignature | boolean? | Whether to use file version instead of computing d.ts signatures |
hasCalledUpdateShapeSignature | Set<Path>? | Files whose signatures have been updated this build |
oldSignatures | Map<Path, string | false>? | Previous signatures before update (for rollback) |
FileInfo Structure src/compiler/builderState.ts104-109:
Sources: src/compiler/builderState.ts62-98 src/compiler/builderState.ts104-109
BuilderProgramState extends BuilderState with incremental compilation features. It is defined in src/compiler/builder.ts209-263
The state maintains caches to avoid re-running the TypeChecker on files that haven't been affected by changes.
semanticDiagnosticsPerFile: Map<Path, readonly Diagnostic[]> src/compiler/builder.ts213emitDiagnosticsPerFile: Map<Path, readonly Diagnostic[]> src/compiler/builder.ts215affectedFilesPendingEmit: ReadonlyMap<Path, BuilderFileEmit> src/compiler/builder.ts158programEmitPending: BuilderFileEmit (used for --outFile scenarios) src/compiler/builder.ts162emitSignatures: Map<Path, EmitSignature> src/compiler/builder.ts172changedFilesSet: Set<Path> - Tracks files that the host reports as modified src/compiler/builder.ts219affectedFiles: readonly SourceFile[] - The current batch of files requiring re-check src/compiler/builder.ts223Sources: src/compiler/builder.ts136-263
The BuilderFileEmit enum tracks what types of output need to be generated for a file. It uses bitflags defined in src/compiler/builder.ts187-201:
| Flag | Value | Description |
|---|---|---|
Js | 1 << 0 | Emit JavaScript file |
JsMap | 1 << 1 | Emit JavaScript source map |
DtsErrors | 1 << 3 | Track/Emit declaration diagnostics |
DtsEmit | 1 << 4 | Emit .d.ts file |
All | AllJs | AllDts | Emit everything |
The function getBuilderFileEmit() src/compiler/builder.ts281-289 determines these flags based on CompilerOptions (e.g., declaration, sourceMap).
Sources: src/compiler/builder.ts187-289
The createBuilderProgramState() function src/compiler/builder.ts321-503 creates a new BuilderProgramState from a new Program and optional old state.
Sources: src/compiler/builder.ts321-503 src/compiler/builderState.ts295-297
The function getNextAffectedFile() src/compiler/builder.ts635-698 is the core of the incremental engine. It determines the next file that needs semantic analysis and/or emit.
referencedMap to find all files that import the changed module src/compiler/builderState.ts588-625.d.ts output). If the signature of a file hasn't changed, its consumers do not need to be re-checked src/compiler/builderState.ts431-460Sources: src/compiler/builder.ts635-698 src/compiler/builderState.ts375-625
Builder state is serialized to .tsbuildinfo files as JSON. This allows incremental builds to persist across different process invocations.
The BuildInfo object src/compiler/builder.ts1748-1842 includes:
BuilderState (file names, versions, and reference map).ReusableDiagnostic to save space and avoid circular references)..d.ts files.Diagnostics are serialized into ReusableDiagnostic objects src/compiler/builder.ts95-102 When the state is reloaded, convertToDiagnostics() src/compiler/builder.ts567-612 maps these back to full Diagnostic objects using the current Program's SourceFile instances.
Sources: src/compiler/builder.ts95-102 src/compiler/builder.ts1557-1842
The tsbuild infrastructure uses UpToDateStatus to determine if a project needs a rebuild without necessarily creating a full Program first.
| Status Type | Code Entity | Meaning |
|---|---|---|
UpToDate | UpToDateStatusType.UpToDate | Inputs are older than outputs |
OutOfDateWithSelf | UpToDateStatusType.OutOfDateWithSelf | A source file is newer than the output |
OutputMissing | UpToDateStatusType.OutputMissing | A required .js or .d.ts is missing |
TsVersionOutOfDate | UpToDateStatusType.TsVersionOutputOfDate | Compiler version changed |
Sources: src/compiler/tsbuild.ts10-38 src/compiler/tsbuild.ts41-174
Refresh this wiki