From 4daa3e23e0aa8a73af0f20c5284c4cd71968965b Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 25 Jan 2023 16:50:28 -0800 Subject: [PATCH 1/2] Fix auto-imports with `--moduleResolution bundler` and `customConditions` --- src/compiler/moduleNameResolver.ts | 2 +- src/compiler/moduleSpecifiers.ts | 6 +++-- .../fourslash/autoImportBundlerExports.ts | 21 ++++++++++++++++ .../fourslash/autoImportsCustomConditions.ts | 24 +++++++++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/autoImportBundlerExports.ts create mode 100644 tests/cases/fourslash/autoImportsCustomConditions.ts diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 45ba44eac4b00..e1737057ba6a4 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -659,7 +659,7 @@ function getNodeResolutionFeatures(options: CompilerOptions) { return features; } -function getConditions(options: CompilerOptions, esmMode?: boolean) { +export function getConditions(options: CompilerOptions, esmMode?: boolean) { // conditions are only used by the node16/nodenext/bundler resolvers - there's no priority order in the list, // it's essentially a set (priority is determined by object insertion order in the object we look at). const conditions = esmMode || getEmitModuleResolutionKind(options) === ModuleResolutionKind.Bundler diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 6dbbcb3fae03f..cdddd048e4245 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -33,6 +33,7 @@ import { forEachAncestorDirectory, getBaseFileName, GetCanonicalFileName, + getConditions, getDirectoryPath, getEmitModuleResolutionKind, getModeForResolutionAtIndex, @@ -46,6 +47,7 @@ import { getPathsBasePath, getRelativePathFromDirectory, getRelativePathToDirectoryOrUrl, + getResolvePackageJsonExports, getSourceFileOfModule, getSupportedExtensions, getTextOfIdentifierOrLiteral, @@ -945,8 +947,8 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan if (typeof cachedPackageJson === "object" || cachedPackageJson === undefined && host.fileExists(packageJsonPath)) { const packageJsonContent = cachedPackageJson?.contents.packageJsonContent || JSON.parse(host.readFile!(packageJsonPath)!); const importMode = overrideMode || importingSourceFile.impliedNodeFormat; - if (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext) { - const conditions = ["node", importMode === ModuleKind.ESNext ? "import" : "require", "types"]; + if (getResolvePackageJsonExports(options)) { + const conditions = getConditions(options, importMode === ModuleKind.ESNext); const fromExports = packageJsonContent.exports && typeof packageJsonContent.name === "string" ? tryGetModuleNameFromExports(options, path, packageRootPath, getPackageNameFromTypesPackageName(packageJsonContent.name), packageJsonContent.exports, conditions) : undefined; diff --git a/tests/cases/fourslash/autoImportBundlerExports.ts b/tests/cases/fourslash/autoImportBundlerExports.ts new file mode 100644 index 0000000000000..37a66bf09af72 --- /dev/null +++ b/tests/cases/fourslash/autoImportBundlerExports.ts @@ -0,0 +1,21 @@ +/// + +// @module: esnext +// @moduleResolution: bundler + +// @Filename: /node_modules/dep/package.json +//// { +//// "name": "dep", +//// "version": "1.0.0", +//// "exports": { +//// ".": "./dist/index.js" +//// } +//// } + +// @Filename: /node_modules/dep/dist/index.d.ts +//// export const dep: number; + +// @Filename: /index.ts +//// dep/**/ + +verify.importFixModuleSpecifiers("", ["dep"]); diff --git a/tests/cases/fourslash/autoImportsCustomConditions.ts b/tests/cases/fourslash/autoImportsCustomConditions.ts new file mode 100644 index 0000000000000..83e968ba2a801 --- /dev/null +++ b/tests/cases/fourslash/autoImportsCustomConditions.ts @@ -0,0 +1,24 @@ +/// + +// @module: esnext +// @moduleResolution: bundler +// @customConditions: custom + +// @Filename: /node_modules/dep/package.json +//// { +//// "name": "dep", +//// "version": "1.0.0", +//// "exports": { +//// ".": { +//// "custom": "./dist/index.js" +//// } +//// } +//// } + +// @Filename: /node_modules/dep/dist/index.d.ts +//// export const dep: number; + +// @Filename: /index.ts +//// dep/**/ + +verify.importFixModuleSpecifiers("", ["dep"]); From 4901275ebac2cf8195448ea2bce0c90e96b23b6c Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 25 Jan 2023 17:06:38 -0800 Subject: [PATCH 2/2] Make getConditions internal --- src/compiler/moduleNameResolver.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index e1737057ba6a4..26fbada55e7d4 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -659,6 +659,7 @@ function getNodeResolutionFeatures(options: CompilerOptions) { return features; } +/** @internal */ export function getConditions(options: CompilerOptions, esmMode?: boolean) { // conditions are only used by the node16/nodenext/bundler resolvers - there's no priority order in the list, // it's essentially a set (priority is determined by object insertion order in the object we look at).