Skip to content

Build cache invalidation bug when creating new subprojects #54501

Closed
@jwmerrill

Description

@jwmerrill

Bug Report

🔎 Search Terms

incremental build cache invalidation stale project

🕗 Version & Regression Information

  • This changed between versions 3.3 and 3.4.

The problem is not applicable before typescript 3.0 because 3.0 introduced the --build flag.

Incremental compilation was introduced in TS 3.4, so it appears that this problem has existed for as long as incremental compilation has existed.

The problem still occurs as of Version 5.2.0-dev.20230602 (typescript@next at the time of writing).

⏯ Playground Link

This problem is not reproducible in playground because it is a build system problem.

I created a reduced test case repo to demonstrate this issue. It has 3 commits and 3 ts source files.

💻 Code

The initial project structure has 3 source files in two directories,

  • src/main/const.ts
  • src/main/index.ts
  • src/hello/hello.ts

and a single sub-project

  • src/main/tsconfig.json

The following commit adds a second subproject:

  • src/hello/tsconfig.json

and moves the const.ts file from src/main/const.ts to src/hello/const.ts

🙁 Actual behavior

If you build the project (using tsc --build) at the second commit, then at the first commit, then at the second commit, tsc incorrectly reports an import error.

build/hello/hello.d.ts:1:23 - error TS2307: Cannot find module 'main/const' or its corresponding type declarations.

1 import { LogFn } from 'main/const';
                        ~~~~~~~~~~~~


Found 1 error.

These steps are described in more detail in the minimial reproduction README.

🙂 Expected behavior

The project builds without error.

After seeing the error, if I run

npx tsc --build --clean
npx tsc --build

the project builds without error.

Interpretation

The first build on the main branch creates a build/hello/tsconfig.tsbuildinfo cache file for the hello subproject.

The next build, on an earlier commit, updates build/hello/hello.d.ts to import from main/const (the original location of this file). This commit has no awareness of the hello subproject, and it does not touch build/hello/tsconfig.tsbuildinfo.

The final build, back on main, does not rebuild the hello subproject because it sees build/hello/tsconfig.tsbuildinfo and sees that the newest input of the hello subproject is older than this cache file. You can see this by running npx tsc --build --verbose

Output:

 > npx tsc --build --verbose
[12:44:45 PM] Projects in this build:
    * src/hello/tsconfig.json
    * src/main/tsconfig.json
    * tsconfig.json

[12:44:45 PM] Project 'src/hello/tsconfig.json' is up to date because newest input 'src/hello/const.ts' is older than output 'build/hello/tsconfig.tsbuildinfo'

[12:44:45 PM] Project 'src/main/tsconfig.json' is out of date because buildinfo file 'build/main/tsconfig.tsbuildinfo' indicates that some of the changes were not emitted

[12:44:45 PM] Building project '/Users/jason/src/tsc-build-cache-invalidation/src/main/tsconfig.json'...

build/hello/hello.d.ts:1:23 - error TS2307: Cannot find module 'main/const' or its corresponding type declarations.

1 import { LogFn } from 'main/const';
                        ~~~~~~~~~~~~


Found 1 error.

This is incorrect because one of the outputs of the hello project is stale, even though none of the inputs are newer than the build cache file.

Notes

This bug is a reduced version of a bug found by Desmos Studio in the process of migrating the Desmos Graphing Calculator to TS subprojects.

Our developers found that they were having to frequently clean the TS build directory when switching back and forth between branches that were either newer than or older than the migration to subprojects.

Related issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions