-
Couldn't load subscription status.
- Fork 11.9k
Description
This is a feature request.
I'd like to start discussion around @ngtools/webpack supporting code splitting by third party libs (including ui-router-ng2).
Currently the code splitting support in @ngtools/webpack has a soft dependency on @angular/router.
My understanding is that:
@ngtools/webpackloader invokes__NGTOOLS_PRIVATE_API_2.listLazyRoutes()listLazyRoutesfinds lazy routes:- References the DI token
ROUTESfound in@angular/router - statically analyzes the application.
- checks each
NgModulefor providedROUTES - Checks each route for
loadChildrenand adds to the list of lazy routes. - returns lazy routes
- References the DI token
- processes lazy routes, redirecting imports to
.ngfactory.tsand doing webpack magic
Goal
I think the goal should be to eliminate the dependency on @angular/router and provide a router agnostic mechanism for third parties to supply code splitting information.
Today, UI-Router supports code splitting using @ngtools/webpack by importing the ROUTES token from @angular/router, then providing the ui-router states as that DI token, i.e., { provide: ROUTES, useValue: module.states, multi: true }. However, this forces ui-router to have a dependency on @angular/router. It also forces ui-router to emulate the structure of @angular/router by adding a loadChildren property.
Proposal 1
Make the DI token configurable by @ngtools/webpack.
Do not reference the token from @angular/router in ngtools-impl.ts, but pass the token in. UI-Router users could configure this somehow to use the STATES token, for example.
This proposal is rather limited in its usefulness. Only one library could support lazy loading + code splitting in a given app.
Proposal 2
Move and/or rename the DI token out of @angular/router
Perhaps the DI token could be moved to @angular/compiler-cli, @angular/common, or @angular/core. This eliminates the need to depend on @angular/router. Additionally, move the token to its own ES6 module. Today, importing the ROUTES token from @angular/router brings in unrelated symbols from @angular/router into the ui-router bundle even using rollup.
This proposal still conceptually ties lazy loading to the @angular/router. All terminology and code analysis assumes that lazy loading code processes @angular/router routes. Third parties have to emulate the router's structure.
Proposal 3
Introduce a routing-agnostic token such as ANALYZE_FOR_LAZY_LOAD.
Either @angular/router or third parties should provide lazy load and code splitting information using this token. I propose instead of providing an array of specifically structured objects such as ROUTES or STATES, that only the lazy load information need be provided, i.e.:
{
provide: ANALYZE_FOR_LAZY_LOAD,
useValue: [
'./child1/child1.module#Child1Module',
'./child2/child2.module#Child2Module'
]
}The @angular/router would then provide the module's lazy load information by doing something like:
const lazyRoutes = ROUTES.map(x => x.loadChildren).filter(identity);
const provider = { provide: ANALYZE_FOR_LAZY_LOAD, useValue: lazyRoutes, multi: true };The knowledge about the lazy load declaration object (i.e., what the loadChildren property means on a route) is moved from @angular/compiler-cli to the library that owns that structure (i.e., the @angular/router).
Of these three proposals, this one is my favorite as it separates concerns nicely and provides a clear mechanism for lib authors to use.