mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Fix prioritization of paths specifiers over node_modules package specifiers (#60238)
This commit is contained in:
@@ -508,46 +508,44 @@ function computeModuleSpecifiers(
|
||||
}
|
||||
}
|
||||
|
||||
if (!specifier) {
|
||||
const local = getLocalModuleSpecifier(
|
||||
modulePath.path,
|
||||
info,
|
||||
compilerOptions,
|
||||
host,
|
||||
options.overrideImportMode || importingSourceFile.impliedNodeFormat,
|
||||
preferences,
|
||||
/*pathsOnly*/ modulePath.isRedirect,
|
||||
);
|
||||
if (!local || forAutoImport && isExcludedByRegex(local, preferences.excludeRegexes)) {
|
||||
continue;
|
||||
}
|
||||
if (modulePath.isRedirect) {
|
||||
redirectPathsSpecifiers = append(redirectPathsSpecifiers, local);
|
||||
}
|
||||
else if (pathIsBareSpecifier(local)) {
|
||||
if (pathContainsNodeModules(local)) {
|
||||
// We could be in this branch due to inappropriate use of `baseUrl`, not intentional `paths`
|
||||
// usage. It's impossible to reason about where to prioritize baseUrl-generated module
|
||||
// specifiers, but if they contain `/node_modules/`, they're going to trigger a portability
|
||||
// error, so *at least* don't prioritize those.
|
||||
relativeSpecifiers = append(relativeSpecifiers, local);
|
||||
}
|
||||
else {
|
||||
pathsSpecifiers = append(pathsSpecifiers, local);
|
||||
}
|
||||
}
|
||||
else if (forAutoImport || !importedFileIsInNodeModules || modulePath.isInNodeModules) {
|
||||
// Why this extra conditional, not just an `else`? If some path to the file contained
|
||||
// 'node_modules', but we can't create a non-relative specifier (e.g. "@foo/bar/path/to/file"),
|
||||
// that means we had to go through a *sibling's* node_modules, not one we can access directly.
|
||||
// If some path to the file was in node_modules but another was not, this likely indicates that
|
||||
// we have a monorepo structure with symlinks. In this case, the non-node_modules path is
|
||||
// probably the realpath, e.g. "../bar/path/to/file", but a relative path to another package
|
||||
// in a monorepo is probably not portable. So, the module specifier we actually go with will be
|
||||
// the relative path through node_modules, so that the declaration emitter can produce a
|
||||
// portability error. (See declarationEmitReexportedSymlinkReference3)
|
||||
const local = getLocalModuleSpecifier(
|
||||
modulePath.path,
|
||||
info,
|
||||
compilerOptions,
|
||||
host,
|
||||
options.overrideImportMode || importingSourceFile.impliedNodeFormat,
|
||||
preferences,
|
||||
/*pathsOnly*/ modulePath.isRedirect || !!specifier,
|
||||
);
|
||||
if (!local || forAutoImport && isExcludedByRegex(local, preferences.excludeRegexes)) {
|
||||
continue;
|
||||
}
|
||||
if (modulePath.isRedirect) {
|
||||
redirectPathsSpecifiers = append(redirectPathsSpecifiers, local);
|
||||
}
|
||||
else if (pathIsBareSpecifier(local)) {
|
||||
if (pathContainsNodeModules(local)) {
|
||||
// We could be in this branch due to inappropriate use of `baseUrl`, not intentional `paths`
|
||||
// usage. It's impossible to reason about where to prioritize baseUrl-generated module
|
||||
// specifiers, but if they contain `/node_modules/`, they're going to trigger a portability
|
||||
// error, so *at least* don't prioritize those.
|
||||
relativeSpecifiers = append(relativeSpecifiers, local);
|
||||
}
|
||||
else {
|
||||
pathsSpecifiers = append(pathsSpecifiers, local);
|
||||
}
|
||||
}
|
||||
else if (forAutoImport || !importedFileIsInNodeModules || modulePath.isInNodeModules) {
|
||||
// Why this extra conditional, not just an `else`? If some path to the file contained
|
||||
// 'node_modules', but we can't create a non-relative specifier (e.g. "@foo/bar/path/to/file"),
|
||||
// that means we had to go through a *sibling's* node_modules, not one we can access directly.
|
||||
// If some path to the file was in node_modules but another was not, this likely indicates that
|
||||
// we have a monorepo structure with symlinks. In this case, the non-node_modules path is
|
||||
// probably the realpath, e.g. "../bar/path/to/file", but a relative path to another package
|
||||
// in a monorepo is probably not portable. So, the module specifier we actually go with will be
|
||||
// the relative path through node_modules, so that the declaration emitter can produce a
|
||||
// portability error. (See declarationEmitReexportedSymlinkReference3)
|
||||
relativeSpecifiers = append(relativeSpecifiers, local);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user