Support auto-import from paths alias without baseUrl (#40546)

This commit is contained in:
Andrew Branch 2020-09-14 15:23:47 -07:00 committed by GitHub
parent ec36d73e7a
commit 575baf5c7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 7 deletions

View File

@ -788,7 +788,7 @@ namespace ts {
}
function tryLoadModuleUsingPathsIfEligible(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState) {
const { baseUrl, paths, pathsBasePath } = state.compilerOptions;
const { baseUrl, paths } = state.compilerOptions;
if (paths && !pathIsRelative(moduleName)) {
if (state.traceEnabled) {
if (baseUrl) {
@ -796,7 +796,7 @@ namespace ts {
}
trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
}
const baseDirectory = baseUrl ?? Debug.checkDefined(pathsBasePath || state.host.getCurrentDirectory?.(), "Encountered 'paths' without a 'baseUrl', config file, or host 'getCurrentDirectory'.");
const baseDirectory = getPathsBasePath(state.compilerOptions, state.host)!; // Always defined when 'paths' is defined
return tryLoadModuleUsingPaths(extensions, moduleName, baseDirectory, paths, loader, /*onlyRecordFailures*/ false, state);
}
}

View File

@ -82,7 +82,7 @@ namespace ts.moduleSpecifiers {
const info = getInfo(importingSourceFileName, host);
const modulePaths = getAllModulePaths(importingSourceFileName, toFileName, host);
return firstDefined(modulePaths, modulePath => tryGetModuleNameAsNodeModule(modulePath, info, host, compilerOptions)) ||
getLocalModuleSpecifier(toFileName, info, compilerOptions, preferences);
getLocalModuleSpecifier(toFileName, info, compilerOptions, host, preferences);
}
/** Returns an import for each symlink and for the realpath. */
@ -121,7 +121,7 @@ namespace ts.moduleSpecifiers {
}
if (!specifier && !modulePath.isRedirect) {
const local = getLocalModuleSpecifier(modulePath.path, info, compilerOptions, preferences);
const local = getLocalModuleSpecifier(modulePath.path, info, compilerOptions, host, preferences);
if (pathIsBareSpecifier(local)) {
pathsSpecifiers = append(pathsSpecifiers, local);
}
@ -156,16 +156,17 @@ namespace ts.moduleSpecifiers {
return { getCanonicalFileName, sourceDirectory };
}
function getLocalModuleSpecifier(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, { ending, relativePreference }: Preferences): string {
function getLocalModuleSpecifier(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, { ending, relativePreference }: Preferences): string {
const { baseUrl, paths, rootDirs, bundledPackageName } = compilerOptions;
const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) ||
removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions);
if (!baseUrl || relativePreference === RelativePreference.Relative) {
if (!baseUrl && !paths || relativePreference === RelativePreference.Relative) {
return relativePath;
}
const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName);
const baseDirectory = getPathsBasePath(compilerOptions, host) || baseUrl!;
const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseDirectory, getCanonicalFileName);
if (!relativeToBaseUrl) {
return relativePath;
}

View File

@ -4087,6 +4087,12 @@ namespace ts {
return options.outFile || options.out;
}
/** Returns 'undefined' if and only if 'options.paths' is undefined. */
export function getPathsBasePath(options: CompilerOptions, host: { getCurrentDirectory?(): string }) {
if (!options.paths) return undefined;
return options.baseUrl ?? Debug.checkDefined(options.pathsBasePath || host.getCurrentDirectory?.(), "Encountered 'paths' without a 'baseUrl', config file, or host 'getCurrentDirectory'.");
}
export interface EmitFileNames {
jsFilePath?: string | undefined;
sourceMapFilePath?: string | undefined;

View File

@ -0,0 +1,21 @@
/// <reference path="fourslash.ts" />
// @Filename: tsconfig.json
//// {
//// "compilerOptions": {
//// "module": "commonjs",
//// "paths": {
//// "@app/*": ["lib/*"]
//// }
//// }
//// }
// @Filename: index.ts
//// utils/**/
// @Filename: lib/utils.ts
//// export const utils = {};
goTo.marker("");
verify.importFixAtPosition([`import { utils } from "@app/utils";\n\nutils`]);