diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 93953a3b90a..352cd83ca94 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2801,7 +2801,7 @@ "category": "Message", "code": 6099 }, - "'package.json' does not have a 'types' or 'main' field.": { + "'package.json' does not have a '{0}' field.": { "category": "Message", "code": 6100 }, @@ -2949,10 +2949,6 @@ "category": "Message", "code": 6136 }, - "No types specified in 'package.json', so returning 'main' value of '{0}'": { - "category": "Message", - "code": 6137 - }, "Property '{0}' is declared but never used.": { "category": "Error", "code": 6138 diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 0300ff71ec5..68b043f1439 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -67,40 +67,31 @@ namespace ts { } /** Reads from "main" or "types"/"typings" depending on `extensions`. */ - function tryReadPackageJsonMainOrTypes(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string { + function tryReadPackageJsonFields(readTypes: boolean, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string | undefined { const jsonContent = readJson(packageJsonPath, state.host); + return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main"); - switch (extensions) { - case Extensions.DtsOnly: - case Extensions.TypeScript: - return tryReadFromField("typings") || tryReadFromField("types"); - - case Extensions.JavaScript: - if (typeof jsonContent.main === "string") { - if (state.traceEnabled) { - trace(state.host, Diagnostics.No_types_specified_in_package_json_so_returning_main_value_of_0, jsonContent.main); - } - return normalizePath(combinePaths(baseDirectory, jsonContent.main)); - } - return undefined; - } - - function tryReadFromField(fieldName: string) { - if (hasProperty(jsonContent, fieldName)) { - const typesFile = (jsonContent)[fieldName]; - if (typeof typesFile === "string") { - const typesFilePath = normalizePath(combinePaths(baseDirectory, typesFile)); - if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, typesFile, typesFilePath); - } - return typesFilePath; - } - else { - if (state.traceEnabled) { - trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, fieldName, typeof typesFile); - } + function tryReadFromField(fieldName: "typings" | "types" | "main"): string | undefined { + if (!hasProperty(jsonContent, fieldName)) { + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_does_not_have_a_0_field, fieldName); } + return; } + + const fileName = jsonContent[fieldName]; + if (typeof fileName !== "string") { + if (state.traceEnabled) { + trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, fieldName, typeof fileName); + } + return; + } + + const path = normalizePath(combinePaths(baseDirectory, fileName)); + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path); + } + return path; } } @@ -698,7 +689,8 @@ namespace ts { return { resolvedModule: undefined, failedLookupLocations }; function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> { - const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, nodeLoadModuleByRelativeName, failedLookupLocations, state); + const loader: ResolutionKindSpecificLoader = (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/true); + const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state); if (resolved) { return toSearchResult({ resolved, isExternalLibraryImport: false }); } @@ -713,7 +705,7 @@ namespace ts { } else { const candidate = normalizePath(combinePaths(containingDirectory, moduleName)); - const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state); + const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/true); return resolved && toSearchResult({ resolved, isExternalLibraryImport: false }); } } @@ -731,7 +723,7 @@ namespace ts { return real; } - function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined { + function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson: boolean): Resolved | undefined { if (state.traceEnabled) { trace(state.host, Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]); } @@ -759,7 +751,7 @@ namespace ts { onlyRecordFailures = true; } } - return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); + return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson); } /* @internal */ @@ -835,50 +827,57 @@ namespace ts { return undefined; } - function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined { - const packageJsonPath = pathToPackageJson(candidate); + function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true): Resolved | undefined { const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host); - if (directoryExists && state.host.fileExists(packageJsonPath)) { - if (state.traceEnabled) { - trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath); - } - const mainOrTypesFile = tryReadPackageJsonMainOrTypes(extensions, packageJsonPath, candidate, state); - if (mainOrTypesFile) { - const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(mainOrTypesFile), state.host); - // A package.json "typings" may specify an exact filename, or may choose to omit an extension. - const fromExactFile = tryFile(mainOrTypesFile, failedLookupLocations, onlyRecordFailures, state); - if (fromExactFile) { - const resolved = fromExactFile && resolvedIfExtensionMatches(extensions, fromExactFile); - if (resolved) { - return resolved; - } - if (state.traceEnabled) { - trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromExactFile); - } - } - const resolved = tryAddingExtensions(mainOrTypesFile, Extensions.TypeScript, failedLookupLocations, onlyRecordFailures, state); - if (resolved) { - return resolved; + if (considerPackageJson) { + const packageJsonPath = pathToPackageJson(candidate); + if (directoryExists && state.host.fileExists(packageJsonPath)) { + const fromPackageJson = loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state); + if (fromPackageJson) { + return fromPackageJson; } } else { - if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_does_not_have_a_types_or_main_field); + if (directoryExists && state.traceEnabled) { + trace(state.host, Diagnostics.File_0_does_not_exist, packageJsonPath); } + // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results + failedLookupLocations.push(packageJsonPath); } } - else { - if (directoryExists && state.traceEnabled) { - trace(state.host, Diagnostics.File_0_does_not_exist, packageJsonPath); - } - // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results - failedLookupLocations.push(packageJsonPath); - } return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state); } + function loadModuleFromPackageJson(packageJsonPath: string, extensions: Extensions, candidate: string, failedLookupLocations: Push, state: ModuleResolutionState): Resolved | undefined { + if (state.traceEnabled) { + trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath); + } + + const file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, packageJsonPath, candidate, state); + if (!file) { + return undefined; + } + + const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(file), state.host); + const fromFile = tryFile(file, failedLookupLocations, onlyRecordFailures, state); + if (fromFile) { + const resolved = fromFile && resolvedIfExtensionMatches(extensions, fromFile); + if (resolved) { + return resolved; + } + if (state.traceEnabled) { + trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile); + } + } + + // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types" + const nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions; + // Don't do package.json lookup recursively, because Node.js' package lookup doesn't. + return nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ false); + } + /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */ function resolvedIfExtensionMatches(extensions: Extensions, path: string): Resolved | undefined { const extension = tryGetExtensionFromPath(path); @@ -1040,7 +1039,6 @@ namespace ts { return value !== undefined ? { value } : undefined; } - /** Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */ function forEachAncestorDirectory(directory: string, callback: (directory: string) => SearchResult): SearchResult { while (true) { diff --git a/tests/baselines/reference/library-reference-12.trace.json b/tests/baselines/reference/library-reference-12.trace.json index 14e46647d6d..75b53d589ee 100644 --- a/tests/baselines/reference/library-reference-12.trace.json +++ b/tests/baselines/reference/library-reference-12.trace.json @@ -5,6 +5,7 @@ "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", "File '/a/node_modules/jquery.d.ts' does not exist.", "Found 'package.json' at '/a/node_modules/jquery/package.json'.", + "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'dist/jquery.d.ts' that references '/a/node_modules/jquery/dist/jquery.d.ts'.", "File '/a/node_modules/jquery/dist/jquery.d.ts' exist - use it as a name resolution result.", "Resolving real path for '/a/node_modules/jquery/dist/jquery.d.ts', result '/a/node_modules/jquery/dist/jquery.d.ts'", diff --git a/tests/baselines/reference/library-reference-2.trace.json b/tests/baselines/reference/library-reference-2.trace.json index 8837f2c9cb1..ef0936a35a2 100644 --- a/tests/baselines/reference/library-reference-2.trace.json +++ b/tests/baselines/reference/library-reference-2.trace.json @@ -2,6 +2,7 @@ "======== Resolving type reference directive 'jquery', containing file '/consumer.ts', root directory '/types'. ========", "Resolving with primary search path '/types'", "Found 'package.json' at '/types/jquery/package.json'.", + "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", "File '/types/jquery/jquery.d.ts' exist - use it as a name resolution result.", "Resolving real path for '/types/jquery/jquery.d.ts', result '/types/jquery/jquery.d.ts'", @@ -9,6 +10,7 @@ "======== Resolving type reference directive 'jquery', containing file 'test/__inferred type names__.ts', root directory '/types'. ========", "Resolving with primary search path '/types'", "Found 'package.json' at '/types/jquery/package.json'.", + "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", "File '/types/jquery/jquery.d.ts' exist - use it as a name resolution result.", "Resolving real path for '/types/jquery/jquery.d.ts', result '/types/jquery/jquery.d.ts'", diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json index e1b1673b32a..8c820e07e48 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json @@ -6,7 +6,8 @@ "File '/node_modules/normalize.css.tsx' does not exist.", "File '/node_modules/normalize.css.d.ts' does not exist.", "Found 'package.json' at '/node_modules/normalize.css/package.json'.", - "'package.json' does not have a 'types' or 'main' field.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", "File '/node_modules/normalize.css/index.ts' does not exist.", "File '/node_modules/normalize.css/index.tsx' does not exist.", "File '/node_modules/normalize.css/index.d.ts' does not exist.", @@ -15,12 +16,13 @@ "File '/node_modules/normalize.css.js' does not exist.", "File '/node_modules/normalize.css.jsx' does not exist.", "Found 'package.json' at '/node_modules/normalize.css/package.json'.", - "No types specified in 'package.json', so returning 'main' value of 'normalize.css'", + "'package.json' has 'main' field 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.", "File '/node_modules/normalize.css/normalize.css' exist - use it as a name resolution result.", "File '/node_modules/normalize.css/normalize.css' has an unsupported extension, so skipping it.", - "File '/node_modules/normalize.css/normalize.css.ts' does not exist.", - "File '/node_modules/normalize.css/normalize.css.tsx' does not exist.", - "File '/node_modules/normalize.css/normalize.css.d.ts' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/normalize.css/normalize.css', target file type 'JavaScript'.", + "File '/node_modules/normalize.css/normalize.css.js' does not exist.", + "File '/node_modules/normalize.css/normalize.css.jsx' does not exist.", + "Directory '/node_modules/normalize.css/normalize.css' does not exist, skipping all lookups in it.", "File '/node_modules/normalize.css/index.js' does not exist.", "File '/node_modules/normalize.css/index.jsx' does not exist.", "======== Module name 'normalize.css' was not resolved. ========" diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json index 11dd95ebe45..e550bb41eab 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json @@ -6,12 +6,19 @@ "File '/node_modules/foo.tsx' does not exist.", "File '/node_modules/foo.d.ts' does not exist.", "Found 'package.json' at '/node_modules/foo/package.json'.", + "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.", "File '/node_modules/foo/foo.js' exist - use it as a name resolution result.", "File '/node_modules/foo/foo.js' has an unsupported extension, so skipping it.", + "Loading module as file / folder, candidate module location '/node_modules/foo/foo.js', target file type 'TypeScript'.", "File '/node_modules/foo/foo.js.ts' does not exist.", "File '/node_modules/foo/foo.js.tsx' does not exist.", "File '/node_modules/foo/foo.js.d.ts' does not exist.", + "File name '/node_modules/foo/foo.js' has a '.js' extension - stripping it", + "File '/node_modules/foo/foo.ts' does not exist.", + "File '/node_modules/foo/foo.tsx' does not exist.", + "File '/node_modules/foo/foo.d.ts' does not exist.", + "Directory '/node_modules/foo/foo.js' does not exist, skipping all lookups in it.", "File '/node_modules/foo/index.ts' does not exist.", "File '/node_modules/foo/index.tsx' does not exist.", "File '/node_modules/foo/index.d.ts' does not exist.", @@ -20,7 +27,7 @@ "File '/node_modules/foo.js' does not exist.", "File '/node_modules/foo.jsx' does not exist.", "Found 'package.json' at '/node_modules/foo/package.json'.", - "'package.json' does not have a 'types' or 'main' field.", + "'package.json' does not have a 'main' field.", "File '/node_modules/foo/index.js' does not exist.", "File '/node_modules/foo/index.jsx' does not exist.", "======== Module name 'foo' was not resolved. ========" diff --git a/tests/baselines/reference/packageJsonMain.js b/tests/baselines/reference/packageJsonMain.js new file mode 100644 index 00000000000..c7f63af27f2 --- /dev/null +++ b/tests/baselines/reference/packageJsonMain.js @@ -0,0 +1,34 @@ +//// [tests/cases/conformance/moduleResolution/packageJsonMain.ts] //// + +//// [package.json] + +{ "main": "oof" } + +//// [oof.js] +module.exports = 0; + +//// [package.json] +{ "main": "rab.js" } + +//// [rab.js] +module.exports = 0; + +//// [package.json] +{ "main": "zab" } + +//// [index.js] +module.exports = 0; + +//// [a.ts] +import foo = require("foo"); +import bar = require("bar"); +import baz = require("baz"); +foo + bar + baz; + + +//// [a.js] +"use strict"; +var foo = require("foo"); +var bar = require("bar"); +var baz = require("baz"); +foo + bar + baz; diff --git a/tests/baselines/reference/packageJsonMain.symbols b/tests/baselines/reference/packageJsonMain.symbols new file mode 100644 index 00000000000..c34c36e8901 --- /dev/null +++ b/tests/baselines/reference/packageJsonMain.symbols @@ -0,0 +1,15 @@ +=== /a.ts === +import foo = require("foo"); +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + +import bar = require("bar"); +>bar : Symbol(bar, Decl(a.ts, 0, 28)) + +import baz = require("baz"); +>baz : Symbol(baz, Decl(a.ts, 1, 28)) + +foo + bar + baz; +>foo : Symbol(foo, Decl(a.ts, 0, 0)) +>bar : Symbol(bar, Decl(a.ts, 0, 28)) +>baz : Symbol(baz, Decl(a.ts, 1, 28)) + diff --git a/tests/baselines/reference/packageJsonMain.trace.json b/tests/baselines/reference/packageJsonMain.trace.json new file mode 100644 index 00000000000..a167e8dfec6 --- /dev/null +++ b/tests/baselines/reference/packageJsonMain.trace.json @@ -0,0 +1,71 @@ +[ + "======== Resolving module 'foo' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/foo.ts' does not exist.", + "File '/node_modules/foo.tsx' does not exist.", + "File '/node_modules/foo.d.ts' does not exist.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/foo/index.tsx' does not exist.", + "File '/node_modules/foo/index.d.ts' does not exist.", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.", + "File '/node_modules/foo.js' does not exist.", + "File '/node_modules/foo.jsx' does not exist.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", + "File '/node_modules/foo/oof' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/foo/oof', target file type 'JavaScript'.", + "File '/node_modules/foo/oof.js' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/foo/oof.js', result '/node_modules/foo/oof.js'", + "======== Module name 'foo' was successfully resolved to '/node_modules/foo/oof.js'. ========", + "======== Resolving module 'bar' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'bar' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/bar.ts' does not exist.", + "File '/node_modules/bar.tsx' does not exist.", + "File '/node_modules/bar.d.ts' does not exist.", + "Found 'package.json' at '/node_modules/bar/package.json'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/bar/index.ts' does not exist.", + "File '/node_modules/bar/index.tsx' does not exist.", + "File '/node_modules/bar/index.d.ts' does not exist.", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Loading module 'bar' from 'node_modules' folder, target file type 'JavaScript'.", + "File '/node_modules/bar.js' does not exist.", + "File '/node_modules/bar.jsx' does not exist.", + "Found 'package.json' at '/node_modules/bar/package.json'.", + "'package.json' has 'main' field 'rab.js' that references '/node_modules/bar/rab.js'.", + "File '/node_modules/bar/rab.js' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/bar/rab.js', result '/node_modules/bar/rab.js'", + "======== Module name 'bar' was successfully resolved to '/node_modules/bar/rab.js'. ========", + "======== Resolving module 'baz' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'baz' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/baz.ts' does not exist.", + "File '/node_modules/baz.tsx' does not exist.", + "File '/node_modules/baz.d.ts' does not exist.", + "Found 'package.json' at '/node_modules/baz/package.json'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/baz/index.ts' does not exist.", + "File '/node_modules/baz/index.tsx' does not exist.", + "File '/node_modules/baz/index.d.ts' does not exist.", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Loading module 'baz' from 'node_modules' folder, target file type 'JavaScript'.", + "File '/node_modules/baz.js' does not exist.", + "File '/node_modules/baz.jsx' does not exist.", + "Found 'package.json' at '/node_modules/baz/package.json'.", + "'package.json' has 'main' field 'zab' that references '/node_modules/baz/zab'.", + "File '/node_modules/baz/zab' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/baz/zab', target file type 'JavaScript'.", + "File '/node_modules/baz/zab.js' does not exist.", + "File '/node_modules/baz/zab.jsx' does not exist.", + "File '/node_modules/baz/zab/index.js' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/baz/zab/index.js', result '/node_modules/baz/zab/index.js'", + "======== Module name 'baz' was successfully resolved to '/node_modules/baz/zab/index.js'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/packageJsonMain.types b/tests/baselines/reference/packageJsonMain.types new file mode 100644 index 00000000000..f30bd95f0e5 --- /dev/null +++ b/tests/baselines/reference/packageJsonMain.types @@ -0,0 +1,17 @@ +=== /a.ts === +import foo = require("foo"); +>foo : any + +import bar = require("bar"); +>bar : any + +import baz = require("baz"); +>baz : any + +foo + bar + baz; +>foo + bar + baz : any +>foo + bar : any +>foo : any +>bar : any +>baz : any + diff --git a/tests/baselines/reference/packageJsonMain_isNonRecursive.errors.txt b/tests/baselines/reference/packageJsonMain_isNonRecursive.errors.txt new file mode 100644 index 00000000000..a886fe3dca5 --- /dev/null +++ b/tests/baselines/reference/packageJsonMain_isNonRecursive.errors.txt @@ -0,0 +1,18 @@ +/a.ts(1,22): error TS2307: Cannot find module 'foo'. + + +==== /a.ts (1 errors) ==== + import foo = require("foo"); + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + +==== /node_modules/foo/package.json (0 errors) ==== + + { "main": "oof" } + +==== /node_modules/foo/oof/package.json (0 errors) ==== + { "main": "ofo" } + +==== /node_modules/foo/oof/ofo.js (0 errors) ==== + module.exports = 0; + \ No newline at end of file diff --git a/tests/baselines/reference/packageJsonMain_isNonRecursive.js b/tests/baselines/reference/packageJsonMain_isNonRecursive.js new file mode 100644 index 00000000000..edd56b359ee --- /dev/null +++ b/tests/baselines/reference/packageJsonMain_isNonRecursive.js @@ -0,0 +1,18 @@ +//// [tests/cases/conformance/moduleResolution/packageJsonMain_isNonRecursive.ts] //// + +//// [package.json] + +{ "main": "oof" } + +//// [package.json] +{ "main": "ofo" } + +//// [ofo.js] +module.exports = 0; + +//// [a.ts] +import foo = require("foo"); + + +//// [a.js] +"use strict"; diff --git a/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json new file mode 100644 index 00000000000..53e1ad25605 --- /dev/null +++ b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json @@ -0,0 +1,29 @@ +[ + "======== Resolving module 'foo' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/foo.ts' does not exist.", + "File '/node_modules/foo.tsx' does not exist.", + "File '/node_modules/foo.d.ts' does not exist.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/foo/index.tsx' does not exist.", + "File '/node_modules/foo/index.d.ts' does not exist.", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.", + "File '/node_modules/foo.js' does not exist.", + "File '/node_modules/foo.jsx' does not exist.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "'package.json' has 'main' field 'oof' that references '/node_modules/foo/oof'.", + "File '/node_modules/foo/oof' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/foo/oof', target file type 'JavaScript'.", + "File '/node_modules/foo/oof.js' does not exist.", + "File '/node_modules/foo/oof.jsx' does not exist.", + "File '/node_modules/foo/oof/index.js' does not exist.", + "File '/node_modules/foo/oof/index.jsx' does not exist.", + "File '/node_modules/foo/index.js' does not exist.", + "File '/node_modules/foo/index.jsx' does not exist.", + "======== Module name 'foo' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/typingsLookup4.js b/tests/baselines/reference/typingsLookup4.js index c11bc13c613..bc506a6036b 100644 --- a/tests/baselines/reference/typingsLookup4.js +++ b/tests/baselines/reference/typingsLookup4.js @@ -18,19 +18,30 @@ export const k: number; //// [lquery.ts] export const l = 2; +//// [package.json] +{ "typings": "mquery" } + +//// [index.tsx] +export const m = 3; + //// [a.ts] import { j } from "jquery"; import { k } from "kquery"; import { l } from "lquery"; -j + k + l; +import { m } from "mquery"; +j + k + l + m; //// [lquery.js] "use strict"; exports.l = 2; +//// [index.js] +"use strict"; +exports.m = 3; //// [a.js] "use strict"; var jquery_1 = require("jquery"); var kquery_1 = require("kquery"); var lquery_1 = require("lquery"); -jquery_1.j + kquery_1.k + lquery_1.l; +var mquery_1 = require("mquery"); +jquery_1.j + kquery_1.k + lquery_1.l + mquery_1.m; diff --git a/tests/baselines/reference/typingsLookup4.symbols b/tests/baselines/reference/typingsLookup4.symbols index 144548c6452..9269ee6617d 100644 --- a/tests/baselines/reference/typingsLookup4.symbols +++ b/tests/baselines/reference/typingsLookup4.symbols @@ -8,10 +8,14 @@ import { k } from "kquery"; import { l } from "lquery"; >l : Symbol(l, Decl(a.ts, 2, 8)) -j + k + l; +import { m } from "mquery"; +>m : Symbol(m, Decl(a.ts, 3, 8)) + +j + k + l + m; >j : Symbol(j, Decl(a.ts, 0, 8)) >k : Symbol(k, Decl(a.ts, 1, 8)) >l : Symbol(l, Decl(a.ts, 2, 8)) +>m : Symbol(m, Decl(a.ts, 3, 8)) === /node_modules/@types/jquery/jquery.d.ts === export const j: number; @@ -25,3 +29,7 @@ export const k: number; export const l = 2; >l : Symbol(l, Decl(lquery.ts, 0, 12)) +=== /node_modules/@types/mquery/mquery/index.tsx === +export const m = 3; +>m : Symbol(m, Decl(index.tsx, 0, 12)) + diff --git a/tests/baselines/reference/typingsLookup4.trace.json b/tests/baselines/reference/typingsLookup4.trace.json index 451d68edf28..332d9ffa416 100644 --- a/tests/baselines/reference/typingsLookup4.trace.json +++ b/tests/baselines/reference/typingsLookup4.trace.json @@ -21,6 +21,7 @@ "Found 'package.json' at '/node_modules/@types/kquery/package.json'.", "'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.", "File '/node_modules/@types/kquery/kquery' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/@types/kquery/kquery', target file type 'TypeScript'.", "File '/node_modules/@types/kquery/kquery.ts' does not exist.", "File '/node_modules/@types/kquery/kquery.tsx' does not exist.", "File '/node_modules/@types/kquery/kquery.d.ts' exist - use it as a name resolution result.", @@ -36,9 +37,28 @@ "Found 'package.json' at '/node_modules/@types/lquery/package.json'.", "'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.", "File '/node_modules/@types/lquery/lquery' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/@types/lquery/lquery', target file type 'TypeScript'.", "File '/node_modules/@types/lquery/lquery.ts' exist - use it as a name resolution result.", "Resolving real path for '/node_modules/@types/lquery/lquery.ts', result '/node_modules/@types/lquery/lquery.ts'", "======== Module name 'lquery' was successfully resolved to '/node_modules/@types/lquery/lquery.ts'. ========", + "======== Resolving module 'mquery' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'mquery' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/mquery.ts' does not exist.", + "File '/node_modules/mquery.tsx' does not exist.", + "File '/node_modules/mquery.d.ts' does not exist.", + "File '/node_modules/@types/mquery.d.ts' does not exist.", + "Found 'package.json' at '/node_modules/@types/mquery/package.json'.", + "'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.", + "File '/node_modules/@types/mquery/mquery' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/@types/mquery/mquery', target file type 'TypeScript'.", + "File '/node_modules/@types/mquery/mquery.ts' does not exist.", + "File '/node_modules/@types/mquery/mquery.tsx' does not exist.", + "File '/node_modules/@types/mquery/mquery.d.ts' does not exist.", + "File '/node_modules/@types/mquery/mquery/index.ts' does not exist.", + "File '/node_modules/@types/mquery/mquery/index.tsx' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/@types/mquery/mquery/index.tsx', result '/node_modules/@types/mquery/mquery/index.tsx'", + "======== Module name 'mquery' was successfully resolved to '/node_modules/@types/mquery/mquery/index.tsx'. ========", "======== Resolving type reference directive 'jquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'", "Found 'package.json' at '/node_modules/@types/jquery/package.json'.", @@ -51,6 +71,7 @@ "Found 'package.json' at '/node_modules/@types/kquery/package.json'.", "'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.", "File '/node_modules/@types/kquery/kquery' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/@types/kquery/kquery', target file type 'TypeScript'.", "File '/node_modules/@types/kquery/kquery.ts' does not exist.", "File '/node_modules/@types/kquery/kquery.tsx' does not exist.", "File '/node_modules/@types/kquery/kquery.d.ts' exist - use it as a name resolution result.", @@ -61,7 +82,21 @@ "Found 'package.json' at '/node_modules/@types/lquery/package.json'.", "'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.", "File '/node_modules/@types/lquery/lquery' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/@types/lquery/lquery', target file type 'TypeScript'.", "File '/node_modules/@types/lquery/lquery.ts' exist - use it as a name resolution result.", "Resolving real path for '/node_modules/@types/lquery/lquery.ts', result '/node_modules/@types/lquery/lquery.ts'", - "======== Type reference directive 'lquery' was successfully resolved to '/node_modules/@types/lquery/lquery.ts', primary: true. ========" + "======== Type reference directive 'lquery' was successfully resolved to '/node_modules/@types/lquery/lquery.ts', primary: true. ========", + "======== Resolving type reference directive 'mquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========", + "Resolving with primary search path '/node_modules/@types'", + "Found 'package.json' at '/node_modules/@types/mquery/package.json'.", + "'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.", + "File '/node_modules/@types/mquery/mquery' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/@types/mquery/mquery', target file type 'TypeScript'.", + "File '/node_modules/@types/mquery/mquery.ts' does not exist.", + "File '/node_modules/@types/mquery/mquery.tsx' does not exist.", + "File '/node_modules/@types/mquery/mquery.d.ts' does not exist.", + "File '/node_modules/@types/mquery/mquery/index.ts' does not exist.", + "File '/node_modules/@types/mquery/mquery/index.tsx' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/@types/mquery/mquery/index.tsx', result '/node_modules/@types/mquery/mquery/index.tsx'", + "======== Type reference directive 'mquery' was successfully resolved to '/node_modules/@types/mquery/mquery/index.tsx', primary: true. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/typingsLookup4.types b/tests/baselines/reference/typingsLookup4.types index e3f747ac55d..afa2483a862 100644 --- a/tests/baselines/reference/typingsLookup4.types +++ b/tests/baselines/reference/typingsLookup4.types @@ -8,12 +8,17 @@ import { k } from "kquery"; import { l } from "lquery"; >l : 2 -j + k + l; +import { m } from "mquery"; +>m : 3 + +j + k + l + m; +>j + k + l + m : number >j + k + l : number >j + k : number >j : number >k : number >l : 2 +>m : 3 === /node_modules/@types/jquery/jquery.d.ts === export const j: number; @@ -28,3 +33,8 @@ export const l = 2; >l : 2 >2 : 2 +=== /node_modules/@types/mquery/mquery/index.tsx === +export const m = 3; +>m : 3 +>3 : 3 + diff --git a/tests/cases/conformance/moduleResolution/packageJsonMain.ts b/tests/cases/conformance/moduleResolution/packageJsonMain.ts new file mode 100644 index 00000000000..6bf21cfaa3a --- /dev/null +++ b/tests/cases/conformance/moduleResolution/packageJsonMain.ts @@ -0,0 +1,27 @@ +// @noImplicitReferences: true +// @currentDirectory: / +// @traceResolution: true + +// @filename: /node_modules/foo/package.json +{ "main": "oof" } + +// @filename: /node_modules/foo/oof.js +module.exports = 0; + +// @filename: /node_modules/bar/package.json +{ "main": "rab.js" } + +// @filename: /node_modules/bar/rab.js +module.exports = 0; + +// @filename: /node_modules/baz/package.json +{ "main": "zab" } + +// @filename: /node_modules/baz/zab/index.js +module.exports = 0; + +// @filename: /a.ts +import foo = require("foo"); +import bar = require("bar"); +import baz = require("baz"); +foo + bar + baz; diff --git a/tests/cases/conformance/moduleResolution/packageJsonMain_isNonRecursive.ts b/tests/cases/conformance/moduleResolution/packageJsonMain_isNonRecursive.ts new file mode 100644 index 00000000000..c6e684b3fe1 --- /dev/null +++ b/tests/cases/conformance/moduleResolution/packageJsonMain_isNonRecursive.ts @@ -0,0 +1,15 @@ +// @noImplicitReferences: true +// @currentDirectory: / +// @traceResolution: true + +// @filename: /node_modules/foo/package.json +{ "main": "oof" } + +// @filename: /node_modules/foo/oof/package.json +{ "main": "ofo" } + +// @filename: /node_modules/foo/oof/ofo.js +module.exports = 0; + +// @filename: /a.ts +import foo = require("foo"); diff --git a/tests/cases/conformance/typings/typingsLookup4.ts b/tests/cases/conformance/typings/typingsLookup4.ts index 234090aebad..10317b6084b 100644 --- a/tests/cases/conformance/typings/typingsLookup4.ts +++ b/tests/cases/conformance/typings/typingsLookup4.ts @@ -1,6 +1,7 @@ // @traceResolution: true // @noImplicitReferences: true // @currentDirectory: / +// @jsx: react // A file extension is optional in typings entries. // @filename: /tsconfig.json @@ -24,8 +25,15 @@ export const k: number; // @filename: /node_modules/@types/lquery/lquery.ts export const l = 2; +// @filename: /node_modules/@types/mquery/package.json +{ "typings": "mquery" } + +// @filename: /node_modules/@types/mquery/mquery/index.tsx +export const m = 3; + // @filename: /a.ts import { j } from "jquery"; import { k } from "kquery"; import { l } from "lquery"; -j + k + l; +import { m } from "mquery"; +j + k + l + m;