Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 328a5ef

Browse filesBrowse files
authored
Merge pull request microsoft#13024 from Microsoft/package_json_unsupported_extension
Skip files from package.json "main" or "types" if they have an unsupported extension.
2 parents f3ad09a + bf94a4a commit 328a5ef
Copy full SHA for 328a5ef

12 files changed

+169-16Lines changed: 169 additions & 16 deletions
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/diagnosticMessages.json‎

Copy file name to clipboardExpand all lines: src/compiler/diagnosticMessages.json
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,6 +2685,10 @@
26852685
"category": "Message",
26862686
"code": 6080
26872687
},
2688+
"File '{0}' has an unsupported extension, so skipping it.": {
2689+
"category": "Message",
2690+
"code": 6081
2691+
},
26882692
"Only 'amd' and 'system' modules are supported alongside --{0}.": {
26892693
"category": "Error",
26902694
"code": 6082
Collapse file

‎src/compiler/moduleNameResolver.ts‎

Copy file name to clipboardExpand all lines: src/compiler/moduleNameResolver.ts
+33-16Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,6 @@ namespace ts {
4747
return resolved.path;
4848
}
4949

50-
/** Create Resolved from a file with unknown extension. */
51-
function resolvedFromAnyFile(path: string): Resolved | undefined {
52-
return { path, extension: extensionFromPath(path) };
53-
}
54-
5550
/** Adds `isExernalLibraryImport` to a Resolved to get a ResolvedModule. */
5651
function resolvedModuleFromResolved({ path, extension }: Resolved, isExternalLibraryImport: boolean): ResolvedModuleFull {
5752
return { resolvedFileName: path, extension, isExternalLibraryImport };
@@ -71,7 +66,8 @@ namespace ts {
7166
traceEnabled: boolean;
7267
}
7368

74-
function tryReadTypesSection(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
69+
/** Reads from "main" or "types"/"typings" depending on `extensions`. */
70+
function tryReadPackageJsonMainOrTypes(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
7571
const jsonContent = readJson(packageJsonPath, state.host);
7672

7773
switch (extensions) {
@@ -714,18 +710,21 @@ namespace ts {
714710
if (state.traceEnabled) {
715711
trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath);
716712
}
717-
const typesFile = tryReadTypesSection(extensions, packageJsonPath, candidate, state);
718-
if (typesFile) {
719-
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(typesFile), state.host);
713+
const mainOrTypesFile = tryReadPackageJsonMainOrTypes(extensions, packageJsonPath, candidate, state);
714+
if (mainOrTypesFile) {
715+
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(mainOrTypesFile), state.host);
720716
// A package.json "typings" may specify an exact filename, or may choose to omit an extension.
721-
const fromFile = tryFile(typesFile, failedLookupLocations, onlyRecordFailures, state);
722-
if (fromFile) {
723-
// Note: this would allow a package.json to specify a ".js" file as typings. Maybe that should be forbidden.
724-
return resolvedFromAnyFile(fromFile);
717+
const fromExactFile = tryFile(mainOrTypesFile, failedLookupLocations, onlyRecordFailures, state);
718+
if (fromExactFile) {
719+
const resolved = fromExactFile && resolvedIfExtensionMatches(extensions, fromExactFile);
720+
if (resolved) {
721+
return resolved;
722+
}
723+
trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromExactFile);
725724
}
726-
const x = tryAddingExtensions(typesFile, Extensions.TypeScript, failedLookupLocations, onlyRecordFailures, state);
727-
if (x) {
728-
return x;
725+
const resolved = tryAddingExtensions(mainOrTypesFile, Extensions.TypeScript, failedLookupLocations, onlyRecordFailures, state);
726+
if (resolved) {
727+
return resolved;
729728
}
730729
}
731730
else {
@@ -745,6 +744,24 @@ namespace ts {
745744
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state);
746745
}
747746

747+
/** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
748+
function resolvedIfExtensionMatches(extensions: Extensions, path: string): Resolved | undefined {
749+
const extension = tryGetExtensionFromPath(path);
750+
return extension !== undefined && extensionIsOk(extensions, extension) ? { path, extension } : undefined;
751+
}
752+
753+
/** True if `extension` is one of the supported `extensions`. */
754+
function extensionIsOk(extensions: Extensions, extension: Extension): boolean {
755+
switch (extensions) {
756+
case Extensions.JavaScript:
757+
return extension === Extension.Js || extension === Extension.Jsx;
758+
case Extensions.TypeScript:
759+
return extension === Extension.Ts || extension === Extension.Tsx || extension === Extension.Dts;
760+
case Extensions.DtsOnly:
761+
return extension === Extension.Dts;
762+
}
763+
}
764+
748765
function pathToPackageJson(directory: string): string {
749766
return combinePaths(directory, "package.json");
750767
}
Collapse file
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//// [tests/cases/compiler/moduleResolutionWithExtensions_unexpected.ts] ////
2+
3+
//// [normalize.css]
4+
// This tests that a package.json "main" with an unexpected extension is ignored.
5+
6+
This file is not read.
7+
8+
//// [package.json]
9+
{ "main": "normalize.css" }
10+
11+
//// [a.ts]
12+
import "normalize.css";
13+
14+
15+
//// [a.js]
16+
"use strict";
17+
require("normalize.css");
Collapse file
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== /a.ts ===
2+
import "normalize.css";
3+
No type information for this code.
4+
No type information for this code.
Collapse file
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[
2+
"======== Resolving module 'normalize.css' from '/a.ts'. ========",
3+
"Module resolution kind is not specified, using 'NodeJs'.",
4+
"Loading module 'normalize.css' from 'node_modules' folder.",
5+
"File '/node_modules/normalize.css.ts' does not exist.",
6+
"File '/node_modules/normalize.css.tsx' does not exist.",
7+
"File '/node_modules/normalize.css.d.ts' does not exist.",
8+
"Found 'package.json' at '/node_modules/normalize.css/package.json'.",
9+
"'package.json' does not have a 'types' or 'main' field.",
10+
"File '/node_modules/normalize.css/index.ts' does not exist.",
11+
"File '/node_modules/normalize.css/index.tsx' does not exist.",
12+
"File '/node_modules/normalize.css/index.d.ts' does not exist.",
13+
"File '/node_modules/@types/normalize.css.d.ts' does not exist.",
14+
"File '/node_modules/@types/normalize.css/package.json' does not exist.",
15+
"File '/node_modules/@types/normalize.css/index.d.ts' does not exist.",
16+
"Loading module 'normalize.css' from 'node_modules' folder.",
17+
"File '/node_modules/normalize.css.js' does not exist.",
18+
"File '/node_modules/normalize.css.jsx' does not exist.",
19+
"Found 'package.json' at '/node_modules/normalize.css/package.json'.",
20+
"No types specified in 'package.json', so returning 'main' value of 'normalize.css'",
21+
"File '/node_modules/normalize.css/normalize.css' exist - use it as a name resolution result.",
22+
"File '/node_modules/normalize.css/normalize.css' has an unsupported extension, so skipping it.",
23+
"File '/node_modules/normalize.css/normalize.css.ts' does not exist.",
24+
"File '/node_modules/normalize.css/normalize.css.tsx' does not exist.",
25+
"File '/node_modules/normalize.css/normalize.css.d.ts' does not exist.",
26+
"File '/node_modules/normalize.css/index.js' does not exist.",
27+
"File '/node_modules/normalize.css/index.jsx' does not exist.",
28+
"======== Module name 'normalize.css' was not resolved. ========"
29+
]
Collapse file
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== /a.ts ===
2+
import "normalize.css";
3+
No type information for this code.
4+
No type information for this code.
Collapse file
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//// [tests/cases/compiler/moduleResolutionWithExtensions_unexpected2.ts] ////
2+
3+
//// [foo.js]
4+
// This tests that a package.json "types" with an unexpected extension is ignored.
5+
6+
This file is not read.
7+
8+
//// [package.json]
9+
{ "types": "foo.js" }
10+
11+
//// [a.ts]
12+
import "foo";
13+
14+
15+
//// [a.js]
16+
"use strict";
17+
require("foo");
Collapse file
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== /a.ts ===
2+
import "foo";
3+
No type information for this code.
4+
No type information for this code.
Collapse file
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[
2+
"======== Resolving module 'foo' from '/a.ts'. ========",
3+
"Module resolution kind is not specified, using 'NodeJs'.",
4+
"Loading module 'foo' from 'node_modules' folder.",
5+
"File '/node_modules/foo.ts' does not exist.",
6+
"File '/node_modules/foo.tsx' does not exist.",
7+
"File '/node_modules/foo.d.ts' does not exist.",
8+
"Found 'package.json' at '/node_modules/foo/package.json'.",
9+
"'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.",
10+
"File '/node_modules/foo/foo.js' exist - use it as a name resolution result.",
11+
"File '/node_modules/foo/foo.js' has an unsupported extension, so skipping it.",
12+
"File '/node_modules/foo/foo.js.ts' does not exist.",
13+
"File '/node_modules/foo/foo.js.tsx' does not exist.",
14+
"File '/node_modules/foo/foo.js.d.ts' does not exist.",
15+
"File '/node_modules/foo/index.ts' does not exist.",
16+
"File '/node_modules/foo/index.tsx' does not exist.",
17+
"File '/node_modules/foo/index.d.ts' does not exist.",
18+
"File '/node_modules/@types/foo.d.ts' does not exist.",
19+
"File '/node_modules/@types/foo/package.json' does not exist.",
20+
"File '/node_modules/@types/foo/index.d.ts' does not exist.",
21+
"Loading module 'foo' from 'node_modules' folder.",
22+
"File '/node_modules/foo.js' does not exist.",
23+
"File '/node_modules/foo.jsx' does not exist.",
24+
"Found 'package.json' at '/node_modules/foo/package.json'.",
25+
"'package.json' does not have a 'types' or 'main' field.",
26+
"File '/node_modules/foo/index.js' does not exist.",
27+
"File '/node_modules/foo/index.jsx' does not exist.",
28+
"======== Module name 'foo' was not resolved. ========"
29+
]
Collapse file
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== /a.ts ===
2+
import "foo";
3+
No type information for this code.
4+
No type information for this code.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.