Treat explicit imports from node_modules as external library imports (#16364)

* Treat explicit imports from `node_modules` as external library imports

* Update baselines
This commit is contained in:
Andy 2017-08-17 13:26:38 -07:00 committed by GitHub
parent babb88a0aa
commit eef7d8bd3d
16 changed files with 99 additions and 29 deletions

View file

@ -1694,7 +1694,6 @@ namespace ts {
if (ambientModule) {
return ambientModule;
}
const isRelative = isExternalModuleNameRelative(moduleReference);
const resolvedModule = getResolvedModule(getSourceFileOfNode(location), moduleReference);
const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule);
const sourceFile = resolvedModule && !resolutionDiagnostic && host.getSourceFile(resolvedModule.resolvedFileName);
@ -1718,7 +1717,7 @@ namespace ts {
}
// May be an untyped module. If so, ignore resolutionDiagnostic.
if (!isRelative && resolvedModule && !extensionIsTypeScript(resolvedModule.extension)) {
if (resolvedModule && resolvedModule.isExternalLibraryImport && !extensionIsTypeScript(resolvedModule.extension)) {
if (isForAugmentation) {
const diag = Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented;
error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);

View file

@ -1543,16 +1543,20 @@ namespace ts {
}
export function normalizePath(path: string): string {
return normalizePathAndParts(path).path;
}
export function normalizePathAndParts(path: string): { path: string, parts: string[] } {
path = normalizeSlashes(path);
const rootLength = getRootLength(path);
const root = path.substr(0, rootLength);
const normalized = getNormalizedParts(path, rootLength);
if (normalized.length) {
const joinedParts = root + normalized.join(directorySeparator);
return pathEndsWithDirectorySeparator(path) ? joinedParts + directorySeparator : joinedParts;
const parts = getNormalizedParts(path, rootLength);
if (parts.length) {
const joinedParts = root + parts.join(directorySeparator);
return { path: pathEndsWithDirectorySeparator(path) ? joinedParts + directorySeparator : joinedParts, parts };
}
else {
return root;
return { path: root, parts };
}
}

View file

@ -747,9 +747,10 @@ namespace ts {
return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
}
else {
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
const { path: candidate, parts } = normalizePathAndParts(combinePaths(containingDirectory, moduleName));
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
return resolved && toSearchResult({ resolved, isExternalLibraryImport: false });
// Treat explicit "node_modules" import as an external library import.
return resolved && toSearchResult({ resolved, isExternalLibraryImport: contains(parts, "node_modules") });
}
}
}

View file

@ -3953,12 +3953,7 @@ namespace ts {
export interface ResolvedModule {
/** Path of the file the module was resolved to. */
resolvedFileName: string;
/**
* Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be a proper external module:
* - be a .d.ts file
* - use top level imports\exports
* - don't use tripleslash references
*/
/** True if `resolvedFileName` comes from `node_modules`. */
isExternalLibraryImport?: boolean;
}

View file

@ -0,0 +1,12 @@
//// [tests/cases/compiler/moduleResolution_explicitNodeModulesImport.ts] ////
//// [index.js]
exports.x = 0;
//// [index.ts]
import { x } from "../node_modules/foo";
//// [index.js]
"use strict";
exports.__esModule = true;

View file

@ -0,0 +1,9 @@
=== /src/index.ts ===
import { x } from "../node_modules/foo";
>x : Symbol(x, Decl(index.ts, 0, 8))
=== /node_modules/foo/index.js ===
exports.x = 0;
>exports : Symbol(x, Decl(index.js, 0, 0))
>x : Symbol(x, Decl(index.js, 0, 0))

View file

@ -0,0 +1,12 @@
=== /src/index.ts ===
import { x } from "../node_modules/foo";
>x : number
=== /node_modules/foo/index.js ===
exports.x = 0;
>exports.x = 0 : 0
>exports.x : any
>exports : any
>x : any
>0 : 0

View file

@ -0,0 +1,12 @@
//// [tests/cases/compiler/moduleResolution_explicitNodeModulesImport_implicitAny.ts] ////
//// [index.js]
exports.x = 0;
//// [index.ts]
import { y } from "../node_modules/foo";
//// [index.js]
"use strict";
exports.__esModule = true;

View file

@ -0,0 +1,4 @@
=== /src/index.ts ===
import { y } from "../node_modules/foo";
>y : Symbol(y, Decl(index.ts, 0, 8))

View file

@ -0,0 +1,4 @@
=== /src/index.ts ===
import { y } from "../node_modules/foo";
>y : any

View file

@ -13,9 +13,6 @@ maxDepthExceeded/root.ts(4,4): error TS2540: Cannot assign to 'rel' because it i
"exclude": ["node_modules/m2/**/*"]
}
==== relative.js (0 errors) ====
exports.relativeProp = true;
==== index.js (0 errors) ====
var m2 = require('m2');
var rel = require('./relative');
@ -51,4 +48,7 @@ maxDepthExceeded/root.ts(4,4): error TS2540: Cannot assign to 'rel' because it i
"b": "hello, world",
"person": m3.person
};
==== relative.js (0 errors) ====
exports.relativeProp = true;

View file

@ -7,14 +7,14 @@
"project": "maxDepthExceeded",
"resolvedInputFiles": [
"lib.d.ts",
"maxDepthExceeded/node_modules/m1/relative.js",
"maxDepthExceeded/node_modules/m1/index.js",
"maxDepthExceeded/root.ts",
"maxDepthExceeded/node_modules/m2/entry.js"
"maxDepthExceeded/node_modules/m2/entry.js",
"maxDepthExceeded/node_modules/m1/relative.js"
],
"emittedFiles": [
"maxDepthExceeded/built/node_modules/m1/relative.js",
"maxDepthExceeded/built/node_modules/m1/index.js",
"maxDepthExceeded/built/root.js"
"maxDepthExceeded/built/root.js",
"maxDepthExceeded/built/node_modules/m1/relative.js"
]
}

