moduleSpecifiers: Don't return a relative path to node_modules (#24460)
This commit is contained in:
parent
160b667846
commit
8bc1932ed5
3 changed files with 42 additions and 23 deletions
|
@ -16,15 +16,18 @@ namespace ts.moduleSpecifiers {
|
||||||
const getCanonicalFileName = hostGetCanonicalFileName(host);
|
const getCanonicalFileName = hostGetCanonicalFileName(host);
|
||||||
const sourceDirectory = getDirectoryPath(importingSourceFile.fileName);
|
const sourceDirectory = getDirectoryPath(importingSourceFile.fileName);
|
||||||
|
|
||||||
return getAllModulePaths(program, moduleSymbol.valueDeclaration.getSourceFile()).map(moduleFileName => {
|
const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol);
|
||||||
const global = tryGetModuleNameFromAmbientModule(moduleSymbol)
|
if (ambient) return [[ambient]];
|
||||||
|| tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension)
|
|
||||||
|| tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory)
|
|
||||||
|| rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName);
|
|
||||||
if (global) {
|
|
||||||
return [global];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const modulePaths = getAllModulePaths(program, moduleSymbol.valueDeclaration.getSourceFile());
|
||||||
|
|
||||||
|
const global = mapDefined(modulePaths, moduleFileName =>
|
||||||
|
tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) ||
|
||||||
|
tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) ||
|
||||||
|
rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName));
|
||||||
|
if (global.length) return global.map(g => [g]);
|
||||||
|
|
||||||
|
return modulePaths.map(moduleFileName => {
|
||||||
const relativePath = removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension);
|
const relativePath = removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension);
|
||||||
if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") {
|
if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") {
|
||||||
return [relativePath];
|
return [relativePath];
|
||||||
|
@ -191,11 +194,12 @@ namespace ts.moduleSpecifiers {
|
||||||
// Simplify the full file path to something that can be resolved by Node.
|
// Simplify the full file path to something that can be resolved by Node.
|
||||||
|
|
||||||
// If the module could be imported by a directory name, use that directory's name
|
// If the module could be imported by a directory name, use that directory's name
|
||||||
let moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName);
|
const moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName);
|
||||||
// Get a path that's relative to node_modules or the importing file's path
|
// Get a path that's relative to node_modules or the importing file's path
|
||||||
moduleSpecifier = getNodeResolvablePath(moduleSpecifier);
|
// if node_modules folder is in this folder or any of its parent folders, no need to keep it.
|
||||||
|
if (!startsWith(sourceDirectory, moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex))) return undefined;
|
||||||
// If the module was found in @types, get the actual Node package name
|
// If the module was found in @types, get the actual Node package name
|
||||||
return getPackageNameFromAtTypesDirectory(moduleSpecifier);
|
return getPackageNameFromAtTypesDirectory(moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1));
|
||||||
|
|
||||||
function getDirectoryOrExtensionlessFileName(path: string): string {
|
function getDirectoryOrExtensionlessFileName(path: string): string {
|
||||||
// If the file is the main module, it can be imported by the package name
|
// If the file is the main module, it can be imported by the package name
|
||||||
|
@ -224,17 +228,6 @@ namespace ts.moduleSpecifiers {
|
||||||
|
|
||||||
return fullModulePathWithoutExtension;
|
return fullModulePathWithoutExtension;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNodeResolvablePath(path: string): string {
|
|
||||||
const basePath = path.substring(0, parts.topLevelNodeModulesIndex);
|
|
||||||
if (sourceDirectory.indexOf(basePath) === 0) {
|
|
||||||
// if node_modules folder is in this folder or any of its parent folders, no need to keep it.
|
|
||||||
return path.substring(parts.topLevelPackageNameIndex + 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, path, getCanonicalFileName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NodeModulePathParts {
|
interface NodeModulePathParts {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/// <reference path="fourslash.ts" />
|
/// <reference path="fourslash.ts" />
|
||||||
|
|
||||||
// @noLib: true
|
// @noLib: true
|
||||||
// @nolib: true
|
|
||||||
// @jsx: preserve
|
// @jsx: preserve
|
||||||
|
|
||||||
// @Filename: /a.tsx
|
// @Filename: /a.tsx
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/// <reference path="fourslash.ts" />
|
||||||
|
|
||||||
|
// @Filename: /a/index.d.ts
|
||||||
|
// @Symlink: /b/node_modules/a/index.d.ts
|
||||||
|
// @Symlink: /c/node_modules/a/index.d.ts
|
||||||
|
////export const a: number;
|
||||||
|
|
||||||
|
// @Filename: /b/index.ts
|
||||||
|
// @Symlink: /c/node_modules/b/index.d.ts
|
||||||
|
////import { a } from 'a'
|
||||||
|
////export const b: number;
|
||||||
|
|
||||||
|
// @Filename: /c/a_user.ts
|
||||||
|
// Importing from "a" to get /c/node_modules/a in the project.
|
||||||
|
// Must do this in a separate file to avoid import fixes attempting to share the import.
|
||||||
|
////import { a } from "a";
|
||||||
|
|
||||||
|
// @Filename: /c/foo.ts
|
||||||
|
////[|import { b } from "b";
|
||||||
|
////a;|]
|
||||||
|
|
||||||
|
goTo.file("/c/foo.ts");
|
||||||
|
verify.importFixAtPosition([
|
||||||
|
`import { b } from "b";
|
||||||
|
import { a } from "a";
|
||||||
|
a;`,
|
||||||
|
]);
|
Loading…
Reference in a new issue