diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index d67bf107a8..7fb308912c 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -769,7 +769,7 @@ namespace ts { 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 }); + return toSearchResult({ resolved, isExternalLibraryImport: stringContains(resolved.path, nodeModulesPathPart) }); } if (!isExternalModuleNameRelative(moduleName)) { @@ -843,7 +843,8 @@ namespace ts { return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson); } - const nodeModulesPathPart = "/node_modules/"; + /*@internal*/ + export const nodeModulesPathPart = "/node_modules/"; /** * This will be called on the successfully resolved path from `loadModuleFromFile`. diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index e56951cb50..8c695e10be 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -401,7 +401,7 @@ namespace ts.moduleSpecifiers { partEnd = fullPath.indexOf("/", partStart + 1); switch (state) { case States.BeforeNodeModules: - if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + if (fullPath.indexOf(nodeModulesPathPart, partStart) === partStart) { topLevelNodeModulesIndex = partStart; topLevelPackageNameIndex = partEnd; state = States.NodeModules; @@ -418,7 +418,7 @@ namespace ts.moduleSpecifiers { } break; case States.PackageContent: - if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + if (fullPath.indexOf(nodeModulesPathPart, partStart) === partStart) { state = States.NodeModules; } else { diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index ae451ae302..2d7bcb34c2 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -419,7 +419,7 @@ namespace ts { function getDirectoryToWatchFromFailedLookupLocationDirectory(dir: string, dirPath: Path) { // If directory path contains node module, get the most parent node_modules directory for watching - while (stringContains(dirPath, "/node_modules/")) { + while (stringContains(dirPath, nodeModulesPathPart)) { dir = getDirectoryPath(dir); dirPath = getDirectoryPath(dirPath); } diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.js b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.js new file mode 100644 index 0000000000..b7f90ca24d --- /dev/null +++ b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.ts] //// + +//// [foobar.js] +module.exports = { a: 10 }; + +//// [a.ts] +import foobar from "foo/bar/foobar.js"; + + +//// [/bin/a.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.symbols b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.symbols new file mode 100644 index 0000000000..f6041ba8e3 --- /dev/null +++ b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.symbols @@ -0,0 +1,4 @@ +=== /a.ts === +import foobar from "foo/bar/foobar.js"; +>foobar : Symbol(foobar, Decl(a.ts, 0, 6)) + diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.trace.json new file mode 100644 index 0000000000..dac9d19bc0 --- /dev/null +++ b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.trace.json @@ -0,0 +1,10 @@ +[ + "======== Resolving module 'foo/bar/foobar.js' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo/bar/foobar.js'.", + "'paths' option is specified, looking for a pattern to match module name 'foo/bar/foobar.js'.", + "Module name 'foo/bar/foobar.js', matched pattern '*'.", + "Trying substitution 'node_modules/*', candidate module location: 'node_modules/foo/bar/foobar.js'.", + "File '/node_modules/foo/bar/foobar.js' exist - use it as a name resolution result.", + "======== Module name 'foo/bar/foobar.js' was successfully resolved to '/node_modules/foo/bar/foobar.js'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.types b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.types new file mode 100644 index 0000000000..829c950773 --- /dev/null +++ b/tests/baselines/reference/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.types @@ -0,0 +1,4 @@ +=== /a.ts === +import foobar from "foo/bar/foobar.js"; +>foobar : any + diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.ts b/tests/cases/compiler/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.ts new file mode 100644 index 0000000000..99e4070ff8 --- /dev/null +++ b/tests/cases/compiler/pathMappingBasedModuleResolution_withExtension_MapedToNodeModules.ts @@ -0,0 +1,23 @@ +// @noImplicitReferences: true +// @traceResolution: true +// @allowJs: true +// @esModuleInterop: true +// @fullEmitPaths: true + +// @Filename: /node_modules/foo/bar/foobar.js +module.exports = { a: 10 }; + +// @Filename: /a.ts +import foobar from "foo/bar/foobar.js"; + +// @Filename: /tsconfig.json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "*": ["node_modules/*", "src/types"] + }, + "allowJs": true, + "outDir": "bin" + } +}