Skip to content

Commit d5e7227

Browse files
author
Andy
authored
Look at correct 'package.json' location for a scoped package (#18580)
* Look at correct 'package.json' location for a scoped package * Update baseline
1 parent 8245597 commit d5e7227

7 files changed

+65
-6
lines changed

src/compiler/moduleNameResolver.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -976,18 +976,21 @@ namespace ts {
976976
}
977977

978978
function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, nodeModulesFolder: string, nodeModulesFolderExists: boolean, failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined {
979-
const { top, rest } = getNameOfTopDirectory(moduleName);
980-
const packageRootPath = combinePaths(nodeModulesFolder, top);
979+
const { packageName, rest } = getPackageName(moduleName);
980+
const packageRootPath = combinePaths(nodeModulesFolder, packageName);
981981
const { packageJsonContent, packageId } = getPackageJsonInfo(packageRootPath, rest, failedLookupLocations, !nodeModulesFolderExists, state);
982982
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
983983
const pathAndExtension = loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
984984
loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state, packageJsonContent);
985985
return withPackageId(packageId, pathAndExtension);
986986
}
987987

988-
function getNameOfTopDirectory(name: string): { top: string, rest: string } {
989-
const idx = name.indexOf(directorySeparator);
990-
return idx === -1 ? { top: name, rest: "" } : { top: name.slice(0, idx), rest: name.slice(idx + 1) };
988+
function getPackageName(moduleName: string): { packageName: string, rest: string } {
989+
let idx = moduleName.indexOf(directorySeparator);
990+
if (moduleName[0] === "@") {
991+
idx = moduleName.indexOf(directorySeparator, idx + 1);
992+
}
993+
return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
991994
}
992995

993996
function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache): SearchResult<Resolved> {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//// [tests/cases/compiler/moduleResolution_packageJson_scopedPackage.ts] ////
2+
3+
//// [package.json]
4+
{ "types": "types.d.ts" }
5+
6+
//// [types.d.ts]
7+
export const x: number;
8+
9+
//// [a.ts]
10+
import { x } from "@foo/bar";
11+
12+
13+
//// [a.js]
14+
"use strict";
15+
exports.__esModule = true;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
=== /a.ts ===
2+
import { x } from "@foo/bar";
3+
>x : Symbol(x, Decl(a.ts, 0, 8))
4+
5+
=== /node_modules/@foo/bar/types.d.ts ===
6+
export const x: number;
7+
>x : Symbol(x, Decl(types.d.ts, 0, 12))
8+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
"======== Resolving module '@foo/bar' from '/a.ts'. ========",
3+
"Module resolution kind is not specified, using 'NodeJs'.",
4+
"Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.",
5+
"Found 'package.json' at '/node_modules/@foo/bar/package.json'.",
6+
"File '/node_modules/@foo/bar.ts' does not exist.",
7+
"File '/node_modules/@foo/bar.tsx' does not exist.",
8+
"File '/node_modules/@foo/bar.d.ts' does not exist.",
9+
"'package.json' does not have a 'typings' field.",
10+
"'package.json' has 'types' field 'types.d.ts' that references '/node_modules/@foo/bar/types.d.ts'.",
11+
"File '/node_modules/@foo/bar/types.d.ts' exist - use it as a name resolution result.",
12+
"Resolving real path for '/node_modules/@foo/bar/types.d.ts', result '/node_modules/@foo/bar/types.d.ts'.",
13+
"======== Module name '@foo/bar' was successfully resolved to '/node_modules/@foo/bar/types.d.ts'. ========"
14+
]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
=== /a.ts ===
2+
import { x } from "@foo/bar";
3+
>x : number
4+
5+
=== /node_modules/@foo/bar/types.d.ts ===
6+
export const x: number;
7+
>x : number
8+

tests/baselines/reference/scopedPackages.trace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"======== Resolving module '@cow/boy' from '/a.ts'. ========",
33
"Module resolution kind is not specified, using 'NodeJs'.",
44
"Loading module '@cow/boy' from 'node_modules' folder, target file type 'TypeScript'.",
5-
"File '/node_modules/@cow/package.json' does not exist.",
5+
"File '/node_modules/@cow/boy/package.json' does not exist.",
66
"File '/node_modules/@cow/boy.ts' does not exist.",
77
"File '/node_modules/@cow/boy.tsx' does not exist.",
88
"File '/node_modules/@cow/boy.d.ts' does not exist.",
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @noImplicitReferences: true
2+
// @traceResolution: true
3+
4+
// @Filename: /node_modules/@foo/bar/package.json
5+
{ "types": "types.d.ts" }
6+
7+
// @Filename: /node_modules/@foo/bar/types.d.ts
8+
export const x: number;
9+
10+
// @Filename: /a.ts
11+
import { x } from "@foo/bar";

0 commit comments

Comments
 (0)