Skip to content

Commit 613e2d3

Browse files
authored
Merge pull request #9421 from Microsoft/dontEmitNodeModules
Don't emit any source files found under node_modules
2 parents a0c1084 + 5e4f13f commit 613e2d3

File tree

15 files changed

+71
-33
lines changed

15 files changed

+71
-33
lines changed

src/compiler/program.ts

+22-15
Original file line numberDiff line numberDiff line change
@@ -779,13 +779,18 @@ namespace ts {
779779
while (true) {
780780
const baseName = getBaseFileName(directory);
781781
if (baseName !== "node_modules") {
782-
const result =
783-
// first: try to load module as-is
784-
loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state) ||
785-
// second: try to load module from the scope '@types'
786-
loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
787-
if (result) {
788-
return result;
782+
// Try to load source from the package
783+
const packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state);
784+
if (packageResult && hasTypeScriptFileExtension(packageResult)) {
785+
// Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package
786+
return packageResult;
787+
}
788+
else {
789+
// Else prefer a types package over non-TypeScript results (e.g. JavaScript files)
790+
const typesResult = loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
791+
if (typesResult || packageResult) {
792+
return typesResult || packageResult;
793+
}
789794
}
790795
}
791796

@@ -1097,7 +1102,7 @@ namespace ts {
10971102
const modulesWithElidedImports: Map<boolean> = {};
10981103

10991104
// Track source files that are JavaScript files found by searching under node_modules, as these shouldn't be compiled.
1100-
const jsFilesFoundSearchingNodeModules: Map<boolean> = {};
1105+
const sourceFilesFoundSearchingNodeModules: Map<boolean> = {};
11011106

11021107
const start = new Date().getTime();
11031108

@@ -1378,7 +1383,7 @@ namespace ts {
13781383
getSourceFile: program.getSourceFile,
13791384
getSourceFileByPath: program.getSourceFileByPath,
13801385
getSourceFiles: program.getSourceFiles,
1381-
getFilesFromNodeModules: () => jsFilesFoundSearchingNodeModules,
1386+
isSourceFileFromExternalLibrary: (file: SourceFile) => !!lookUp(sourceFilesFoundSearchingNodeModules, file.path),
13821387
writeFile: writeFileCallback || (
13831388
(fileName, data, writeByteOrderMark, onError, sourceFiles) => host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles)),
13841389
isEmitBlocked,
@@ -2066,15 +2071,17 @@ namespace ts {
20662071
// - noResolve is falsy
20672072
// - module name comes from the list of imports
20682073
// - it's not a top level JavaScript module that exceeded the search max
2069-
const isJsFileUnderNodeModules = resolution && resolution.isExternalLibraryImport &&
2070-
hasJavaScriptFileExtension(resolution.resolvedFileName);
2074+
const isFromNodeModulesSearch = resolution && resolution.isExternalLibraryImport;
2075+
const isJsFileFromNodeModules = isFromNodeModulesSearch && hasJavaScriptFileExtension(resolution.resolvedFileName);
20712076

2072-
if (isJsFileUnderNodeModules) {
2073-
jsFilesFoundSearchingNodeModules[resolvedPath] = true;
2077+
if (isFromNodeModulesSearch) {
2078+
sourceFilesFoundSearchingNodeModules[resolvedPath] = true;
2079+
}
2080+
if (isJsFileFromNodeModules) {
20742081
currentNodeModulesJsDepth++;
20752082
}
20762083

2077-
const elideImport = isJsFileUnderNodeModules && currentNodeModulesJsDepth > maxNodeModulesJsDepth;
2084+
const elideImport = isJsFileFromNodeModules && currentNodeModulesJsDepth > maxNodeModulesJsDepth;
20782085
const shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !elideImport;
20792086

20802087
if (elideImport) {
@@ -2089,7 +2096,7 @@ namespace ts {
20892096
file.imports[i].end);
20902097
}
20912098

2092-
if (isJsFileUnderNodeModules) {
2099+
if (isJsFileFromNodeModules) {
20932100
currentNodeModulesJsDepth--;
20942101
}
20952102
}

src/compiler/utilities.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace ts {
3636
getSourceFiles(): SourceFile[];
3737

3838
/* @internal */
39-
getFilesFromNodeModules(): Map<boolean>;
39+
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
4040

4141
getCommonSourceDirectory(): string;
4242
getCanonicalFileName(fileName: string): string;
@@ -2277,10 +2277,9 @@ namespace ts {
22772277
}
22782278
else {
22792279
const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
2280-
const nodeModulesFiles = host.getFilesFromNodeModules();
22812280
for (const sourceFile of sourceFiles) {
22822281
// Don't emit if source file is a declaration file, or was located under node_modules
2283-
if (!isDeclarationFile(sourceFile) && !lookUp(nodeModulesFiles, sourceFile.path)) {
2282+
if (!isDeclarationFile(sourceFile) && !host.isSourceFileFromExternalLibrary(sourceFile)) {
22842283
onSingleFileEmit(host, sourceFile);
22852284
}
22862285
}
@@ -2314,10 +2313,9 @@ namespace ts {
23142313
function onBundledEmit(host: EmitHost) {
23152314
// Can emit only sources that are not declaration file and are either non module code or module with
23162315
// --module or --target es6 specified. Files included by searching under node_modules are also not emitted.
2317-
const nodeModulesFiles = host.getFilesFromNodeModules();
23182316
const bundledSources = filter(host.getSourceFiles(),
23192317
sourceFile => !isDeclarationFile(sourceFile) &&
2320-
!lookUp(nodeModulesFiles, sourceFile.path) &&
2318+
!host.isSourceFileFromExternalLibrary(sourceFile) &&
23212319
(!isExternalModule(sourceFile) ||
23222320
!!getEmitModuleKind(options)));
23232321
if (bundledSources.length) {

tests/baselines/reference/moduleAugmentationInDependency2.js

-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ export {};
88
//// [app.ts]
99
import "A"
1010

11-
//// [index.js]
12-
"use strict";
1311
//// [app.js]
1412
"use strict";
1513
require("A");

tests/baselines/reference/pathMappingBasedModuleResolution5_node.js

-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ exports.x = 1;
3131
//// [file2.js]
3232
"use strict";
3333
exports.y = 1;
34-
//// [file4.js]
35-
"use strict";
36-
exports.z1 = 1;
3734
//// [file1.js]
3835
"use strict";
3936
var file1_1 = require("folder2/file1");
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
define(["require", "exports", "m1"], function (require, exports, m1) {
1+
define(["require", "exports", "m1", "m4"], function (require, exports, m1, m4) {
22
"use strict";
33
m1.f1("test");
44
m1.f2.a = 10;
5-
m1.f2.person.age = "10"; // Error: Should be number
5+
m1.f2.person.age = "10"; // Should error if loaded the .js files correctly
6+
var r2 = 3 + m4.foo; // Should be OK if correctly using the @types .d.ts file
67
});

tests/baselines/reference/project/nodeModulesMaxDepthIncreased/amd/nodeModulesMaxDepthIncreased.errors.txt

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
maxDepthIncreased/root.ts(4,1): error TS2322: Type 'string' is not assignable to type 'number'.
1+
maxDepthIncreased/root.ts(7,1): error TS2322: Type 'string' is not assignable to type 'number'.
22

33

44
==== index.js (0 errors) ====
@@ -28,11 +28,19 @@ maxDepthIncreased/root.ts(4,1): error TS2322: Type 'string' is not assignable to
2828

2929
exports.f2 = m2;
3030

31+
==== entry.d.ts (0 errors) ====
32+
export declare var foo: number;
33+
3134
==== maxDepthIncreased/root.ts (1 errors) ====
3235
import * as m1 from "m1";
36+
import * as m4 from "m4";
37+
3338
m1.f1("test");
3439
m1.f2.a = 10;
35-
m1.f2.person.age = "10"; // Error: Should be number
40+
41+
m1.f2.person.age = "10"; // Should error if loaded the .js files correctly
3642
~~~~~~~~~~~~~~~~
3743
!!! error TS2322: Type 'string' is not assignable to type 'number'.
44+
45+
let r2 = 3 + m4.foo; // Should be OK if correctly using the @types .d.ts file
3846

tests/baselines/reference/project/nodeModulesMaxDepthIncreased/amd/nodeModulesMaxDepthIncreased.json

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"maxDepthIncreased/node_modules/m2/node_modules/m3/index.js",
1111
"maxDepthIncreased/node_modules/m2/entry.js",
1212
"maxDepthIncreased/node_modules/m1/index.js",
13+
"maxDepthIncreased/node_modules/@types/m4/entry.d.ts",
1314
"maxDepthIncreased/root.ts"
1415
],
1516
"emittedFiles": [
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"use strict";
22
var m1 = require("m1");
3+
var m4 = require("m4");
34
m1.f1("test");
45
m1.f2.a = 10;
5-
m1.f2.person.age = "10"; // Error: Should be number
6+
m1.f2.person.age = "10"; // Should error if loaded the .js files correctly
7+
var r2 = 3 + m4.foo; // Should be OK if correctly using the @types .d.ts file

tests/baselines/reference/project/nodeModulesMaxDepthIncreased/node/nodeModulesMaxDepthIncreased.errors.txt

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
maxDepthIncreased/root.ts(4,1): error TS2322: Type 'string' is not assignable to type 'number'.
1+
maxDepthIncreased/root.ts(7,1): error TS2322: Type 'string' is not assignable to type 'number'.
22

33

44
==== index.js (0 errors) ====
@@ -28,11 +28,19 @@ maxDepthIncreased/root.ts(4,1): error TS2322: Type 'string' is not assignable to
2828

2929
exports.f2 = m2;
3030

31+
==== entry.d.ts (0 errors) ====
32+
export declare var foo: number;
33+
3134
==== maxDepthIncreased/root.ts (1 errors) ====
3235
import * as m1 from "m1";
36+
import * as m4 from "m4";
37+
3338
m1.f1("test");
3439
m1.f2.a = 10;
35-
m1.f2.person.age = "10"; // Error: Should be number
40+
41+
m1.f2.person.age = "10"; // Should error if loaded the .js files correctly
3642
~~~~~~~~~~~~~~~~
3743
!!! error TS2322: Type 'string' is not assignable to type 'number'.
44+
45+
let r2 = 3 + m4.foo; // Should be OK if correctly using the @types .d.ts file
3846

tests/baselines/reference/project/nodeModulesMaxDepthIncreased/node/nodeModulesMaxDepthIncreased.json

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"maxDepthIncreased/node_modules/m2/node_modules/m3/index.js",
1111
"maxDepthIncreased/node_modules/m2/entry.js",
1212
"maxDepthIncreased/node_modules/m1/index.js",
13+
"maxDepthIncreased/node_modules/@types/m4/entry.d.ts",
1314
"maxDepthIncreased/root.ts"
1415
],
1516
"emittedFiles": [

tests/cases/projects/NodeModulesSearch/maxDepthIncreased/node_modules/@types/m4/entry.d.ts

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/cases/projects/NodeModulesSearch/maxDepthIncreased/node_modules/@types/m4/package.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/cases/projects/NodeModulesSearch/maxDepthIncreased/node_modules/m4/entry.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/cases/projects/NodeModulesSearch/maxDepthIncreased/node_modules/m4/package.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import * as m1 from "m1";
2+
import * as m4 from "m4";
3+
24
m1.f1("test");
35
m1.f2.a = 10;
4-
m1.f2.person.age = "10"; // Error: Should be number
6+
7+
m1.f2.person.age = "10"; // Should error if loaded the .js files correctly
8+
9+
let r2 = 3 + m4.foo; // Should be OK if correctly using the @types .d.ts file

0 commit comments

Comments
 (0)