fix(ivy): support listing lazy route for project-root-relative entry point in `ngtsc` (#28542)

I don't know of any use of this API with a project-root-relative path
(i.e. the cli will always call it with an absolute path), but keeping
the API backwards compatible just in case.

PR Close #28542
This commit is contained in:
George Kalpakas 2019-02-07 19:03:13 +02:00 committed by Miško Hevery
parent 3eec314ba9
commit 188f20fb16
3 changed files with 36 additions and 3 deletions

View File

@ -21,7 +21,7 @@ import {ImportRewriter, ModuleResolver, NoopImportRewriter, R3SymbolsImportRewri
import {PartialEvaluator} from './partial_evaluator';
import {TypeScriptReflectionHost} from './reflection';
import {HostResourceLoader} from './resource_loader';
import {NgModuleRouteAnalyzer} from './routing';
import {NgModuleRouteAnalyzer, entryPointKeyFor} from './routing';
import {FactoryGenerator, FactoryInfo, GeneratedShimsHostWrapper, ShimGenerator, SummaryGenerator, generatedFactoryTransform} from './shims';
import {ivySwitchTransform} from './switch';
import {IvyCompilation, declarationTransformFactory, ivyTransformFactory} from './transform';
@ -191,6 +191,38 @@ export class NgtscProgram implements api.Program {
}
listLazyRoutes(entryRoute?: string|undefined): api.LazyRoute[] {
if (entryRoute) {
// Note:
// This resolution step is here to match the implementation of the old `AotCompilerHost` (see
// https://github.com/angular/angular/blob/50732e156/packages/compiler-cli/src/transformers/compiler_host.ts#L175-L188).
//
// `@angular/cli` will always call this API with an absolute path, so the resolution step is
// not necessary, but keeping it backwards compatible in case someone else is using the API.
// Relative entry paths are disallowed.
if (entryRoute.startsWith('.')) {
throw new Error(
`Falied to list lazy routes: Resolution of relative paths (${entryRoute}) is not supported.`);
}
// Non-relative entry paths fall into one of the following categories:
// - Absolute system paths (e.g. `/foo/bar/my-project/my-module`), which are unaffected by the
// logic below.
// - Paths to enternal modules (e.g. `some-lib`).
// - Paths mapped to directories in `tsconfig.json` (e.g. `shared/my-module`).
// (See https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping.)
//
// In all cases above, the `containingFile` argument is ignored, so we can just take the first
// of the root files.
const containingFile = this.tsProgram.getRootFileNames()[0];
const [entryPath, moduleName] = entryRoute.split('#');
const resolved = ts.resolveModuleName(entryPath, containingFile, this.options, this.host);
if (resolved.resolvedModule) {
entryRoute = entryPointKeyFor(resolved.resolvedModule.resolvedFileName, moduleName);
}
}
this.ensureAnalyzed();
return this.routeAnalyzer !.listLazyRoutes(entryRoute);
}

View File

@ -9,3 +9,4 @@
/// <reference types="node" />
export {LazyRoute, NgModuleRouteAnalyzer} from './src/analyzer';
export {entryPointKeyFor} from './src/route';

View File

@ -37,7 +37,7 @@ describe('ngtools_api (deprecated)', () => {
export class ErrorComp2 {}
@NgModule({
declarations: [ErrorComp2, NonExistentComp],
declarations: [ErrorComp2],
imports: [RouterModule.forRoot([{loadChildren: './child#ChildModule'}])]
})
export class MainModule {}
@ -60,7 +60,7 @@ describe('ngtools_api (deprecated)', () => {
});
}
fixmeIvy('FW-629: ngtsc lists lazy routes').it('should list lazy routes recursively', () => {
it('should list lazy routes recursively', () => {
writeSomeRoutes();
const {program, host, options} =
createProgram(['src/main.ts', 'src/child.ts', 'src/child2.ts']);