mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Keep extended config's raw file, include, exclude relative to itself and correct it when setting extending options (#42544)
* Test when config file extends is incorrectly computed Test for #40720 * Keep extended config's raw file, include, exclude relative to itself and correct it when setting extending options Fixes #40720
This commit is contained in:
parent
1c25b009f2
commit
c3e132da59
@ -2617,14 +2617,17 @@ namespace ts {
|
||||
if (ownConfig.extendedConfigPath) {
|
||||
// copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios.
|
||||
resolutionStack = resolutionStack.concat([resolvedPath]);
|
||||
const extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors, extendedConfigCache);
|
||||
const extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, resolutionStack, errors, extendedConfigCache);
|
||||
if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) {
|
||||
const baseRaw = extendedConfig.raw;
|
||||
const raw = ownConfig.raw;
|
||||
let relativeDifference: string | undefined ;
|
||||
const setPropertyInRawIfNotUndefined = (propertyName: string) => {
|
||||
const value = raw[propertyName] || baseRaw[propertyName];
|
||||
if (value) {
|
||||
raw[propertyName] = value;
|
||||
if (!raw[propertyName] && baseRaw[propertyName]) {
|
||||
raw[propertyName] = map(baseRaw[propertyName], (path: string) => isRootedDiskPath(path) ? path : combinePaths(
|
||||
relativeDifference ||= convertToRelativePath(getDirectoryPath(ownConfig.extendedConfigPath!), basePath, createGetCanonicalFileName(host.useCaseSensitiveFileNames)),
|
||||
path
|
||||
));
|
||||
}
|
||||
};
|
||||
setPropertyInRawIfNotUndefined("include");
|
||||
@ -2786,7 +2789,6 @@ namespace ts {
|
||||
sourceFile: TsConfigSourceFile | undefined,
|
||||
extendedConfigPath: string,
|
||||
host: ParseConfigHost,
|
||||
basePath: string,
|
||||
resolutionStack: string[],
|
||||
errors: Push<Diagnostic>,
|
||||
extendedConfigCache?: ESMap<string, ExtendedConfigCacheEntry>
|
||||
@ -2801,25 +2803,8 @@ namespace ts {
|
||||
else {
|
||||
extendedResult = readJsonConfigFile(extendedConfigPath, path => host.readFile(path));
|
||||
if (!extendedResult.parseDiagnostics.length) {
|
||||
const extendedDirname = getDirectoryPath(extendedConfigPath);
|
||||
extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname,
|
||||
extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, getDirectoryPath(extendedConfigPath),
|
||||
getBaseFileName(extendedConfigPath), resolutionStack, errors, extendedConfigCache);
|
||||
|
||||
if (isSuccessfulParsedTsconfig(extendedConfig)) {
|
||||
// Update the paths to reflect base path
|
||||
const relativeDifference = convertToRelativePath(extendedDirname, basePath, identity);
|
||||
const updatePath = (path: string) => isRootedDiskPath(path) ? path : combinePaths(relativeDifference, path);
|
||||
const mapPropertiesInRawIfNotUndefined = (propertyName: string) => {
|
||||
if (raw[propertyName]) {
|
||||
raw[propertyName] = map(raw[propertyName], updatePath);
|
||||
}
|
||||
};
|
||||
|
||||
const { raw } = extendedConfig;
|
||||
mapPropertiesInRawIfNotUndefined("include");
|
||||
mapPropertiesInRawIfNotUndefined("exclude");
|
||||
mapPropertiesInRawIfNotUndefined("files");
|
||||
}
|
||||
}
|
||||
if (extendedConfigCache) {
|
||||
extendedConfigCache.set(path, { extendedResult, extendedConfig });
|
||||
|
||||
@ -112,6 +112,7 @@
|
||||
"unittests/services/transpile.ts",
|
||||
"unittests/tsbuild/amdModulesWithOut.ts",
|
||||
"unittests/tsbuild/configFileErrors.ts",
|
||||
"unittests/tsbuild/configFileExtends.ts",
|
||||
"unittests/tsbuild/containerOnlyReferenced.ts",
|
||||
"unittests/tsbuild/declarationEmit.ts",
|
||||
"unittests/tsbuild/demo.ts",
|
||||
|
||||
52
src/testRunner/unittests/tsbuild/configFileExtends.ts
Normal file
52
src/testRunner/unittests/tsbuild/configFileExtends.ts
Normal file
@ -0,0 +1,52 @@
|
||||
namespace ts {
|
||||
describe("unittests:: tsbuild:: configFileExtends:: when tsconfig extends another config", () => {
|
||||
function getConfigExtendsWithIncludeFs() {
|
||||
return loadProjectFromFiles({
|
||||
"/src/tsconfig.json": JSON.stringify({
|
||||
references: [
|
||||
{ path: "./shared/tsconfig.json" },
|
||||
{ path: "./webpack/tsconfig.json" }
|
||||
],
|
||||
files: []
|
||||
}),
|
||||
"/src/shared/tsconfig-base.json": JSON.stringify({
|
||||
include: ["./typings-base/"]
|
||||
}),
|
||||
"/src/shared/typings-base/globals.d.ts": `type Unrestricted = any;`,
|
||||
"/src/shared/tsconfig.json": JSON.stringify({
|
||||
extends: "./tsconfig-base.json",
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
outDir: "../target-tsc-build/",
|
||||
rootDir: ".."
|
||||
},
|
||||
files: ["./index.ts"]
|
||||
}),
|
||||
"/src/shared/index.ts": `export const a: Unrestricted = 1;`,
|
||||
"/src/webpack/tsconfig.json": JSON.stringify({
|
||||
extends: "../shared/tsconfig-base.json",
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
outDir: "../target-tsc-build/",
|
||||
rootDir: ".."
|
||||
},
|
||||
files: ["./index.ts"],
|
||||
references: [{ path: "../shared/tsconfig.json" }]
|
||||
}),
|
||||
"/src/webpack/index.ts": `export const b: Unrestricted = 1;`,
|
||||
});
|
||||
}
|
||||
verifyTsc({
|
||||
scenario: "configFileExtends",
|
||||
subScenario: "when building solution with projects extends config with include",
|
||||
fs: getConfigExtendsWithIncludeFs,
|
||||
commandLineArgs: ["--b", "/src/tsconfig.json", "--v", "--listFiles"],
|
||||
});
|
||||
verifyTsc({
|
||||
scenario: "configFileExtends",
|
||||
subScenario: "when building project uses reference and both extend config with include",
|
||||
fs: getConfigExtendsWithIncludeFs,
|
||||
commandLineArgs: ["--b", "/src/webpack/tsconfig.json", "--v", "--listFiles"],
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -0,0 +1,160 @@
|
||||
Input::
|
||||
//// [/lib/lib.d.ts]
|
||||
/// <reference no-default-lib="true"/>
|
||||
interface Boolean {}
|
||||
interface Function {}
|
||||
interface CallableFunction {}
|
||||
interface NewableFunction {}
|
||||
interface IArguments {}
|
||||
interface Number { toExponential: any; }
|
||||
interface Object {}
|
||||
interface RegExp {}
|
||||
interface String { charAt: any; }
|
||||
interface Array<T> { length: number; [n: number]: T; }
|
||||
interface ReadonlyArray<T> {}
|
||||
declare const console: { log(msg: any): void; };
|
||||
|
||||
//// [/src/shared/index.ts]
|
||||
export const a: Unrestricted = 1;
|
||||
|
||||
//// [/src/shared/tsconfig-base.json]
|
||||
{"include":["./typings-base/"]}
|
||||
|
||||
//// [/src/shared/tsconfig.json]
|
||||
{"extends":"./tsconfig-base.json","compilerOptions":{"composite":true,"outDir":"../target-tsc-build/","rootDir":".."},"files":["./index.ts"]}
|
||||
|
||||
//// [/src/shared/typings-base/globals.d.ts]
|
||||
type Unrestricted = any;
|
||||
|
||||
//// [/src/tsconfig.json]
|
||||
|
||||
|
||||
//// [/src/webpack/index.ts]
|
||||
export const b: Unrestricted = 1;
|
||||
|
||||
//// [/src/webpack/tsconfig.json]
|
||||
{"extends":"../shared/tsconfig-base.json","compilerOptions":{"composite":true,"outDir":"../target-tsc-build/","rootDir":".."},"files":["./index.ts"],"references":[{"path":"../shared/tsconfig.json"}]}
|
||||
|
||||
|
||||
|
||||
Output::
|
||||
/lib/tsc --b /src/webpack/tsconfig.json --v --listFiles
|
||||
[[90m12:00:00 AM[0m] Projects in this build:
|
||||
* src/shared/tsconfig.json
|
||||
* src/webpack/tsconfig.json
|
||||
|
||||
[[90m12:00:00 AM[0m] Project 'src/shared/tsconfig.json' is out of date because output file 'src/target-tsc-build/shared/index.js' does not exist
|
||||
|
||||
[[90m12:00:00 AM[0m] Building project '/src/shared/tsconfig.json'...
|
||||
|
||||
/lib/lib.d.ts
|
||||
/src/shared/index.ts
|
||||
/src/shared/typings-base/globals.d.ts
|
||||
[[90m12:00:00 AM[0m] Project 'src/webpack/tsconfig.json' is out of date because output file 'src/target-tsc-build/webpack/index.js' does not exist
|
||||
|
||||
[[90m12:00:00 AM[0m] Building project '/src/webpack/tsconfig.json'...
|
||||
|
||||
/lib/lib.d.ts
|
||||
/src/webpack/index.ts
|
||||
/src/shared/typings-base/globals.d.ts
|
||||
exitCode:: ExitStatus.Success
|
||||
|
||||
|
||||
//// [/src/target-tsc-build/shared/index.d.ts]
|
||||
export declare const a: Unrestricted;
|
||||
|
||||
|
||||
//// [/src/target-tsc-build/shared/index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.a = void 0;
|
||||
exports.a = 1;
|
||||
|
||||
|
||||
//// [/src/target-tsc-build/shared/tsconfig.tsbuildinfo]
|
||||
{
|
||||
"program": {
|
||||
"fileInfos": {
|
||||
"../../../lib/lib.d.ts": {
|
||||
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
|
||||
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
|
||||
"affectsGlobalScope": true
|
||||
},
|
||||
"../../shared/index.ts": {
|
||||
"version": "-22125360210-export const a: Unrestricted = 1;",
|
||||
"signature": "-478734393-export declare const a: Unrestricted;\r\n",
|
||||
"affectsGlobalScope": false
|
||||
},
|
||||
"../../shared/typings-base/globals.d.ts": {
|
||||
"version": "4725476611-type Unrestricted = any;",
|
||||
"signature": "4725476611-type Unrestricted = any;",
|
||||
"affectsGlobalScope": true
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"composite": true,
|
||||
"outDir": "..",
|
||||
"rootDir": "../..",
|
||||
"listFiles": true,
|
||||
"configFilePath": "../../shared/tsconfig.json"
|
||||
},
|
||||
"referencedMap": {},
|
||||
"exportedModulesMap": {},
|
||||
"semanticDiagnosticsPerFile": [
|
||||
"../../../lib/lib.d.ts",
|
||||
"../../shared/index.ts",
|
||||
"../../shared/typings-base/globals.d.ts"
|
||||
]
|
||||
},
|
||||
"version": "FakeTSVersion"
|
||||
}
|
||||
|
||||
//// [/src/target-tsc-build/webpack/index.d.ts]
|
||||
export declare const b: Unrestricted;
|
||||
|
||||
|
||||
//// [/src/target-tsc-build/webpack/index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.b = void 0;
|
||||
exports.b = 1;
|
||||
|
||||
|
||||
//// [/src/target-tsc-build/webpack/tsconfig.tsbuildinfo]
|
||||
{
|
||||
"program": {
|
||||
"fileInfos": {
|
||||
"../../../lib/lib.d.ts": {
|
||||
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
|
||||
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
|
||||
"affectsGlobalScope": true
|
||||
},
|
||||
"../../webpack/index.ts": {
|
||||
"version": "-14405273073-export const b: Unrestricted = 1;",
|
||||
"signature": "-5074241048-export declare const b: Unrestricted;\r\n",
|
||||
"affectsGlobalScope": false
|
||||
},
|
||||
"../../shared/typings-base/globals.d.ts": {
|
||||
"version": "4725476611-type Unrestricted = any;",
|
||||
"signature": "4725476611-type Unrestricted = any;",
|
||||
"affectsGlobalScope": true
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"composite": true,
|
||||
"outDir": "..",
|
||||
"rootDir": "../..",
|
||||
"listFiles": true,
|
||||
"configFilePath": "../../webpack/tsconfig.json"
|
||||
},
|
||||
"referencedMap": {},
|
||||
"exportedModulesMap": {},
|
||||
"semanticDiagnosticsPerFile": [
|
||||
"../../../lib/lib.d.ts",
|
||||
"../../shared/typings-base/globals.d.ts",
|
||||
"../../webpack/index.ts"
|
||||
]
|
||||
},
|
||||
"version": "FakeTSVersion"
|
||||
}
|
||||
|
||||
@ -0,0 +1,161 @@
|
||||
Input::
|
||||
//// [/lib/lib.d.ts]
|
||||
/// <reference no-default-lib="true"/>
|
||||
interface Boolean {}
|
||||
interface Function {}
|
||||
interface CallableFunction {}
|
||||
interface NewableFunction {}
|
||||
interface IArguments {}
|
||||
interface Number { toExponential: any; }
|
||||
interface Object {}
|
||||
interface RegExp {}
|
||||
interface String { charAt: any; }
|
||||
interface Array<T> { length: number; [n: number]: T; }
|
||||
interface ReadonlyArray<T> {}
|
||||
declare const console: { log(msg: any): void; };
|
||||
|
||||
//// [/src/shared/index.ts]
|
||||
export const a: Unrestricted = 1;
|
||||
|
||||
//// [/src/shared/tsconfig-base.json]
|
||||
{"include":["./typings-base/"]}
|
||||
|
||||
//// [/src/shared/tsconfig.json]
|
||||
{"extends":"./tsconfig-base.json","compilerOptions":{"composite":true,"outDir":"../target-tsc-build/","rootDir":".."},"files":["./index.ts"]}
|
||||
|
||||
//// [/src/shared/typings-base/globals.d.ts]
|
||||
type Unrestricted = any;
|
||||
|
||||
//// [/src/tsconfig.json]
|
||||
{"references":[{"path":"./shared/tsconfig.json"},{"path":"./webpack/tsconfig.json"}],"files":[]}
|
||||
|
||||
//// [/src/webpack/index.ts]
|
||||
export const b: Unrestricted = 1;
|
||||
|
||||
//// [/src/webpack/tsconfig.json]
|
||||
{"extends":"../shared/tsconfig-base.json","compilerOptions":{"composite":true,"outDir":"../target-tsc-build/","rootDir":".."},"files":["./index.ts"],"references":[{"path":"../shared/tsconfig.json"}]}
|
||||
|
||||
|
||||
|
||||
Output::
|
||||
/lib/tsc --b /src/tsconfig.json --v --listFiles
|
||||
[[90m12:00:00 AM[0m] Projects in this build:
|
||||
* src/shared/tsconfig.json
|
||||
* src/webpack/tsconfig.json
|
||||
* src/tsconfig.json
|
||||
|
||||
[[90m12:00:00 AM[0m] Project 'src/shared/tsconfig.json' is out of date because output file 'src/target-tsc-build/shared/index.js' does not exist
|
||||
|
||||
[[90m12:00:00 AM[0m] Building project '/src/shared/tsconfig.json'...
|
||||
|
||||
/lib/lib.d.ts
|
||||
/src/shared/index.ts
|
||||
/src/shared/typings-base/globals.d.ts
|
||||
[[90m12:00:00 AM[0m] Project 'src/webpack/tsconfig.json' is out of date because output file 'src/target-tsc-build/webpack/index.js' does not exist
|
||||
|
||||
[[90m12:00:00 AM[0m] Building project '/src/webpack/tsconfig.json'...
|
||||
|
||||
/lib/lib.d.ts
|
||||
/src/webpack/index.ts
|
||||
/src/shared/typings-base/globals.d.ts
|
||||
exitCode:: ExitStatus.Success
|
||||
|
||||
|
||||
//// [/src/target-tsc-build/shared/index.d.ts]
|
||||
export declare const a: Unrestricted;
|
||||
|
||||
|
||||
//// [/src/target-tsc-build/shared/index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.a = void 0;
|
||||
exports.a = 1;
|
||||
|
||||
|
||||
//// [/src/target-tsc-build/shared/tsconfig.tsbuildinfo]
|
||||
{
|
||||
"program": {
|
||||
"fileInfos": {
|
||||
"../../../lib/lib.d.ts": {
|
||||
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
|
||||
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
|
||||
"affectsGlobalScope": true
|
||||
},
|
||||
"../../shared/index.ts": {
|
||||
"version": "-22125360210-export const a: Unrestricted = 1;",
|
||||
"signature": "-478734393-export declare const a: Unrestricted;\r\n",
|
||||
"affectsGlobalScope": false
|
||||
},
|
||||
"../../shared/typings-base/globals.d.ts": {
|
||||
"version": "4725476611-type Unrestricted = any;",
|
||||
"signature": "4725476611-type Unrestricted = any;",
|
||||
"affectsGlobalScope": true
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"composite": true,
|
||||
"outDir": "..",
|
||||
"rootDir": "../..",
|
||||
"listFiles": true,
|
||||
"configFilePath": "../../shared/tsconfig.json"
|
||||
},
|
||||
"referencedMap": {},
|
||||
"exportedModulesMap": {},
|
||||
"semanticDiagnosticsPerFile": [
|
||||
"../../../lib/lib.d.ts",
|
||||
"../../shared/index.ts",
|
||||
"../../shared/typings-base/globals.d.ts"
|
||||
]
|
||||
},
|
||||
"version": "FakeTSVersion"
|
||||
}
|
||||
|
||||
//// [/src/target-tsc-build/webpack/index.d.ts]
|
||||
export declare const b: Unrestricted;
|
||||
|
||||
|
||||
//// [/src/target-tsc-build/webpack/index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.b = void 0;
|
||||
exports.b = 1;
|
||||
|
||||
|
||||
//// [/src/target-tsc-build/webpack/tsconfig.tsbuildinfo]
|
||||
{
|
||||
"program": {
|
||||
"fileInfos": {
|
||||
"../../../lib/lib.d.ts": {
|
||||
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
|
||||
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
|
||||
"affectsGlobalScope": true
|
||||
},
|
||||
"../../webpack/index.ts": {
|
||||
"version": "-14405273073-export const b: Unrestricted = 1;",
|
||||
"signature": "-5074241048-export declare const b: Unrestricted;\r\n",
|
||||
"affectsGlobalScope": false
|
||||
},
|
||||
"../../shared/typings-base/globals.d.ts": {
|
||||
"version": "4725476611-type Unrestricted = any;",
|
||||
"signature": "4725476611-type Unrestricted = any;",
|
||||
"affectsGlobalScope": true
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"composite": true,
|
||||
"outDir": "..",
|
||||
"rootDir": "../..",
|
||||
"listFiles": true,
|
||||
"configFilePath": "../../webpack/tsconfig.json"
|
||||
},
|
||||
"referencedMap": {},
|
||||
"exportedModulesMap": {},
|
||||
"semanticDiagnosticsPerFile": [
|
||||
"../../../lib/lib.d.ts",
|
||||
"../../shared/typings-base/globals.d.ts",
|
||||
"../../webpack/index.ts"
|
||||
]
|
||||
},
|
||||
"version": "FakeTSVersion"
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user