Handle outDir and declrationDir correctly to generate output file names for the tsbuild

This commit is contained in:
Sheetal Nandi 2019-03-14 09:21:20 -07:00
parent 2961bc3fc0
commit a6f7ec3464
7 changed files with 142 additions and 10 deletions

View file

@ -138,14 +138,27 @@ namespace ts {
/* @internal */
export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean) {
Debug.assert(!fileExtensionIs(inputFileName, Extension.Dts) && hasTSFileExtension(inputFileName));
const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase);
const outputPath = resolvePath(configFile.options.declarationDir || configFile.options.outDir || getDirectoryPath(Debug.assertDefined(configFile.options.configFilePath)), relativePath);
let outputPath: string;
const declarationDir = configFile.options.declarationDir || configFile.options.outDir;
if (declarationDir) {
const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase);
outputPath = resolvePath(declarationDir, relativePath);
}
else {
outputPath = inputFileName;
}
return changeExtension(outputPath, Extension.Dts);
}
function getOutputJSFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean) {
const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase);
const outputPath = resolvePath(configFile.options.outDir || getDirectoryPath(Debug.assertDefined(configFile.options.configFilePath)), relativePath);
let outputPath: string;
if (configFile.options.outDir) {
const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase);
outputPath = resolvePath(configFile.options.outDir, relativePath);
}
else {
outputPath = inputFileName;
}
const isJsonFile = fileExtensionIs(inputFileName, Extension.Json);
const outputFileName = changeExtension(outputPath, isJsonFile ?
Extension.Json :
@ -203,6 +216,8 @@ namespace ts {
const jsFilePath = getOutputJSFileName(inputFileName, configFile, ignoreCase);
if (jsFilePath) return jsFilePath;
}
const buildInfoPath = getOutputPathForBuildInfo(configFile.options);
if (buildInfoPath) return buildInfoPath;
return Debug.fail(`project ${configFile.options.configFilePath} expected to have at least one output`);
}

View file

@ -1,5 +1,5 @@
namespace ts {
describe("unittests:: tsbuild:: with resolveJsonModule option", () => {
describe("unittests:: tsbuild:: with resolveJsonModule option on project resolveJsonModuleAndComposite", () => {
let projFs: vfs.FileSystem;
const allExpectedOutputs = ["/src/dist/src/index.js", "/src/dist/src/index.d.ts", "/src/dist/src/hello.json"];
before(() => {
@ -63,19 +63,92 @@ export default hello.hello`);
const configFile = "src/tsconfig_withFiles.json";
replaceText(fs, configFile, `"composite": true,`, `"composite": true, "sourceMap": true,`);
const host = new fakes.SolutionBuilderHost(fs);
const builder = createSolutionBuilder(host, [configFile], { verbose: false });
const builder = createSolutionBuilder(host, [configFile], { verbose: true });
builder.buildAllProjects();
host.assertDiagnosticMessages();
host.assertDiagnosticMessages(
getExpectedDiagnosticForProjectsInBuild(configFile),
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, configFile, "src/dist/src/index.js"],
[Diagnostics.Building_project_0, `/${configFile}`]
);
for (const output of [...allExpectedOutputs, "/src/dist/src/index.js.map"]) {
assert(fs.existsSync(output), `Expect file ${output} to exist`);
}
const newBuilder = createSolutionBuilder(host, [configFile], { verbose: true });
newBuilder.buildAllProjects();
host.clearDiagnostics();
builder.resetBuildContext();
builder.buildAllProjects();
host.assertDiagnosticMessages(
getExpectedDiagnosticForProjectsInBuild(configFile),
[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"]
);
});
it("with resolveJsonModule and without outDir", () => {
const fs = projFs.shadow();
const configFile = "src/tsconfig_withFiles.json";
replaceText(fs, configFile, `"outDir": "dist",`, "");
const host = new fakes.SolutionBuilderHost(fs);
const builder = createSolutionBuilder(host, [configFile], { verbose: true });
builder.buildAllProjects();
host.assertDiagnosticMessages(
getExpectedDiagnosticForProjectsInBuild(configFile),
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, configFile, "src/src/index.js"],
[Diagnostics.Building_project_0, `/${configFile}`]
);
for (const output of ["/src/src/index.js", "/src/src/index.d.ts"]) {
assert(fs.existsSync(output), `Expect file ${output} to exist`);
}
host.clearDiagnostics();
builder.resetBuildContext();
builder.buildAllProjects();
host.assertDiagnosticMessages(
getExpectedDiagnosticForProjectsInBuild(configFile),
[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"]
);
});
});
describe("unittests:: tsbuild:: with resolveJsonModule option on project importJsonFromProjectReference", () => {
let projFs: vfs.FileSystem;
before(() => {
projFs = loadProjectFromDisk("tests/projects/importJsonFromProjectReference");
});
after(() => {
projFs = undefined!; // Release the contents
});
it("when importing json module from project reference", () => {
const expectedOutput = "/src/main/index.js";
const fs = projFs.shadow();
const configFile = "src/tsconfig.json";
const stringsConfigFile = "src/strings/tsconfig.json";
const mainConfigFile = "src/main/tsconfig.json";
const host = new fakes.SolutionBuilderHost(fs);
const builder = createSolutionBuilder(host, [configFile], { verbose: true });
builder.buildAllProjects();
host.assertDiagnosticMessages(
getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile),
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, stringsConfigFile, "src/strings/tsconfig.tsbuildinfo"],
[Diagnostics.Building_project_0, `/${stringsConfigFile}`],
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, mainConfigFile, "src/main/index.js"],
[Diagnostics.Building_project_0, `/${mainConfigFile}`],
[Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, "/src/strings/foo.json"],
[Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, configFile, mainConfigFile],
[Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, `/${configFile}`, `/${mainConfigFile}`]
);
assert.isFalse(fs.existsSync(expectedOutput), `Expect file ${expectedOutput} to not exist because of errors`);
host.clearDiagnostics();
builder.resetBuildContext();
builder.buildAllProjects();
host.assertDiagnosticMessages(
getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile),
[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"],
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, mainConfigFile, "src/main/index.js"],
[Diagnostics.Building_project_0, `/${mainConfigFile}`],
[Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, "/src/strings/foo.json"],
[Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, configFile, mainConfigFile],
[Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, `/${configFile}`, `/${mainConfigFile}`]
);
});
});
}

View file

@ -0,0 +1,3 @@
import { foo } from '../strings/foo.json';
console.log(foo);

View file

@ -0,0 +1,11 @@
{
"extends": "../tsconfig.json",
"include": [
"./**/*.ts"
],
"references": [
{
"path": "../strings/tsconfig.json"
}
]
}

View file

@ -0,0 +1,3 @@
{
"foo": "bar baz"
}

View file

@ -0,0 +1,8 @@
{
"extends": "../tsconfig.json",
"include": [
"./**/*.ts",
"./**/*.json"
],
"references": []
}

View file

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"rootDir": "./",
"composite": true,
"resolveJsonModule": true,
"strict": true,
"esModuleInterop": true
},
"references": [
{
"path": "./strings/tsconfig.json"
},
{
"path": "./main/tsconfig.json"
}
]
}