diff --git a/src/compiler/program.ts b/src/compiler/program.ts index a1a06eaa1e..857ac30656 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -592,6 +592,7 @@ namespace ts { const programDiagnostics = createDiagnosticCollection(); const currentDirectory = host.getCurrentDirectory(); const supportedExtensions = getSupportedExtensions(options); + const supportedExtensionsWithJsonIfResolveJsonModule = options.resolveJsonModule ? [...supportedExtensions, Extension.Json] : undefined; // Map storing if there is emit blocking diagnostics for given input const hasEmitBlockingDiagnostics = createMap(); @@ -1925,7 +1926,7 @@ namespace ts { refFile?: SourceFile): SourceFile | undefined { if (hasExtension(fileName)) { - if (!options.allowNonTsExtensions && !forEach(supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) { + if (!options.allowNonTsExtensions && !forEach(supportedExtensionsWithJsonIfResolveJsonModule || supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) { if (fail) fail(Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'"); return undefined; } diff --git a/src/testRunner/unittests/tsbuild.ts b/src/testRunner/unittests/tsbuild.ts index f9e030ba3a..5cb546f8ab 100644 --- a/src/testRunner/unittests/tsbuild.ts +++ b/src/testRunner/unittests/tsbuild.ts @@ -233,6 +233,38 @@ namespace ts { assert.isBelow(fs.statSync("/src/core/index.js").mtimeMs, time(), "Upstream JS file should not have been rebuilt"); }); }); + + describe("tsbuild - with resolveJsonModule option", () => { + const projFs = loadProjectFromDisk("tests/projects/resolveJsonModuleAndComposite"); + const allExpectedOutputs = ["/src/tests/dist/src/index.js", "/src/tests/dist/src/index.d.ts", "/src/tests/dist/src/hello.json"]; + + function verifyProjectWithResolveJsonModule(configFile: string, ...expectedDiagnosticMessages: DiagnosticMessage[]) { + const fs = projFs.shadow(); + const host = new fakes.CompilerHost(fs); + const builder = createSolutionBuilder(host, buildHost, [configFile], { dry: false, force: false, verbose: false }); + clearDiagnostics(); + builder.buildAllProjects(); + assertDiagnosticMessages(...expectedDiagnosticMessages); + if (!expectedDiagnosticMessages.length) { + // Check for outputs. Not an exhaustive list + for (const output of allExpectedOutputs) { + assert(fs.existsSync(output), `Expect file ${output} to exist`); + } + } + } + + it("with resolveJsonModule and include only", () => { + verifyProjectWithResolveJsonModule("/src/tests/tsconfig_withInclude.json", Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern); + }); + + it("with resolveJsonModule and files containing json file", () => { + verifyProjectWithResolveJsonModule("/src/tests/tsconfig_withFiles.json"); + }); + + it("with resolveJsonModule and include and files", () => { + verifyProjectWithResolveJsonModule("/src/tests/tsconfig_withIncludeAndFiles.json"); + }); + }); } export namespace OutFile { @@ -427,4 +459,4 @@ namespace ts { fs.makeReadonly(); return fs; } -} \ No newline at end of file +} diff --git a/tests/projects/resolveJsonModuleAndComposite/tests/src/hello.json b/tests/projects/resolveJsonModuleAndComposite/tests/src/hello.json new file mode 100644 index 0000000000..eeedd40076 --- /dev/null +++ b/tests/projects/resolveJsonModuleAndComposite/tests/src/hello.json @@ -0,0 +1,3 @@ +{ + "hello": "world" +} \ No newline at end of file diff --git a/tests/projects/resolveJsonModuleAndComposite/tests/src/index.ts b/tests/projects/resolveJsonModuleAndComposite/tests/src/index.ts new file mode 100644 index 0000000000..997c752d5a --- /dev/null +++ b/tests/projects/resolveJsonModuleAndComposite/tests/src/index.ts @@ -0,0 +1,3 @@ +import hello from "./hello.json" + +export default hello.hello \ No newline at end of file diff --git a/tests/projects/resolveJsonModuleAndComposite/tests/tsconfig_withFiles.json b/tests/projects/resolveJsonModuleAndComposite/tests/tsconfig_withFiles.json new file mode 100644 index 0000000000..14a0614cb3 --- /dev/null +++ b/tests/projects/resolveJsonModuleAndComposite/tests/tsconfig_withFiles.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "composite": true, + "target": "esnext", + "moduleResolution": "node", + "module": "commonjs", + "resolveJsonModule": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "outDir": "dist" + }, + "files": [ + "src/index.ts", "src/hello.json" + ] +} \ No newline at end of file diff --git a/tests/projects/resolveJsonModuleAndComposite/tests/tsconfig_withInclude.json b/tests/projects/resolveJsonModuleAndComposite/tests/tsconfig_withInclude.json new file mode 100644 index 0000000000..b65aa32444 --- /dev/null +++ b/tests/projects/resolveJsonModuleAndComposite/tests/tsconfig_withInclude.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "composite": true, + "target": "esnext", + "moduleResolution": "node", + "module": "commonjs", + "resolveJsonModule": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "outDir": "dist" + }, + "include": [ + "src/**/*" + ] +} \ No newline at end of file diff --git a/tests/projects/resolveJsonModuleAndComposite/tests/tsconfig_withIncludeAndFiles.json b/tests/projects/resolveJsonModuleAndComposite/tests/tsconfig_withIncludeAndFiles.json new file mode 100644 index 0000000000..c9819ed3ca --- /dev/null +++ b/tests/projects/resolveJsonModuleAndComposite/tests/tsconfig_withIncludeAndFiles.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "composite": true, + "target": "esnext", + "moduleResolution": "node", + "module": "commonjs", + "resolveJsonModule": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "outDir": "dist" + }, + "files": [ + "src/hello.json" + ], + "include": [ + "src/**/*" + ] +} \ No newline at end of file