diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 7dcf950b43..cc79c02f1d 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -794,14 +794,12 @@ namespace ts { } else { // Check tsconfig time - const tsconfigTime = host.getModifiedTime(project.options.configFilePath!) || missingFileModifiedTime; - if (oldestOutputFileTime < tsconfigTime) { - return { - type: UpToDateStatusType.OutOfDateWithSelf, - outOfDateOutputFileName: oldestOutputFileName, - newerInputFileName: project.options.configFilePath! - }; - } + const configStatus = checkConfigFileUpToDateStatus(project.options.configFilePath!, oldestOutputFileTime, oldestOutputFileName); + if (configStatus) return configStatus; + + // Check extended config time + const extendedConfigStatus = forEach(project.options.configFile!.extendedSourceFiles || emptyArray, configFile => checkConfigFileUpToDateStatus(configFile, oldestOutputFileTime, oldestOutputFileName)); + if (extendedConfigStatus) return extendedConfigStatus; } if (!buildInfoChecked.hasKey(project.options.configFilePath as ResolvedConfigFileName)) { @@ -839,6 +837,18 @@ namespace ts { }; } + function checkConfigFileUpToDateStatus(configFile: string, oldestOutputFileTime: Date, oldestOutputFileName: string): Status.OutOfDateWithSelf | undefined { + // Check tsconfig time + const tsconfigTime = host.getModifiedTime(configFile) || missingFileModifiedTime; + if (oldestOutputFileTime < tsconfigTime) { + return { + type: UpToDateStatusType.OutOfDateWithSelf, + outOfDateOutputFileName: oldestOutputFileName, + newerInputFileName: configFile + }; + } + } + function invalidateProject(configFileName: string, reloadLevel?: ConfigFileProgramReloadLevel) { invalidateResolvedProject(resolveProjectName(configFileName), reloadLevel); } diff --git a/src/testRunner/unittests/tsbuild/sample.ts b/src/testRunner/unittests/tsbuild/sample.ts index 93ffc43ac2..6d128b348c 100644 --- a/src/testRunner/unittests/tsbuild/sample.ts +++ b/src/testRunner/unittests/tsbuild/sample.ts @@ -282,6 +282,37 @@ namespace ts { [Diagnostics.Updating_unchanged_output_timestamps_of_project_0, "/src/tests/tsconfig.json"] ); }); + + it("rebuilds when extended config file changes", () => { + const fs = projFs.shadow(); + fs.writeFileSync("/src/tests/tsconfig.base.json", JSON.stringify({ compilerOptions: { target: "es3" } })); + replaceText(fs, "/src/tests/tsconfig.json", `"references": [`, `"extends": "./tsconfig.base.json", "references": [`); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true }); + builder.buildAllProjects(); + host.assertDiagnosticMessages( + getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"], + [Diagnostics.Building_project_0, "/src/core/tsconfig.json"], + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/logic/tsconfig.json", "src/logic/index.js"], + [Diagnostics.Building_project_0, "/src/logic/tsconfig.json"], + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/tests/tsconfig.json", "src/tests/index.js"], + [Diagnostics.Building_project_0, "/src/tests/tsconfig.json"] + ); + host.clearDiagnostics(); + tick(); + builder.resetBuildContext(); + fs.writeFileSync("/src/tests/tsconfig.base.json", JSON.stringify({ compilerOptions: {} })); + builder.buildAllProjects(); + host.assertDiagnosticMessages( + getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), + [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"], + [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/logic/tsconfig.json", "src/logic/index.ts", "src/logic/index.js"], + [Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/tests/tsconfig.json", "src/tests/index.js", "src/tests/tsconfig.base.json"], + [Diagnostics.Building_project_0, "/src/tests/tsconfig.json"], + [Diagnostics.Updating_unchanged_output_timestamps_of_project_0, "/src/tests/tsconfig.json"] + ); + }); }); describe("downstream-blocked compilations", () => {