(lshost): run second module resolution pass if first pass yielded non-ts file (#10959)

* (lshost): run second module resolution pass if first pass yielded non-ts file

* use length check
This commit is contained in:
Vladimir Matveev 2016-09-16 15:49:20 -07:00 committed by GitHub
parent 4668c99222
commit 121b04ee36
2 changed files with 41 additions and 3 deletions

View file

@ -1881,4 +1881,32 @@ namespace ts.projectSystem {
projectService.checkNumberOfProjects({});
});
});
describe("prefer typings to js", () => {
it("during second resolution pass", () => {
const typingsCacheLocation = "/a/typings";
const f1 = {
path: "/a/b/app.js",
content: "var x = require('bar')"
};
const barjs = {
path: "/a/b/node_modules/bar/index.js",
content: "export let x = 1"
};
const barTypings = {
path: `${typingsCacheLocation}/node_modules/@types/bar/index.d.ts`,
content: "export let y: number"
};
const config = {
path: "/a/b/jsconfig.json",
content: JSON.stringify({ compilerOptions: { allowJs: true }, exclude: ["node_modules"] })
};
const host = createServerHost([f1, barjs, barTypings, config]);
const projectService = createProjectService(host, { typingsInstaller: new TestTypingsInstaller(typingsCacheLocation, host) });
projectService.openClientFile(f1.path);
projectService.checkNumberOfProjects({ configuredProjects: 1 });
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path, barTypings.path]);
});
});
}

View file

@ -24,8 +24,15 @@ namespace ts.server {
this.resolveModuleName = (moduleName, containingFile, compilerOptions, host) => {
const primaryResult = resolveModuleName(moduleName, containingFile, compilerOptions, host);
if (primaryResult.resolvedModule) {
return primaryResult;
// return result immediately only if it is .ts, .tsx or .d.ts
// otherwise try to load typings from @types
if (fileExtensionIsAny(primaryResult.resolvedModule.resolvedFileName, supportedTypeScriptExtensions)) {
return primaryResult;
}
}
// create different collection of failed lookup locations for second pass
// if it will fail and we've already found something during the first pass - we don't want to pollute its results
const secondaryLookupFailedLookupLocations: string[] = [];
const globalCache = this.project.projectService.typingsInstaller.globalTypingsCacheLocation;
if (this.project.getTypingOptions().enableAutoDiscovery && globalCache) {
const traceEnabled = isTraceEnabled(compilerOptions, host);
@ -33,11 +40,14 @@ namespace ts.server {
trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, this.project.getProjectName(), moduleName, globalCache);
}
const state: ModuleResolutionState = { compilerOptions, host, skipTsx: false, traceEnabled };
const resolvedName = loadModuleFromNodeModules(moduleName, globalCache, primaryResult.failedLookupLocations, state, /*checkOneLevel*/ true);
const resolvedName = loadModuleFromNodeModules(moduleName, globalCache, secondaryLookupFailedLookupLocations, state, /*checkOneLevel*/ true);
if (resolvedName) {
return createResolvedModule(resolvedName, /*isExternalLibraryImport*/ true, primaryResult.failedLookupLocations);
return createResolvedModule(resolvedName, /*isExternalLibraryImport*/ true, primaryResult.failedLookupLocations.concat(secondaryLookupFailedLookupLocations));
}
}
if (!primaryResult.resolvedModule && secondaryLookupFailedLookupLocations.length) {
primaryResult.failedLookupLocations = primaryResult.failedLookupLocations.concat(secondaryLookupFailedLookupLocations);
}
return primaryResult;
};
}