Skip to content

Commit

Permalink
chore(typescript) support node_modules lookup natively.
Browse files Browse the repository at this point in the history
  • Loading branch information
basarat committed Aug 20, 2015
1 parent 5fa52d0 commit 1c82c69
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
53 changes: 53 additions & 0 deletions dist/main/lang/core/languageServiceHost2.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,63 @@ var LanguageServiceHost = (function () {
return _this.config.projectFileDirectory;
};
this.getDefaultLibFileName = ts.getDefaultLibFileName;
this.resolvedExternalModuleCache = {};
if (!config.project.compilerOptions.noLib) {
this.addScript(exports.getDefaultLibFilePath(config.project.compilerOptions));
}
}
LanguageServiceHost.prototype.resolveModuleNames = function (moduleNames, containingFile) {
var _this = this;
return moduleNames.map(function (x) { return _this.resolveExternalModule(x, containingFile); });
};
LanguageServiceHost.prototype.resolveExternalModule = function (moduleName, containingFile) {
var normalizePath = ts.normalizePath;
var combinePaths = ts.combinePaths;
var removeFileExtension = ts.removeFileExtension;
var getDirectoryPath = ts.getDirectoryPath;
var forEach = ts.forEach;
var supportedExtensions = ts.supportedExtensions;
var cacheLookupName = moduleName + containingFile;
if (this.resolvedExternalModuleCache[cacheLookupName]) {
return this.resolvedExternalModuleCache[cacheLookupName];
}
if (this.resolvedExternalModuleCache[cacheLookupName] === '') {
return undefined;
}
function getNameIfExists(fileName) {
if (fs.existsSync(fileName)) {
return fileName;
}
}
while (true) {
var found = ts.forEach(ts.supportedExtensions, function (extension) { return getNameIfExists(ts.normalizePath(ts.combinePaths(containingFile, moduleName)) + extension); });
if (!found) {
found = ts.forEach(ts.supportedExtensions, function (extension) { return getNameIfExists(ts.normalizePath(ts.combinePaths(ts.combinePaths(containingFile, "node_modules"), moduleName)) + extension); });
}
if (!found) {
var pkgJson = getNameIfExists(normalizePath(combinePaths(combinePaths(combinePaths(containingFile, "node_modules"), moduleName), "package.json")));
if (pkgJson) {
var pkgFile = JSON.parse(fs.readFileSync(pkgJson, 'utf8'));
if (pkgFile.main) {
var indexFileName = removeFileExtension(combinePaths(getDirectoryPath(pkgJson), pkgFile.main));
found = forEach(supportedExtensions, function (extension) { return getNameIfExists(indexFileName + extension); });
}
}
}
if (!found) {
found = forEach(supportedExtensions, function (extension) { return getNameIfExists(normalizePath(combinePaths(combinePaths(combinePaths(containingFile, "node_modules"), moduleName), "index")) + extension); });
}
if (found) {
return this.resolvedExternalModuleCache[cacheLookupName] = found;
}
var parentPath = getDirectoryPath(containingFile);
if (parentPath === containingFile) {
this.resolvedExternalModuleCache[cacheLookupName] = '';
return undefined;
}
containingFile = parentPath;
}
};
return LanguageServiceHost;
})();
exports.LanguageServiceHost = LanguageServiceHost;
70 changes: 70 additions & 0 deletions lib/main/lang/core/languageServiceHost2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,4 +360,74 @@ export class LanguageServiceHost implements ts.LanguageServiceHost {
return this.config.projectFileDirectory;
}
getDefaultLibFileName = ts.getDefaultLibFileName;

resolveModuleNames(moduleNames: string[], containingFile: string): string[] {
return moduleNames.map(x=> this.resolveExternalModule(x, containingFile));
}

/**
* node_modules resolution logic
* Code from https://github.com/Microsoft/TypeScript/pull/3147/files
*/
resolvedExternalModuleCache: ts.Map<string> = {};
resolveExternalModule(moduleName: string, containingFile: string): string {
let normalizePath = ts.normalizePath;
let combinePaths = ts.combinePaths;
let removeFileExtension = ts.removeFileExtension;
let getDirectoryPath = ts.getDirectoryPath;
let forEach = ts.forEach;
let supportedExtensions = ts.supportedExtensions;

let cacheLookupName = moduleName + containingFile;
if (this.resolvedExternalModuleCache[cacheLookupName]) {
return this.resolvedExternalModuleCache[cacheLookupName];
}
if (this.resolvedExternalModuleCache[cacheLookupName] === '') {
return undefined;
}
function getNameIfExists(fileName: string): string {
if (fs.existsSync(fileName)) {
return fileName;
}
}
while (true) {
// Look at files by all extensions
let found = ts.forEach(ts.supportedExtensions,
extension => getNameIfExists(ts.normalizePath(ts.combinePaths(containingFile, moduleName)) + extension));
// Also look at all files by node_modules
if (!found) {
found = ts.forEach(ts.supportedExtensions,
extension => getNameIfExists(ts.normalizePath(ts.combinePaths(ts.combinePaths(containingFile, "node_modules"), moduleName)) + extension));
}
// Also look at package.json's main in node_modules
if (!found) {
// If we found a package.json then look at its main field
let pkgJson = getNameIfExists(normalizePath(combinePaths(combinePaths(combinePaths(containingFile, "node_modules"), moduleName), "package.json")));
if (pkgJson) {
let pkgFile = JSON.parse(fs.readFileSync(pkgJson,'utf8'));
if (pkgFile.main) {
var indexFileName = removeFileExtension(combinePaths(getDirectoryPath(pkgJson), pkgFile.main));
found = forEach(supportedExtensions,
extension => getNameIfExists(indexFileName + extension))
}
}
}
// look at node_modules index
if (!found) {
found = forEach(supportedExtensions,
extension => getNameIfExists(normalizePath(combinePaths(combinePaths(combinePaths(containingFile, "node_modules"), moduleName), "index")) + extension));
}

// Finally cache and return or continue up the directory tree
if (found) {
return this.resolvedExternalModuleCache[cacheLookupName] = found;
}
let parentPath = getDirectoryPath(containingFile);
if (parentPath === containingFile) {
this.resolvedExternalModuleCache[cacheLookupName] = '';
return undefined;
}
containingFile = parentPath;
}
}
}

0 comments on commit 1c82c69

Please sign in to comment.