Expand anti-parent-barrel auto-import heuristic to all moduleResolution modes (#57342)

This commit is contained in:
Andrew Branch 2024-02-08 11:12:35 -08:00 committed by GitHub
parent 10a3872de4
commit 76cf0928f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 62 additions and 4 deletions

View File

@ -97,7 +97,6 @@ import {
mapDefined,
memoizeOne,
ModuleKind,
ModuleResolutionKind,
moduleResolutionUsesNodeModules,
moduleSpecifiers,
MultiMap,
@ -1054,13 +1053,11 @@ function compareModuleSpecifiers(
// This is a simple heuristic to try to avoid creating an import cycle with a barrel re-export.
// E.g., do not `import { Foo } from ".."` when you could `import { Foo } from "../Foo"`.
// This can produce false positives or negatives if re-exports cross into sibling directories
// (e.g. `export * from "../whatever"`) or are not named "index" (we don't even try to consider
// this if we're in a resolution mode where you can't drop trailing "/index" from paths).
// (e.g. `export * from "../whatever"`) or are not named "index".
function isFixPossiblyReExportingImportingFile(fix: ImportFixWithModuleSpecifier, importingFile: SourceFile, compilerOptions: CompilerOptions, toPath: (fileName: string) => Path): boolean {
if (
fix.isReExport &&
fix.exportInfo?.moduleFileName &&
getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node10 &&
isIndexFileName(fix.exportInfo.moduleFileName)
) {
const reExportDir = toPath(getDirectoryPath(fix.exportInfo.moduleFileName));

View File

@ -0,0 +1,30 @@
/// <reference path="fourslash.ts" />
// @module: preserve
// @moduleResolution: bundler
// @Filename: /foo/a.ts
//// export const A = 0;
// @Filename: /foo/b.ts
//// export {};
//// A/*sibling*/
// @Filename: /foo/index.ts
//// export * from "./a";
//// export * from "./b";
// @Filename: /index.ts
//// export * from "./foo";
//// export * from "./src";
// @Filename: /src/a.ts
//// export {};
//// A/*parent*/
// @Filename: /src/index.ts
//// export * from "./a";
// Module specifiers made up of only "." and ".." components are deprioritized
verify.importFixModuleSpecifiers("sibling", ["./a", ".", ".."]);
verify.importFixModuleSpecifiers("parent", ["../foo", "../foo/a", ".."]);

View File

@ -0,0 +1,31 @@
/// <reference path="fourslash.ts" />
// @module: nodenext
// @Filename: /package.json
//// { "type": "module" }
// @Filename: /foo/a.ts
//// export const A = 0;
// @Filename: /foo/b.ts
//// export {};
//// A/*sibling*/
// @Filename: /foo/index.ts
//// export * from "./a.js";
//// export * from "./b.js";
// @Filename: /index.ts
//// export * from "./foo/index.js";
//// export * from "./src/index.js";
// @Filename: /src/a.ts
//// export {};
//// A/*parent*/
// @Filename: /src/index.ts
//// export * from "./a.js";
verify.importFixModuleSpecifiers("sibling", ["./a.js", "./index.js", "../index.js"]);
verify.importFixModuleSpecifiers("parent", ["../foo/a.js", "../foo/index.js", "../index.js"]);