Merge pull request #13024 from Microsoft/package_json_unsupported_extension
Skip files from package.json "main" or "types" if they have an unsupported extension.
This commit is contained in:
commit
328a5ef2ba
12 changed files with 169 additions and 16 deletions
|
@ -2685,6 +2685,10 @@
|
|||
"category": "Message",
|
||||
"code": 6080
|
||||
},
|
||||
"File '{0}' has an unsupported extension, so skipping it.": {
|
||||
"category": "Message",
|
||||
"code": 6081
|
||||
},
|
||||
"Only 'amd' and 'system' modules are supported alongside --{0}.": {
|
||||
"category": "Error",
|
||||
"code": 6082
|
||||
|
|
|
@ -47,11 +47,6 @@ namespace ts {
|
|||
return resolved.path;
|
||||
}
|
||||
|
||||
/** Create Resolved from a file with unknown extension. */
|
||||
function resolvedFromAnyFile(path: string): Resolved | undefined {
|
||||
return { path, extension: extensionFromPath(path) };
|
||||
}
|
||||
|
||||
/** Adds `isExernalLibraryImport` to a Resolved to get a ResolvedModule. */
|
||||
function resolvedModuleFromResolved({ path, extension }: Resolved, isExternalLibraryImport: boolean): ResolvedModuleFull {
|
||||
return { resolvedFileName: path, extension, isExternalLibraryImport };
|
||||
|
@ -71,7 +66,8 @@ namespace ts {
|
|||
traceEnabled: boolean;
|
||||
}
|
||||
|
||||
function tryReadTypesSection(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
|
||||
/** Reads from "main" or "types"/"typings" depending on `extensions`. */
|
||||
function tryReadPackageJsonMainOrTypes(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
|
||||
const jsonContent = readJson(packageJsonPath, state.host);
|
||||
|
||||
switch (extensions) {
|
||||
|
@ -714,18 +710,21 @@ namespace ts {
|
|||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath);
|
||||
}
|
||||
const typesFile = tryReadTypesSection(extensions, packageJsonPath, candidate, state);
|
||||
if (typesFile) {
|
||||
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(typesFile), state.host);
|
||||
const mainOrTypesFile = tryReadPackageJsonMainOrTypes(extensions, packageJsonPath, candidate, state);
|
||||
if (mainOrTypesFile) {
|
||||
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(mainOrTypesFile), state.host);
|
||||
// A package.json "typings" may specify an exact filename, or may choose to omit an extension.
|
||||
const fromFile = tryFile(typesFile, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (fromFile) {
|
||||
// Note: this would allow a package.json to specify a ".js" file as typings. Maybe that should be forbidden.
|
||||
return resolvedFromAnyFile(fromFile);
|
||||
const fromExactFile = tryFile(mainOrTypesFile, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (fromExactFile) {
|
||||
const resolved = fromExactFile && resolvedIfExtensionMatches(extensions, fromExactFile);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromExactFile);
|
||||
}
|
||||
const x = tryAddingExtensions(typesFile, Extensions.TypeScript, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (x) {
|
||||
return x;
|
||||
const resolved = tryAddingExtensions(mainOrTypesFile, Extensions.TypeScript, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -745,6 +744,24 @@ namespace ts {
|
|||
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state);
|
||||
}
|
||||
|
||||
/** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
|
||||
function resolvedIfExtensionMatches(extensions: Extensions, path: string): Resolved | undefined {
|
||||
const extension = tryGetExtensionFromPath(path);
|
||||
return extension !== undefined && extensionIsOk(extensions, extension) ? { path, extension } : undefined;
|
||||
}
|
||||
|
||||
/** True if `extension` is one of the supported `extensions`. */
|
||||
function extensionIsOk(extensions: Extensions, extension: Extension): boolean {
|
||||
switch (extensions) {
|
||||
case Extensions.JavaScript:
|
||||
return extension === Extension.Js || extension === Extension.Jsx;
|
||||
case Extensions.TypeScript:
|
||||
return extension === Extension.Ts || extension === Extension.Tsx || extension === Extension.Dts;
|
||||
case Extensions.DtsOnly:
|
||||
return extension === Extension.Dts;
|
||||
}
|
||||
}
|
||||
|
||||
function pathToPackageJson(directory: string): string {
|
||||
return combinePaths(directory, "package.json");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
//// [tests/cases/compiler/moduleResolutionWithExtensions_unexpected.ts] ////
|
||||
|
||||
//// [normalize.css]
|
||||
// This tests that a package.json "main" with an unexpected extension is ignored.
|
||||
|
||||
This file is not read.
|
||||
|
||||
//// [package.json]
|
||||
{ "main": "normalize.css" }
|
||||
|
||||
//// [a.ts]
|
||||
import "normalize.css";
|
||||
|
||||
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
require("normalize.css");
|
|
@ -0,0 +1,4 @@
|
|||
=== /a.ts ===
|
||||
import "normalize.css";
|
||||
No type information for this code.
|
||||
No type information for this code.
|
|
@ -0,0 +1,29 @@
|
|||
[
|
||||
"======== Resolving module 'normalize.css' from '/a.ts'. ========",
|
||||
"Module resolution kind is not specified, using 'NodeJs'.",
|
||||
"Loading module 'normalize.css' from 'node_modules' folder.",
|
||||
"File '/node_modules/normalize.css.ts' does not exist.",
|
||||
"File '/node_modules/normalize.css.tsx' does not exist.",
|
||||
"File '/node_modules/normalize.css.d.ts' does not exist.",
|
||||
"Found 'package.json' at '/node_modules/normalize.css/package.json'.",
|
||||
"'package.json' does not have a 'types' or 'main' field.",
|
||||
"File '/node_modules/normalize.css/index.ts' does not exist.",
|
||||
"File '/node_modules/normalize.css/index.tsx' does not exist.",
|
||||
"File '/node_modules/normalize.css/index.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/normalize.css.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/normalize.css/package.json' does not exist.",
|
||||
"File '/node_modules/@types/normalize.css/index.d.ts' does not exist.",
|
||||
"Loading module 'normalize.css' from 'node_modules' folder.",
|
||||
"File '/node_modules/normalize.css.js' does not exist.",
|
||||
"File '/node_modules/normalize.css.jsx' does not exist.",
|
||||
"Found 'package.json' at '/node_modules/normalize.css/package.json'.",
|
||||
"No types specified in 'package.json', so returning 'main' value of 'normalize.css'",
|
||||
"File '/node_modules/normalize.css/normalize.css' exist - use it as a name resolution result.",
|
||||
"File '/node_modules/normalize.css/normalize.css' has an unsupported extension, so skipping it.",
|
||||
"File '/node_modules/normalize.css/normalize.css.ts' does not exist.",
|
||||
"File '/node_modules/normalize.css/normalize.css.tsx' does not exist.",
|
||||
"File '/node_modules/normalize.css/normalize.css.d.ts' does not exist.",
|
||||
"File '/node_modules/normalize.css/index.js' does not exist.",
|
||||
"File '/node_modules/normalize.css/index.jsx' does not exist.",
|
||||
"======== Module name 'normalize.css' was not resolved. ========"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
=== /a.ts ===
|
||||
import "normalize.css";
|
||||
No type information for this code.
|
||||
No type information for this code.
|
|
@ -0,0 +1,17 @@
|
|||
//// [tests/cases/compiler/moduleResolutionWithExtensions_unexpected2.ts] ////
|
||||
|
||||
//// [foo.js]
|
||||
// This tests that a package.json "types" with an unexpected extension is ignored.
|
||||
|
||||
This file is not read.
|
||||
|
||||
//// [package.json]
|
||||
{ "types": "foo.js" }
|
||||
|
||||
//// [a.ts]
|
||||
import "foo";
|
||||
|
||||
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
require("foo");
|
|
@ -0,0 +1,4 @@
|
|||
=== /a.ts ===
|
||||
import "foo";
|
||||
No type information for this code.
|
||||
No type information for this code.
|
|
@ -0,0 +1,29 @@
|
|||
[
|
||||
"======== Resolving module 'foo' from '/a.ts'. ========",
|
||||
"Module resolution kind is not specified, using 'NodeJs'.",
|
||||
"Loading module 'foo' from 'node_modules' folder.",
|
||||
"File '/node_modules/foo.ts' does not exist.",
|
||||
"File '/node_modules/foo.tsx' does not exist.",
|
||||
"File '/node_modules/foo.d.ts' does not exist.",
|
||||
"Found 'package.json' at '/node_modules/foo/package.json'.",
|
||||
"'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.",
|
||||
"File '/node_modules/foo/foo.js' exist - use it as a name resolution result.",
|
||||
"File '/node_modules/foo/foo.js' has an unsupported extension, so skipping it.",
|
||||
"File '/node_modules/foo/foo.js.ts' does not exist.",
|
||||
"File '/node_modules/foo/foo.js.tsx' does not exist.",
|
||||
"File '/node_modules/foo/foo.js.d.ts' does not exist.",
|
||||
"File '/node_modules/foo/index.ts' does not exist.",
|
||||
"File '/node_modules/foo/index.tsx' does not exist.",
|
||||
"File '/node_modules/foo/index.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/foo.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/foo/package.json' does not exist.",
|
||||
"File '/node_modules/@types/foo/index.d.ts' does not exist.",
|
||||
"Loading module 'foo' from 'node_modules' folder.",
|
||||
"File '/node_modules/foo.js' does not exist.",
|
||||
"File '/node_modules/foo.jsx' does not exist.",
|
||||
"Found 'package.json' at '/node_modules/foo/package.json'.",
|
||||
"'package.json' does not have a 'types' or 'main' field.",
|
||||
"File '/node_modules/foo/index.js' does not exist.",
|
||||
"File '/node_modules/foo/index.jsx' does not exist.",
|
||||
"======== Module name 'foo' was not resolved. ========"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
=== /a.ts ===
|
||||
import "foo";
|
||||
No type information for this code.
|
||||
No type information for this code.
|
|
@ -0,0 +1,12 @@
|
|||
// @noImplicitReferences: true
|
||||
// @traceResolution: true
|
||||
// This tests that a package.json "main" with an unexpected extension is ignored.
|
||||
|
||||
// @Filename: /node_modules/normalize.css/normalize.css
|
||||
This file is not read.
|
||||
|
||||
// @Filename: /node_modules/normalize.css/package.json
|
||||
{ "main": "normalize.css" }
|
||||
|
||||
// @Filename: /a.ts
|
||||
import "normalize.css";
|
|
@ -0,0 +1,12 @@
|
|||
// @noImplicitReferences: true
|
||||
// @traceResolution: true
|
||||
// This tests that a package.json "types" with an unexpected extension is ignored.
|
||||
|
||||
// @Filename: /node_modules/foo/foo.js
|
||||
This file is not read.
|
||||
|
||||
// @Filename: /node_modules/foo/package.json
|
||||
{ "types": "foo.js" }
|
||||
|
||||
// @Filename: /a.ts
|
||||
import "foo";
|
Loading…
Reference in a new issue