Cover more cases for node module auto-import (#54024)

This commit is contained in:
Jm 2023-05-10 00:46:55 +08:00 committed by GitHub
parent 2291afc187
commit 362703a213
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 1 deletions

View File

@ -24,6 +24,7 @@ import {
ExportAssignment,
Extension,
extensionFromPath,
extensionsNotSupportingExtensionlessResolution,
fileExtensionIsOneOf,
FileIncludeKind,
firstDefined,
@ -91,6 +92,7 @@ import {
removeExtension,
removeFileExtension,
removeSuffix,
removeTrailingDirectorySeparator,
ResolutionMode,
resolvePath,
ScriptKind,
@ -1007,10 +1009,24 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan
// happens very easily in fourslash tests though, since every test file listed gets included. See
// importNameCodeFix_typesVersions.ts for an example.)
const mainExportFile = toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
if (removeFileExtension(mainExportFile) === removeFileExtension(getCanonicalFileName(moduleFileToTry))) {
const canonicalModuleFileToTry = getCanonicalFileName(moduleFileToTry);
if (removeFileExtension(mainExportFile) === removeFileExtension(canonicalModuleFileToTry)) {
// ^ An arbitrary removal of file extension for this comparison is almost certainly wrong
return { packageRootPath, moduleFileToTry };
}
else if (
packageJsonContent.type !== "module" &&
!fileExtensionIsOneOf(canonicalModuleFileToTry, extensionsNotSupportingExtensionlessResolution) &&
startsWith(canonicalModuleFileToTry, mainExportFile) &&
getDirectoryPath(canonicalModuleFileToTry) === removeTrailingDirectorySeparator(mainExportFile) &&
removeFileExtension(getBaseFileName(canonicalModuleFileToTry)) === "index"
) {
// if mainExportFile is a directory, which contains moduleFileToTry, we just try index file
// example mainExportFile: `pkg/lib` and moduleFileToTry: `pkg/lib/index`, we can use packageRootPath
// but this behavior is deprecated for packages with "type": "module", so we only do this for packages without "type": "module"
// and make sure that the extension on index.{???} is something that supports omitting the extension
return { packageRootPath, moduleFileToTry };
}
}
}
else {

View File

@ -0,0 +1,26 @@
/// <reference path="fourslash.ts" />
// @allowJs: true
// @Filename: /node_modules/pkg/package.json
//// {
//// "name": "pkg",
//// "version": "1.0.0",
//// "main": "lib",
//// "module": "lib"
//// }
// @Filename: /node_modules/pkg/lib/index.js
//// export function foo() {};
// @Filename: /package.json
//// {
//// "dependencies": {
//// "pkg": "*"
//// }
//// }
// @Filename: /index.ts
//// foo/**/
verify.importFixModuleSpecifiers("", ["pkg"]);

View File

@ -0,0 +1,25 @@
/// <reference path="fourslash.ts" />
// @allowJs: true
// @Filename: /node_modules/pkg/package.json
//// {
//// "name": "pkg",
//// "version": "1.0.0",
//// "main": "lib"
//// }
// @Filename: /node_modules/pkg/lib/index.d.mts
//// export declare function foo(): any;
// @Filename: /package.json
//// {
//// "dependencies": {
//// "pkg": "*"
//// }
//// }
// @Filename: /index.ts
//// foo/**/
verify.importFixModuleSpecifiers("", ["pkg/lib/index.mjs"]);

View File

@ -0,0 +1,26 @@
/// <reference path="fourslash.ts" />
// @allowJs: true
// @Filename: /node_modules/pkg/package.json
//// {
//// "name": "pkg",
//// "version": "1.0.0",
//// "main": "lib",
//// "type": "module"
//// }
// @Filename: /node_modules/pkg/lib/index.js
//// export function foo() {};
// @Filename: /package.json
//// {
//// "dependencies": {
//// "pkg": "*"
//// }
//// }
// @Filename: /index.ts
//// foo/**/
verify.importFixModuleSpecifiers("", ["pkg/lib"]);