Skip to content

Commit a6f7ec3

Browse files
committed
Handle outDir and declrationDir correctly to generate output file names for the tsbuild
1 parent 2961bc3 commit a6f7ec3

File tree

7 files changed

+142
-10
lines changed

7 files changed

+142
-10
lines changed

src/compiler/emitter.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,27 @@ namespace ts {
138138
/* @internal */
139139
export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean) {
140140
Debug.assert(!fileExtensionIs(inputFileName, Extension.Dts) && hasTSFileExtension(inputFileName));
141-
const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase);
142-
const outputPath = resolvePath(configFile.options.declarationDir || configFile.options.outDir || getDirectoryPath(Debug.assertDefined(configFile.options.configFilePath)), relativePath);
141+
let outputPath: string;
142+
const declarationDir = configFile.options.declarationDir || configFile.options.outDir;
143+
if (declarationDir) {
144+
const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase);
145+
outputPath = resolvePath(declarationDir, relativePath);
146+
}
147+
else {
148+
outputPath = inputFileName;
149+
}
143150
return changeExtension(outputPath, Extension.Dts);
144151
}
145152

146153
function getOutputJSFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean) {
147-
const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase);
148-
const outputPath = resolvePath(configFile.options.outDir || getDirectoryPath(Debug.assertDefined(configFile.options.configFilePath)), relativePath);
154+
let outputPath: string;
155+
if (configFile.options.outDir) {
156+
const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase);
157+
outputPath = resolvePath(configFile.options.outDir, relativePath);
158+
}
159+
else {
160+
outputPath = inputFileName;
161+
}
149162
const isJsonFile = fileExtensionIs(inputFileName, Extension.Json);
150163
const outputFileName = changeExtension(outputPath, isJsonFile ?
151164
Extension.Json :
@@ -203,6 +216,8 @@ namespace ts {
203216
const jsFilePath = getOutputJSFileName(inputFileName, configFile, ignoreCase);
204217
if (jsFilePath) return jsFilePath;
205218
}
219+
const buildInfoPath = getOutputPathForBuildInfo(configFile.options);
220+
if (buildInfoPath) return buildInfoPath;
206221
return Debug.fail(`project ${configFile.options.configFilePath} expected to have at least one output`);
207222
}
208223

