Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build .tsbuildinfo file when building using tsc --b #29813

Merged
merged 124 commits into from
Mar 8, 2019

Conversation

sheetalkamat
Copy link
Member

@sheetalkamat sheetalkamat commented Feb 7, 2019

  • When tsconfig specifies compiler options incremental file with .tsbuildinfo extension is emitted.
  • Composite projects indirectly specify incremental as true and its error to specify incremental as false in the composite project
  • If project specifies tsBuildInfoFile options, it uses the path specified by that to write the build information.
  • If project specifies out or outFile option, the outFileWithoutExtension.tsbuildinfo file is written next to output js file.
  • If project specified outDir, config files base file name with extension as .tsbuildinfo is written in outDir
  • Otherswise config files base file name with extension as .tsbuildinfo is written next to the config file
  • Generated file is json with type as BuildInfo shown below.
    export interface SourceFileInfo {
        // List of helpers in own source files emitted if no prepend is present
        helpers?: string[];
        prologues?: SourceFilePrologueInfo[];
    }

    export interface BundleFileInfo {
        sections: BundleFileSection[];
        sources?: SourceFileInfo;
    }

    export interface BundleBuildInfo {
        js?: BundleFileInfo;
        dts?: BundleFileInfo;
        commonSourceDirectory: string;
        sourceFiles: ReadonlyArray<string>;
    }

    export interface ProgramBuildInfo {
        fileInfos: MapLike<BuilderState.FileInfo>;
        options: CompilerOptions;
        referencedMap?: MapLike<string[]>;
        exportedModulesMap?: MapLike<string[]>;
        semanticDiagnosticsPerFile?: string[];
    }

    export interface BuildInfo {
        bundle?: BundleBuildInfo;
        program?: ProgramBuildInfo;
        version: string;
    }
  • Field program in buildInfo is Builder information so we can track the file changes since that version and build incrementally even without watch (that is emitting only affected files or getting errors only from changed/affected files). This should help us get perf similar to --w incremental builds even on subsequent invokes of build (In short we are serializing information of builder program that we keep in memory during incremental builds in --w mode). Also pulled 6c5ae93 to store semantic diagnostics though in --b scenario it will always be just file name as emit happens only if there are no errors.
  • Field bundle stores information to be able to emit into single file. This consists of different sections in file, eg. prologues, prepended file contents and their range's. When having project that references another project with prepend as true, this helps in faster emit when the referenced project changes but it doesn't change declaration file. Previously we would have to create program for project referencing changed output to generate new output, but this just uses section information from buildinfo file and emit new output without having to create program. This saves us time for creating program and checking errors (since the errors are not cached with --out as we cant tell change in declaration emit) and emitting all files. Having section also fixes issues like Duplicate "use strict" prologue in the generated output.  #25550 to generate better output.
  • if version of compiler does not match with version in the buildInfo file, it starts fresh build
  • The bundle information also contains internal declaration sections, so if project has stripInternal instead of concatenating whole string it skips out portions of internal and generates correct .d.ts
  • Currently the build info is generated and emitted in emitter but the information comes from two places, emitter itself (about --out) and the other from the program itself which is actually builder program (so one level of abstraction outside of the program). Open to suggestion if there is different way to write this information. Goal was to not write files multiple time (eg once by builder and once by emitter). Also another thought is that builder doesn't do anything or change much if the scenario is --out since any change means new emit and new diagnostics, so its ok to not store program information in this case and in other scenario there is nothing of importance in those other section than program so may be separating these two (reading and writing only modified field) might not be a bad decision. But will need to see how that goes.

Measured perf with updating LKG from master to build this branch using gulp local and then with this branch's build as LKG and using gulp local

Build With Master With this branch
After clean Finished 'local' after 52 s Finished 'local' after 36 s
Local change without --d change Finished 'local' after 44 s Finished 'local' after 25 s
Local change revert Finished 'local' after 44 s Finished 'local' after 21 s
…st manipulate output

Step 1: Update the verbose log to reflect it
@RyanCavanaugh
Copy link
Member

We can ship with this requirement and see how it goes

if (declarationMapText === text) return;
break;
default:
Debug.assertNever(name as never);
Copy link
Member

@RyanCavanaugh RyanCavanaugh Mar 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asserting to never here defeats the purpose of the assertNever function

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i.e. this should just be Debug.fail

@sheetalkamat
Copy link
Member Author

@RyanCavanaugh Added logic to start from scratch if not same compiler version as discussed in design meeting.

@sdwvit
Copy link

sdwvit commented Mar 23, 2019

Best feature of 3.4!

@tommedema
Copy link

Should we commit .tsbuildinfo files to version control?

@sheetalkamat
Copy link
Member Author

@tommedema They are like the output .js files and shouldn't be committed to version control.

@sdwvit
Copy link

sdwvit commented Mar 29, 2019

@tommedema don't think so, it is a cache which will be overridden by next tsc launch if code changes

@TheSpyder
Copy link

  • If project specified outDir, config files base file name with extension as .tsbuildinfo is written in outDir
  • Otherswise config files base file name with extension as .tsbuildinfo is written next to the config file

This isn't the behaviour I'm seeing using 3.4.2, it's falling through to the last path option for the build info file. I'm working on a composite project in a yarn workspace, with a config that begins with

{
  "compilerOptions": {
    "outDir": "lib",
    "rootDir": "src",
    "composite": true,
    "baseUrl": "."
  }
}

When using tsc -b it's generating the tsconfig.tsbuildinfo file next to the config file instead of in the lib folder. I have to specify "tsBuildInfoFile": "lib/tsconfig.tsbuildinfo" manually.

Should I log a new issue for this? It seems easy to repro but I can work on one if needed.

@glen-84
Copy link

glen-84 commented Apr 26, 2019

@TheSpyder
Copy link

Ah, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
7 participants