Handle package.json watch in tsc and tsserver. (#49328)

* refactoring

* Maintain packagejson paths per resolution so we dont have invalidate everything on package json change

* Fix todo
This commit is contained in:
Sheetal Nandi
2022-06-08 10:22:29 -07:00
committed by GitHub
parent b8f6488323
commit 5cedf3e680
85 changed files with 1974 additions and 550 deletions
+72 -8
View File
@@ -86,15 +86,24 @@ namespace ts {
return { fileName: resolved.path, packageId: resolved.packageId };
}
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean | undefined, failedLookupLocations: string[], diagnostics: Diagnostic[], resultFromCache: ResolvedModuleWithFailedLookupLocations | undefined): ResolvedModuleWithFailedLookupLocations {
function createResolvedModuleWithFailedLookupLocations(
resolved: Resolved | undefined,
isExternalLibraryImport: boolean | undefined,
failedLookupLocations: string[],
affectingLocations: string[],
diagnostics: Diagnostic[],
resultFromCache: ResolvedModuleWithFailedLookupLocations | undefined
): ResolvedModuleWithFailedLookupLocations {
if (resultFromCache) {
resultFromCache.failedLookupLocations.push(...failedLookupLocations);
resultFromCache.affectingLocations.push(...affectingLocations);
return resultFromCache;
}
return {
resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath: resolved.originalPath === true ? undefined : resolved.originalPath, extension: resolved.extension, isExternalLibraryImport, packageId: resolved.packageId },
failedLookupLocations,
resolutionDiagnostics: diagnostics
affectingLocations,
resolutionDiagnostics: diagnostics,
};
}
@@ -104,6 +113,7 @@ namespace ts {
compilerOptions: CompilerOptions;
traceEnabled: boolean;
failedLookupLocations: Push<string>;
affectingLocations: Push<string>;
resultFromCache?: ResolvedModuleWithFailedLookupLocations;
packageJsonInfoCache: PackageJsonInfoCache | undefined;
features: NodeResolutionFeatures;
@@ -345,6 +355,7 @@ namespace ts {
}
const failedLookupLocations: string[] = [];
const affectingLocations: string[] = [];
let features = getDefaultNodeResolutionFeatures(options);
// Unlike `import` statements, whose mode-calculating APIs are all guaranteed to return `undefined` if we're in an un-mode-ed module resolution
// setting, type references will return their target mode regardless of options because of how the parser works, so we guard against the mode being
@@ -363,6 +374,7 @@ namespace ts {
host,
traceEnabled,
failedLookupLocations,
affectingLocations,
packageJsonInfoCache: cache,
features,
conditions,
@@ -388,7 +400,7 @@ namespace ts {
isExternalLibraryImport: pathContainsNodeModules(fileName),
};
}
result = { resolvedTypeReferenceDirective, failedLookupLocations, resolutionDiagnostics: diagnostics };
result = { resolvedTypeReferenceDirective, failedLookupLocations, affectingLocations, resolutionDiagnostics: diagnostics };
perFolderCache?.set(typeReferenceDirectiveName, /*mode*/ resolutionMode, result);
if (traceEnabled) traceResult(result);
return result;
@@ -479,6 +491,7 @@ namespace ts {
host,
traceEnabled: isTraceEnabled(options, host),
failedLookupLocations: [],
affectingLocations: [],
packageJsonInfoCache: cache?.getPackageJsonInfoCache(),
conditions: emptyArray,
features: NodeResolutionFeatures.None,
@@ -1330,6 +1343,7 @@ namespace ts {
const traceEnabled = isTraceEnabled(compilerOptions, host);
const failedLookupLocations: string[] = [];
const affectingLocations: string[] = [];
// conditions are only used by the node16/nodenext resolver - there's no priority order in the list,
//it's essentially a set (priority is determined by object insertion order in the object we look at).
const conditions = features & NodeResolutionFeatures.EsmMode ? ["node", "import", "types"] : ["node", "require", "types"];
@@ -1343,6 +1357,7 @@ namespace ts {
host,
traceEnabled,
failedLookupLocations,
affectingLocations,
packageJsonInfoCache: cache,
features,
conditions,
@@ -1351,7 +1366,14 @@ namespace ts {
};
const result = forEach(extensions, ext => tryResolve(ext));
return createResolvedModuleWithFailedLookupLocations(result?.value?.resolved, result?.value?.isExternalLibraryImport, failedLookupLocations, diagnostics, state.resultFromCache);
return createResolvedModuleWithFailedLookupLocations(
result?.value?.resolved,
result?.value?.isExternalLibraryImport,
failedLookupLocations,
affectingLocations,
diagnostics,
state.resultFromCache
);
function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> {
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ true);
@@ -1675,6 +1697,7 @@ namespace ts {
host,
traceEnabled: isTraceEnabled(options, host),
failedLookupLocations: [],
affectingLocations: [],
packageJsonInfoCache: cache?.getPackageJsonInfoCache(),
conditions: ["node", "require", "types"],
features,
@@ -1785,6 +1808,7 @@ namespace ts {
compilerOptions: CompilerOptions;
traceEnabled: boolean;
failedLookupLocations: Push<string>;
affectingLocations: Push<string>;
resultFromCache?: ResolvedModuleWithFailedLookupLocations;
packageJsonInfoCache: PackageJsonInfoCache | undefined;
features: number;
@@ -1796,6 +1820,7 @@ namespace ts {
compilerOptions: options,
traceEnabled: isTraceEnabled(options, host),
failedLookupLocations: [],
affectingLocations: [],
packageJsonInfoCache,
features: 0,
conditions: [],
@@ -1827,6 +1852,7 @@ namespace ts {
if (existing !== undefined) {
if (typeof existing !== "boolean") {
if (traceEnabled) trace(host, Diagnostics.File_0_exists_according_to_earlier_cached_lookups, packageJsonPath);
state.affectingLocations.push(packageJsonPath);
return existing;
}
else {
@@ -1844,6 +1870,7 @@ namespace ts {
const versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state);
const result = { packageDirectory, packageJsonContent, versionPaths, resolvedEntrypoints: undefined };
state.packageJsonInfoCache?.setPackageJsonInfo(packageJsonPath, result);
state.affectingLocations.push(packageJsonPath);
return result;
}
else {
@@ -2550,13 +2577,31 @@ namespace ts {
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(compilerOptions, host);
const failedLookupLocations: string[] = [];
const affectingLocations: string[] = [];
const containingDirectory = getDirectoryPath(containingFile);
const diagnostics: Diagnostic[] = [];
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache: cache, features: NodeResolutionFeatures.None, conditions: [], requestContainingDirectory: containingDirectory, reportDiagnostic: diag => void diagnostics.push(diag) };
const state: ModuleResolutionState = {
compilerOptions,
host,
traceEnabled,
failedLookupLocations,
affectingLocations, packageJsonInfoCache: cache,
features: NodeResolutionFeatures.None,
conditions: [],
requestContainingDirectory: containingDirectory,
reportDiagnostic: diag => void diagnostics.push(diag),
};
const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
// No originalPath because classic resolution doesn't resolve realPath
return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations, diagnostics, state.resultFromCache);
return createResolvedModuleWithFailedLookupLocations(
resolved && resolved.value,
/*isExternalLibraryImport*/ false,
failedLookupLocations,
affectingLocations,
diagnostics,
state.resultFromCache
);
function tryResolve(extensions: Extensions): SearchResult<Resolved> {
const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, state);
@@ -2601,10 +2646,29 @@ namespace ts {
trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
}
const failedLookupLocations: string[] = [];
const affectingLocations: string[] = [];
const diagnostics: Diagnostic[] = [];
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache, features: NodeResolutionFeatures.None, conditions: [], requestContainingDirectory: undefined, reportDiagnostic: diag => void diagnostics.push(diag) };
const state: ModuleResolutionState = {
compilerOptions,
host,
traceEnabled,
failedLookupLocations,
affectingLocations,
packageJsonInfoCache,
features: NodeResolutionFeatures.None,
conditions: [],
requestContainingDirectory: undefined,
reportDiagnostic: diag => void diagnostics.push(diag),
};
const resolved = loadModuleFromImmediateNodeModulesDirectory(Extensions.DtsOnly, moduleName, globalCache, state, /*typesScopeOnly*/ false, /*cache*/ undefined, /*redirectedReference*/ undefined);
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations, diagnostics, state.resultFromCache);
return createResolvedModuleWithFailedLookupLocations(
resolved,
/*isExternalLibraryImport*/ true,
failedLookupLocations,
affectingLocations,
diagnostics,
state.resultFromCache
);
}
/**