Skip to content

Commit

Permalink
Look at correct 'package.json' location for a scoped package (#18580) (
Browse files Browse the repository at this point in the history
…#18651)

* Look at correct 'package.json' location for a scoped package

* Update baseline
  • Loading branch information
Andy committed Sep 21, 2017
1 parent acfd670 commit 5538770
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 6 deletions.
13 changes: 8 additions & 5 deletions src/compiler/moduleNameResolver.ts
Expand Up @@ -975,18 +975,21 @@ namespace ts {
}

function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, nodeModulesFolder: string, nodeModulesFolderExists: boolean, failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined {
const { top, rest } = getNameOfTopDirectory(moduleName);
const packageRootPath = combinePaths(nodeModulesFolder, top);
const { packageName, rest } = getPackageName(moduleName);
const packageRootPath = combinePaths(nodeModulesFolder, packageName);
const { packageJsonContent, packageId } = getPackageJsonInfo(packageRootPath, rest, failedLookupLocations, !nodeModulesFolderExists, state);
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
const pathAndExtension = loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state, packageJsonContent);
return withPackageId(packageId, pathAndExtension);
}

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

function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache): SearchResult<Resolved> {
Expand Down
@@ -0,0 +1,15 @@
//// [tests/cases/compiler/moduleResolution_packageJson_scopedPackage.ts] ////

//// [package.json]
{ "types": "types.d.ts" }

//// [types.d.ts]
export const x: number;

//// [a.ts]
import { x } from "@foo/bar";


//// [a.js]
"use strict";
exports.__esModule = true;
@@ -0,0 +1,8 @@
=== /a.ts ===
import { x } from "@foo/bar";
>x : Symbol(x, Decl(a.ts, 0, 8))

=== /node_modules/@foo/bar/types.d.ts ===
export const x: number;
>x : Symbol(x, Decl(types.d.ts, 0, 12))

@@ -0,0 +1,14 @@
[
"======== Resolving module '@foo/bar' from '/a.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.",
"Found 'package.json' at '/node_modules/@foo/bar/package.json'.",
"File '/node_modules/@foo/bar.ts' does not exist.",
"File '/node_modules/@foo/bar.tsx' does not exist.",
"File '/node_modules/@foo/bar.d.ts' does not exist.",
"'package.json' does not have a 'typings' field.",
"'package.json' has 'types' field 'types.d.ts' that references '/node_modules/@foo/bar/types.d.ts'.",
"File '/node_modules/@foo/bar/types.d.ts' exist - use it as a name resolution result.",
"Resolving real path for '/node_modules/@foo/bar/types.d.ts', result '/node_modules/@foo/bar/types.d.ts'.",
"======== Module name '@foo/bar' was successfully resolved to '/node_modules/@foo/bar/types.d.ts'. ========"
]
@@ -0,0 +1,8 @@
=== /a.ts ===
import { x } from "@foo/bar";
>x : number

=== /node_modules/@foo/bar/types.d.ts ===
export const x: number;
>x : number

2 changes: 1 addition & 1 deletion tests/baselines/reference/scopedPackages.trace.json
Expand Up @@ -2,7 +2,7 @@
"======== Resolving module '@cow/boy' from '/a.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module '@cow/boy' from 'node_modules' folder, target file type 'TypeScript'.",
"File '/node_modules/@cow/package.json' does not exist.",
"File '/node_modules/@cow/boy/package.json' does not exist.",
"File '/node_modules/@cow/boy.ts' does not exist.",
"File '/node_modules/@cow/boy.tsx' does not exist.",
"File '/node_modules/@cow/boy.d.ts' does not exist.",
Expand Down
11 changes: 11 additions & 0 deletions tests/cases/compiler/moduleResolution_packageJson_scopedPackage.ts
@@ -0,0 +1,11 @@
// @noImplicitReferences: true
// @traceResolution: true

// @Filename: /node_modules/@foo/bar/package.json
{ "types": "types.d.ts" }

// @Filename: /node_modules/@foo/bar/types.d.ts
export const x: number;

// @Filename: /a.ts
import { x } from "@foo/bar";

0 comments on commit 5538770

Please sign in to comment.