From 6199ea5d4a83b12c0760c2f7dfc77913f7fb5d27 Mon Sep 17 00:00:00 2001 From: Greg Magolan Date: Fri, 6 Apr 2018 11:08:19 -0700 Subject: [PATCH] fix(compiler-cli): shorten resolved module name in fileNameToModuleName to npm package name for typings (#23231) PR Close #23231 --- integration/bazel/BUILD.bazel | 7 ++-- .../src/transformers/compiler_host.ts | 33 ++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/integration/bazel/BUILD.bazel b/integration/bazel/BUILD.bazel index 2a800b8b5c..95347887f0 100644 --- a/integration/bazel/BUILD.bazel +++ b/integration/bazel/BUILD.bazel @@ -4,9 +4,12 @@ filegroup( name = "node_modules", srcs = glob( ["node_modules/**/*"], - # Exclude directories that commonly contain filenames which are - # illegal bazel labels exclude = [ + # Exclude rxjs because we build it from sources using the label @rxjs//:rxjs + "node_modules/rxjs/**", + + # Exclude directories that commonly contain filenames which are + # illegal bazel labels # e.g. node_modules/adm-zip/test/assets/attributes_test/New folder/hidden.txt "node_modules/**/test/**", # e.g. node_modules/xpath/docs/function resolvers.md diff --git a/packages/compiler-cli/src/transformers/compiler_host.ts b/packages/compiler-cli/src/transformers/compiler_host.ts index 0d486f963e..963693257d 100644 --- a/packages/compiler-cli/src/transformers/compiler_host.ts +++ b/packages/compiler-cli/src/transformers/compiler_host.ts @@ -57,6 +57,7 @@ function assert(condition: T | null | undefined) { export class TsCompilerAotCompilerTypeCheckHostAdapter implements ts.CompilerHost, AotCompilerHost, TypeCheckHost { private metadataReaderCache = createMetadataReaderCache(); + private fileNameToModuleNameCache = new Map(); private flatModuleIndexCache = new Map(); private flatModuleIndexNames = new Set(); private flatModuleIndexRedirectNames = new Set(); @@ -187,6 +188,12 @@ export class TsCompilerAotCompilerTypeCheckHostAdapter implements ts.CompilerHos * import project sources. */ fileNameToModuleName(importedFile: string, containingFile: string): string { + const cacheKey = `${importedFile}:${containingFile}`; + let moduleName = this.fileNameToModuleNameCache.get(cacheKey); + if (moduleName != null) { + return moduleName; + } + const originalImportedFile = importedFile; if (this.options.traceResolution) { console.error( @@ -196,11 +203,10 @@ export class TsCompilerAotCompilerTypeCheckHostAdapter implements ts.CompilerHos // drop extension importedFile = importedFile.replace(EXT, ''); - const importedFilePackagName = getPackageName(importedFile); + const importedFilePackageName = getPackageName(importedFile); const containingFilePackageName = getPackageName(containingFile); - let moduleName: string; - if (importedFilePackagName === containingFilePackageName || + if (importedFilePackageName === containingFilePackageName || GENERATED_FILES.test(originalImportedFile)) { const rootedContainingFile = relativeToRootDirs(containingFile, this.rootDirs); const rootedImportedFile = relativeToRootDirs(importedFile, this.rootDirs); @@ -211,12 +217,31 @@ export class TsCompilerAotCompilerTypeCheckHostAdapter implements ts.CompilerHos importedFile = rootedImportedFile; } moduleName = dotRelative(path.dirname(containingFile), importedFile); - } else if (importedFilePackagName) { + } else if (importedFilePackageName) { moduleName = stripNodeModulesPrefix(importedFile); + if (originalImportedFile.endsWith('.d.ts')) { + // the moduleName for these typings could be shortented to the npm package name + // if the npm package typings matches the importedFile + try { + const modulePath = importedFile.substring(0, importedFile.length - moduleName.length) + + importedFilePackageName; + const packageJson = require(modulePath + '/package.json'); + const packageTypings = path.posix.join(modulePath, packageJson.typings); + if (packageTypings === originalImportedFile) { + moduleName = importedFilePackageName; + } + } catch (e) { + // the above require() will throw if there is no package.json file + // and this is safe to ignore and correct to keep the longer + // moduleName in this case + } + } } else { throw new Error( `Trying to import a source file from a node_modules package: import ${originalImportedFile} from ${containingFile}`); } + + this.fileNameToModuleNameCache.set(cacheKey, moduleName); return moduleName; }