src/testRunner/unittests/tsbuild/resolveJsonModule.ts

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
namespace ts {
2-
describe("unittests:: tsbuild:: with resolveJsonModule option", () => {
2+
describe("unittests:: tsbuild:: with resolveJsonModule option on project resolveJsonModuleAndComposite", () => {
33
let projFs: vfs.FileSystem;
44
const allExpectedOutputs = ["/src/dist/src/index.js", "/src/dist/src/index.d.ts", "/src/dist/src/hello.json"];
55
before(() => {
@@ -63,19 +63,92 @@ export default hello.hello`);
6363
const configFile = "src/tsconfig_withFiles.json";
6464
replaceText(fs, configFile, `"composite": true,`, `"composite": true, "sourceMap": true,`);
6565
const host = new fakes.SolutionBuilderHost(fs);
66-
const builder = createSolutionBuilder(host, [configFile], { verbose: false });
66+
const builder = createSolutionBuilder(host, [configFile], { verbose: true });
6767
builder.buildAllProjects();
68-
host.assertDiagnosticMessages();
68+
host.assertDiagnosticMessages(
69+
getExpectedDiagnosticForProjectsInBuild(configFile),
70+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, configFile, "src/dist/src/index.js"],
71+
[Diagnostics.Building_project_0, `/${configFile}`]
72+
);
6973
for (const output of [...allExpectedOutputs, "/src/dist/src/index.js.map"]) {
7074
assert(fs.existsSync(output), `Expect file ${output} to exist`);
7175
}
72-
73-
const newBuilder = createSolutionBuilder(host, [configFile], { verbose: true });
74-
newBuilder.buildAllProjects();
76+
host.clearDiagnostics();
77+
builder.resetBuildContext();
78+
builder.buildAllProjects();
7579
host.assertDiagnosticMessages(
7680
getExpectedDiagnosticForProjectsInBuild(configFile),
7781
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, configFile, "src/src/index.ts", "src/dist/src/index.js"]
7882
);
7983
});
84+
85+
it("with resolveJsonModule and without outDir", () => {
86+
const fs = projFs.shadow();
87+
const configFile = "src/tsconfig_withFiles.json";
88+
replaceText(fs, configFile, `"outDir": "dist",`, "");
89+
const host = new fakes.SolutionBuilderHost(fs);
90+
const builder = createSolutionBuilder(host, [configFile], { verbose: true });
91+
builder.buildAllProjects();
92+
host.assertDiagnosticMessages(
93+
getExpectedDiagnosticForProjectsInBuild(configFile),
94+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, configFile, "src/src/index.js"],
95+
[Diagnostics.Building_project_0, `/${configFile}`]
96+
);
97+
for (const output of ["/src/src/index.js", "/src/src/index.d.ts"]) {
98+
assert(fs.existsSync(output), `Expect file ${output} to exist`);
99+
}
100+
host.clearDiagnostics();
101+
builder.resetBuildContext();
102+
builder.buildAllProjects();
103+
host.assertDiagnosticMessages(
104+
getExpectedDiagnosticForProjectsInBuild(configFile),
105+
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, configFile, "src/src/index.ts", "src/src/index.js"]
106+
);
107+
});
108+
});
109+
110+
describe("unittests:: tsbuild:: with resolveJsonModule option on project importJsonFromProjectReference", () => {
111+
let projFs: vfs.FileSystem;
112+
before(() => {
113+
projFs = loadProjectFromDisk("tests/projects/importJsonFromProjectReference");
114+
});
115+
116+
after(() => {
117+
projFs = undefined!; // Release the contents
118+
});
119+
120+
it("when importing json module from project reference", () => {
121+
const expectedOutput = "/src/main/index.js";
122+
const fs = projFs.shadow();
123+
const configFile = "src/tsconfig.json";
124+
const stringsConfigFile = "src/strings/tsconfig.json";
125+
const mainConfigFile = "src/main/tsconfig.json";
126+
const host = new fakes.SolutionBuilderHost(fs);
127+
const builder = createSolutionBuilder(host, [configFile], { verbose: true });
128+
builder.buildAllProjects();
129+
host.assertDiagnosticMessages(
130+
getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile),
131+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, stringsConfigFile, "src/strings/tsconfig.tsbuildinfo"],
132+
[Diagnostics.Building_project_0, `/${stringsConfigFile}`],
133+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, mainConfigFile, "src/main/index.js"],
134+
[Diagnostics.Building_project_0, `/${mainConfigFile}`],
135+
[Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, "/src/strings/foo.json"],
136+
[Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, configFile, mainConfigFile],
137+
[Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, `/${configFile}`, `/${mainConfigFile}`]
138+
);
139+
assert.isFalse(fs.existsSync(expectedOutput), `Expect file ${expectedOutput} to not exist because of errors`);
140+
host.clearDiagnostics();
141+
builder.resetBuildContext();
142+
builder.buildAllProjects();
143+
host.assertDiagnosticMessages(
144+
getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile),
145+
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, stringsConfigFile, "src/strings/foo.json", "src/strings/tsconfig.tsbuildinfo"],
146+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, mainConfigFile, "src/main/index.js"],
147+
[Diagnostics.Building_project_0, `/${mainConfigFile}`],
148+
[Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, "/src/strings/foo.json"],
149+
[Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, configFile, mainConfigFile],
150+
[Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, `/${configFile}`, `/${mainConfigFile}`]
151+
);
152+
});
80153
});
81154
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { foo } from '../strings/foo.json';
2+
3+
console.log(foo);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": "../tsconfig.json",
3+
"include": [
4+
"./**/*.ts"
5+
],
6+
"references": [
7+
{
8+
"path": "../strings/tsconfig.json"
9+
}
10+
]
11+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"foo": "bar baz"
3+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "../tsconfig.json",
3+
"include": [
4+
"./**/*.ts",
5+
"./**/*.json"
6+
],
7+
"references": []
8+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"module": "commonjs",
5+
"rootDir": "./",
6+
"composite": true,
7+
"resolveJsonModule": true,
8+
"strict": true,
9+
"esModuleInterop": true
10+
},
11+
"references": [
12+
{
13+
"path": "./strings/tsconfig.json"
14+
},
15+
{
16+
"path": "./main/tsconfig.json"
17+
}
18+
]
19+
}

0 commit comments

Comments
 (0)