View file

@ -13,9 +13,6 @@ maxDepthExceeded/root.ts(4,4): error TS2540: Cannot assign to 'rel' because it i
"exclude": ["node_modules/m2/**/*"]
}
==== relative.js (0 errors) ====
exports.relativeProp = true;
==== index.js (0 errors) ====
var m2 = require('m2');
var rel = require('./relative');
@ -51,4 +48,7 @@ maxDepthExceeded/root.ts(4,4): error TS2540: Cannot assign to 'rel' because it i
"b": "hello, world",
"person": m3.person
};
==== relative.js (0 errors) ====
exports.relativeProp = true;

View file

@ -7,14 +7,14 @@
"project": "maxDepthExceeded",
"resolvedInputFiles": [
"lib.d.ts",
"maxDepthExceeded/node_modules/m1/relative.js",
"maxDepthExceeded/node_modules/m1/index.js",
"maxDepthExceeded/root.ts",
"maxDepthExceeded/node_modules/m2/entry.js"
"maxDepthExceeded/node_modules/m2/entry.js",
"maxDepthExceeded/node_modules/m1/relative.js"
],
"emittedFiles": [
"maxDepthExceeded/built/node_modules/m1/relative.js",
"maxDepthExceeded/built/node_modules/m1/index.js",
"maxDepthExceeded/built/root.js"
"maxDepthExceeded/built/root.js",
"maxDepthExceeded/built/node_modules/m1/relative.js"
]
}

View file

@ -0,0 +1,9 @@
// @allowJs: true
// @noImplicitReferences: true
// @maxNodeModuleJsDepth: 1
// @Filename: /node_modules/foo/index.js
exports.x = 0;
// @Filename: /src/index.ts
import { x } from "../node_modules/foo";

View file

@ -0,0 +1,9 @@
// @allowJs: true
// @noImplicitReferences: true
// @maxNodeModuleJsDepth: 0
// @Filename: /node_modules/foo/index.js
exports.x = 0;
// @Filename: /src/index.ts
import { y } from "../node_modules/foo";