From 0b7b308d832b2bad12500d51bebec06513bd99b6 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 19 Sep 2017 14:42:31 -0700 Subject: [PATCH 1/2] Look at correct 'package.json' location for a scoped package --- src/compiler/moduleNameResolver.ts | 13 ++++++++----- .../moduleResolution_packageJson_scopedPackage.js | 15 +++++++++++++++ ...leResolution_packageJson_scopedPackage.symbols | 8 ++++++++ ...esolution_packageJson_scopedPackage.trace.json | 14 ++++++++++++++ ...duleResolution_packageJson_scopedPackage.types | 8 ++++++++ .../moduleResolution_packageJson_scopedPackage.ts | 11 +++++++++++ 6 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/moduleResolution_packageJson_scopedPackage.js create mode 100644 tests/baselines/reference/moduleResolution_packageJson_scopedPackage.symbols create mode 100644 tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json create mode 100644 tests/baselines/reference/moduleResolution_packageJson_scopedPackage.types create mode 100644 tests/cases/compiler/moduleResolution_packageJson_scopedPackage.ts diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index ddffe876d8085..84256b3a1b1d9 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -976,8 +976,8 @@ namespace ts { } function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, nodeModulesFolder: string, nodeModulesFolderExists: boolean, failedLookupLocations: Push, 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) || @@ -985,9 +985,12 @@ namespace ts { 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, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache): SearchResult { diff --git a/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.js b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.js new file mode 100644 index 0000000000000..32495ee1ab308 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.js @@ -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; diff --git a/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.symbols b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.symbols new file mode 100644 index 0000000000000..4522817e78f66 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.symbols @@ -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)) + diff --git a/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json new file mode 100644 index 0000000000000..69dcfca4eb681 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json @@ -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'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.types b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.types new file mode 100644 index 0000000000000..b2d16a70c2e58 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.types @@ -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 + diff --git a/tests/cases/compiler/moduleResolution_packageJson_scopedPackage.ts b/tests/cases/compiler/moduleResolution_packageJson_scopedPackage.ts new file mode 100644 index 0000000000000..624d21b4d7121 --- /dev/null +++ b/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"; From 04f557bcc9ac4e4e8ce78e931ef490fd955a8be6 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 20 Sep 2017 06:54:55 -0700 Subject: [PATCH 2/2] Update baseline --- tests/baselines/reference/scopedPackages.trace.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/scopedPackages.trace.json b/tests/baselines/reference/scopedPackages.trace.json index a2b8af4826645..1844f8c6c8d8e 100644 --- a/tests/baselines/reference/scopedPackages.trace.json +++ b/tests/baselines/reference/scopedPackages.trace.json @@ -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.",