feat(compiler): make .ngsummary.json files portable

This also allows to customize the filePaths in `.ngsummary.json` file
via the new methods `toSummaryFileName` and `fromSummaryFileName`
on the `CompilerHost`.
This commit is contained in:
Tobias Bosch
2017-08-15 14:41:48 -07:00
committed by Hans
parent 6a1ab61cce
commit 2572bf508f
15 changed files with 149 additions and 53 deletions

View File

@ -130,6 +130,20 @@ export interface CompilerHost extends ts.CompilerHost {
* See ImportResolver.
*/
fileNameToModuleName(importedFilePath: string, containingFilePath: string): string|null;
/**
* Converts a file name into a representation that should be stored in a summary file.
* This has to include changing the suffix as well.
* E.g.
* `some_file.ts` -> `some_file.d.ts`
*
* @param referringSrcFileName the soure file that refers to fileName
*/
toSummaryFileName(fileName: string, referringSrcFileName: string): string;
/**
* Converts a fileName that was processed by `toSummaryFileName` back into a real fileName
* given the fileName of the library that is referrig to it.
*/
fromSummaryFileName(fileName: string, referringLibFileName: string): string;
/**
* Load a referenced resource either statically or asynchronously. If the host returns a
* `Promise<string>` it is assumed the user of the corresponding `Program` will call

View File

@ -24,6 +24,8 @@ export function createCompilerHost(
host.moduleNameToFileName = mixin.moduleNameToFileName.bind(mixin);
host.fileNameToModuleName = mixin.fileNameToModuleName.bind(mixin);
host.toSummaryFileName = mixin.toSummaryFileName.bind(mixin);
host.fromSummaryFileName = mixin.fromSummaryFileName.bind(mixin);
// Make sure we do not `host.realpath()` from TS as we do not want to resolve symlinks.
// https://github.com/Microsoft/TypeScript/issues/9552
@ -109,9 +111,15 @@ class CompilerHostMixin {
let moduleName: string;
if (importedFilePackagName === containingFilePackageName) {
moduleName = dotRelative(
path.dirname(stripRootDir(this.rootDirs, containingFile)),
stripRootDir(this.rootDirs, importedFile));
const rootedContainingFile = stripRootDir(this.rootDirs, containingFile);
const rootedImportedFile = stripRootDir(this.rootDirs, importedFile);
if (rootedContainingFile !== containingFile && rootedImportedFile !== importedFile) {
// if both files are contained in the `rootDirs`, then strip the rootDirs
containingFile = rootedContainingFile;
importedFile = rootedImportedFile;
}
moduleName = dotRelative(path.dirname(containingFile), importedFile);
} else if (importedFilePackagName) {
moduleName = stripNodeModulesPrefix(importedFile);
} else {
@ -120,6 +128,18 @@ class CompilerHostMixin {
}
return moduleName;
}
toSummaryFileName(fileName: string, referringSrcFileName: string): string {
return this.fileNameToModuleName(fileName, referringSrcFileName);
}
fromSummaryFileName(fileName: string, referringLibFileName: string): string {
const resolved = this.moduleNameToFileName(fileName, referringLibFileName);
if (!resolved) {
throw new Error(`Could not resolve ${fileName} from ${referringLibFileName}`);
}
return resolved;
}
}
interface ModuleFilenameResolutionHost extends ts.ModuleResolutionHost {
@ -189,6 +209,11 @@ function stripNodeModulesPrefix(filePath: string): string {
return filePath.replace(/.*node_modules\//, '');
}
function getNodeModulesPrefix(filePath: string): string|null {
const match = /.*node_modules\//.exec(filePath);
return match ? match[1] : null;
}
function normalizePath(p: string): string {
return path.normalize(path.join(p, '.')).replace(/\\/g, '/');
}

View File

@ -314,6 +314,14 @@ class AotCompilerHostImpl extends BaseAotCompilerHost<CompilerHost> {
fileNameToModuleName(importedFile: string, containingFile: string): string|null {
return this.context.fileNameToModuleName(importedFile, containingFile);
}
toSummaryFileName(fileName: string, referringSrcFileName: string): string {
return this.context.toSummaryFileName(fileName, referringSrcFileName);
}
fromSummaryFileName(fileName: string, referringLibFileName: string): string {
return this.context.fromSummaryFileName(fileName, referringLibFileName);
}
}
export function createProgram(