mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-16 07:13:45 -05:00
Merge pull request #31541 from microsoft/packageId
Always use resolved file to figure out subModule name in package id
This commit is contained in:
@@ -3811,10 +3811,6 @@
|
||||
"category": "Error",
|
||||
"code": 6189
|
||||
},
|
||||
"Found 'package.json' at '{0}'. Package ID is '{1}'.": {
|
||||
"category": "Message",
|
||||
"code": 6190
|
||||
},
|
||||
"Whether to keep outdated console output in watch mode instead of clearing the screen.": {
|
||||
"category": "Message",
|
||||
"code": 6191
|
||||
@@ -3923,6 +3919,14 @@
|
||||
"category": "Message",
|
||||
"code": 6217
|
||||
},
|
||||
"======== Module name '{0}' was successfully resolved to '{1}' with Package ID '{2}'. ========": {
|
||||
"category": "Message",
|
||||
"code": 6218
|
||||
},
|
||||
"======== Type reference directive '{0}' was successfully resolved to '{1}' with Package ID '{2}', primary: {3}. ========": {
|
||||
"category": "Message",
|
||||
"code": 6219
|
||||
},
|
||||
|
||||
"Projects to reference": {
|
||||
"category": "Message",
|
||||
@@ -4975,7 +4979,7 @@
|
||||
"code": 95079
|
||||
},
|
||||
|
||||
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer." :{
|
||||
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
|
||||
"category": "Error",
|
||||
"code": 18004
|
||||
},
|
||||
|
||||
@@ -16,12 +16,23 @@ namespace ts {
|
||||
push(value: T): void;
|
||||
}
|
||||
|
||||
function withPackageId(packageId: PackageId | undefined, r: PathAndExtension | undefined): Resolved | undefined {
|
||||
function withPackageId(packageInfo: PackageJsonInfo | undefined, r: PathAndExtension | undefined): Resolved | undefined {
|
||||
let packageId: PackageId | undefined;
|
||||
if (r && packageInfo) {
|
||||
const packageJsonContent = packageInfo.packageJsonContent as PackageJson;
|
||||
if (typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string") {
|
||||
packageId = {
|
||||
name: packageJsonContent.name,
|
||||
subModuleName: r.path.slice(packageInfo.packageDirectory.length + directorySeparator.length),
|
||||
version: packageJsonContent.version
|
||||
};
|
||||
}
|
||||
}
|
||||
return r && { path: r.path, extension: r.ext, packageId };
|
||||
}
|
||||
|
||||
function noPackageId(r: PathAndExtension | undefined): Resolved | undefined {
|
||||
return withPackageId(/*packageId*/ undefined, r);
|
||||
return withPackageId(/*packageInfo*/ undefined, r);
|
||||
}
|
||||
|
||||
function removeIgnoredPackageId(r: Resolved | undefined): PathAndExtension | undefined {
|
||||
@@ -307,7 +318,12 @@ namespace ts {
|
||||
const { fileName, packageId } = resolved;
|
||||
const resolvedFileName = options.preserveSymlinks ? fileName : realPath(fileName, host, traceEnabled);
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFileName, primary);
|
||||
if (packageId) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3, typeReferenceDirectiveName, resolvedFileName, packageIdToString(packageId), primary);
|
||||
}
|
||||
else {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFileName, primary);
|
||||
}
|
||||
}
|
||||
resolvedTypeReferenceDirective = { primary, resolvedFileName, packageId, isExternalLibraryImport: pathContainsNodeModules(fileName) };
|
||||
}
|
||||
@@ -663,7 +679,12 @@ namespace ts {
|
||||
|
||||
if (traceEnabled) {
|
||||
if (result.resolvedModule) {
|
||||
trace(host, Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName);
|
||||
if (result.resolvedModule.packageId) {
|
||||
trace(host, Diagnostics.Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2, moduleName, result.resolvedModule.resolvedFileName, packageIdToString(result.resolvedModule.packageId));
|
||||
}
|
||||
else {
|
||||
trace(host, Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
trace(host, Diagnostics.Module_name_0_was_not_resolved, moduleName);
|
||||
@@ -968,10 +989,9 @@ namespace ts {
|
||||
}
|
||||
const resolvedFromFile = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state);
|
||||
if (resolvedFromFile) {
|
||||
const nm = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile) : undefined;
|
||||
const packageInfo = nm && getPackageJsonInfo(nm.packageDirectory, nm.subModuleName, /*onlyRecordFailures*/ false, state);
|
||||
const packageId = packageInfo && packageInfo.packageId;
|
||||
return withPackageId(packageId, resolvedFromFile);
|
||||
const packageDirectory = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile) : undefined;
|
||||
const packageInfo = packageDirectory ? getPackageJsonInfo(packageDirectory, /*onlyRecordFailures*/ false, state) : undefined;
|
||||
return withPackageId(packageInfo, resolvedFromFile);
|
||||
}
|
||||
}
|
||||
if (!onlyRecordFailures) {
|
||||
@@ -998,13 +1018,12 @@ namespace ts {
|
||||
* (Not neeeded for `loadModuleFromNodeModules` as that looks up the `package.json` as part of resolution.)
|
||||
*
|
||||
* packageDirectory is the directory of the package itself.
|
||||
* subModuleName is the path within the package.
|
||||
* For `blah/node_modules/foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "index.d.ts" }. (Part before "/node_modules/" is ignored.)
|
||||
* For `/node_modules/foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar/index.d.ts" }.
|
||||
* For `/node_modules/@types/foo/bar/index.d.ts` this is { packageDirectory: "@types/foo", subModuleName: "bar/index.d.ts" }.
|
||||
* For `/node_modules/foo/bar/index.d.ts` this is { packageDirectory: "foo", subModuleName": "bar/index.d.ts" }.
|
||||
* For `blah/node_modules/foo/index.d.ts` this is packageDirectory: "foo"
|
||||
* For `/node_modules/foo/bar.d.ts` this is packageDirectory: "foo"
|
||||
* For `/node_modules/@types/foo/bar/index.d.ts` this is packageDirectory: "@types/foo"
|
||||
* For `/node_modules/foo/bar/index.d.ts` this is packageDirectory: "foo"
|
||||
*/
|
||||
function parseNodeModuleFromPath(resolved: PathAndExtension): { packageDirectory: string, subModuleName: string } | undefined {
|
||||
function parseNodeModuleFromPath(resolved: PathAndExtension): string | undefined {
|
||||
const path = normalizePath(resolved.path);
|
||||
const idx = path.lastIndexOf(nodeModulesPathPart);
|
||||
if (idx === -1) {
|
||||
@@ -1016,9 +1035,7 @@ namespace ts {
|
||||
if (path.charCodeAt(indexAfterNodeModules) === CharacterCodes.at) {
|
||||
indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName);
|
||||
}
|
||||
const packageDirectory = path.slice(0, indexAfterPackageName);
|
||||
const subModuleName = removeExtension(path.slice(indexAfterPackageName + 1), resolved.ext) + Extension.Dts;
|
||||
return { packageDirectory, subModuleName };
|
||||
return path.slice(0, indexAfterPackageName);
|
||||
}
|
||||
|
||||
function moveToNextDirectorySeparatorIfAvailable(path: string, prevSeparatorIndex: number): number {
|
||||
@@ -1026,19 +1043,6 @@ namespace ts {
|
||||
return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex;
|
||||
}
|
||||
|
||||
function addExtensionAndIndex(path: string): string {
|
||||
if (path === "") {
|
||||
return "index.d.ts";
|
||||
}
|
||||
if (endsWith(path, ".d.ts")) {
|
||||
return path;
|
||||
}
|
||||
if (path === "index" || endsWith(path, "/index")) {
|
||||
return path + ".d.ts";
|
||||
}
|
||||
return path + "/index.d.ts";
|
||||
}
|
||||
|
||||
function loadModuleFromFileNoPackageId(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
|
||||
return noPackageId(loadModuleFromFile(extensions, candidate, onlyRecordFailures, state));
|
||||
}
|
||||
@@ -1119,61 +1123,29 @@ namespace ts {
|
||||
}
|
||||
|
||||
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true) {
|
||||
const packageInfo = considerPackageJson ? getPackageJsonInfo(candidate, "", onlyRecordFailures, state) : undefined;
|
||||
const packageId = packageInfo && packageInfo.packageId;
|
||||
const packageInfo = considerPackageJson ? getPackageJsonInfo(candidate, onlyRecordFailures, state) : undefined;
|
||||
const packageJsonContent = packageInfo && packageInfo.packageJsonContent;
|
||||
const versionPaths = packageInfo && packageInfo.versionPaths;
|
||||
return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths));
|
||||
return withPackageId(packageInfo, loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths));
|
||||
}
|
||||
|
||||
interface PackageJsonInfo {
|
||||
packageJsonContent: PackageJsonPathFields | undefined;
|
||||
packageId: PackageId | undefined;
|
||||
packageDirectory: string;
|
||||
packageJsonContent: PackageJsonPathFields;
|
||||
versionPaths: VersionPaths | undefined;
|
||||
}
|
||||
|
||||
function getPackageJsonInfo(packageDirectory: string, subModuleName: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PackageJsonInfo | undefined {
|
||||
function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PackageJsonInfo | undefined {
|
||||
const { host, traceEnabled } = state;
|
||||
const directoryExists = !onlyRecordFailures && directoryProbablyExists(packageDirectory, host);
|
||||
const packageJsonPath = combinePaths(packageDirectory, "package.json");
|
||||
if (directoryExists && host.fileExists(packageJsonPath)) {
|
||||
const packageJsonContent = readJson(packageJsonPath, host) as PackageJson;
|
||||
if (subModuleName === "") { // looking up the root - need to handle types/typings/main redirects for subModuleName
|
||||
const path = readPackageJsonTypesFields(packageJsonContent, packageDirectory, state);
|
||||
if (typeof path === "string") {
|
||||
subModuleName = addExtensionAndIndex(path.substring(packageDirectory.length + 1));
|
||||
}
|
||||
else {
|
||||
const jsPath = readPackageJsonMainField(packageJsonContent, packageDirectory, state);
|
||||
if (typeof jsPath === "string" && jsPath.length > packageDirectory.length) {
|
||||
const potentialSubModule = jsPath.substring(packageDirectory.length + 1);
|
||||
subModuleName = (forEach(supportedJSExtensions, extension =>
|
||||
tryRemoveExtension(potentialSubModule, extension)) || potentialSubModule) + Extension.Dts;
|
||||
}
|
||||
else {
|
||||
subModuleName = "index.d.ts";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!endsWith(subModuleName, Extension.Dts)) {
|
||||
subModuleName = addExtensionAndIndex(subModuleName);
|
||||
}
|
||||
|
||||
const versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state);
|
||||
const packageId: PackageId | undefined = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string"
|
||||
? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version }
|
||||
: undefined;
|
||||
if (traceEnabled) {
|
||||
if (packageId) {
|
||||
trace(host, Diagnostics.Found_package_json_at_0_Package_ID_is_1, packageJsonPath, packageIdToString(packageId));
|
||||
}
|
||||
else {
|
||||
trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath);
|
||||
}
|
||||
trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath);
|
||||
}
|
||||
|
||||
return { packageJsonContent, packageId, versionPaths };
|
||||
const versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state);
|
||||
return { packageDirectory, packageJsonContent, versionPaths };
|
||||
}
|
||||
else {
|
||||
if (directoryExists && traceEnabled) {
|
||||
@@ -1328,27 +1300,36 @@ namespace ts {
|
||||
const candidate = normalizePath(combinePaths(nodeModulesDirectory, moduleName));
|
||||
|
||||
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
|
||||
let packageJsonContent: PackageJsonPathFields | undefined;
|
||||
let packageId: PackageId | undefined;
|
||||
let versionPaths: VersionPaths | undefined;
|
||||
|
||||
const packageInfo = getPackageJsonInfo(candidate, "", !nodeModulesDirectoryExists, state);
|
||||
let packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state);
|
||||
if (packageInfo) {
|
||||
({ packageJsonContent, packageId, versionPaths } = packageInfo);
|
||||
const fromFile = loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state);
|
||||
if (fromFile) {
|
||||
return noPackageId(fromFile);
|
||||
}
|
||||
|
||||
const fromDirectory = loadNodeModuleFromDirectoryWorker(extensions, candidate, !nodeModulesDirectoryExists, state, packageJsonContent, versionPaths);
|
||||
return withPackageId(packageId, fromDirectory);
|
||||
const fromDirectory = loadNodeModuleFromDirectoryWorker(
|
||||
extensions,
|
||||
candidate,
|
||||
!nodeModulesDirectoryExists,
|
||||
state,
|
||||
packageInfo.packageJsonContent,
|
||||
packageInfo.versionPaths
|
||||
);
|
||||
return withPackageId(packageInfo, fromDirectory);
|
||||
}
|
||||
|
||||
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => {
|
||||
const pathAndExtension =
|
||||
loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) ||
|
||||
loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths);
|
||||
return withPackageId(packageId, pathAndExtension);
|
||||
loadNodeModuleFromDirectoryWorker(
|
||||
extensions,
|
||||
candidate,
|
||||
onlyRecordFailures,
|
||||
state,
|
||||
packageInfo && packageInfo.packageJsonContent,
|
||||
packageInfo && packageInfo.versionPaths
|
||||
);
|
||||
return withPackageId(packageInfo, pathAndExtension);
|
||||
};
|
||||
|
||||
const { packageName, rest } = parsePackageName(moduleName);
|
||||
@@ -1356,14 +1337,13 @@ namespace ts {
|
||||
const packageDirectory = combinePaths(nodeModulesDirectory, packageName);
|
||||
|
||||
// Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings.
|
||||
const packageInfo = getPackageJsonInfo(packageDirectory, rest, !nodeModulesDirectoryExists, state);
|
||||
if (packageInfo) ({ packageId, versionPaths } = packageInfo);
|
||||
if (versionPaths) {
|
||||
packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state);
|
||||
if (packageInfo && packageInfo.versionPaths) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, version, rest);
|
||||
trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, packageInfo.versionPaths.version, version, rest);
|
||||
}
|
||||
const packageDirectoryExists = nodeModulesDirectoryExists && directoryProbablyExists(packageDirectory, state.host);
|
||||
const fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, versionPaths.paths, loader, !packageDirectoryExists, state);
|
||||
const fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, packageInfo.versionPaths.paths, loader, !packageDirectoryExists, state);
|
||||
if (fromPaths) {
|
||||
return fromPaths.value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user