Skip to content

@ngtools/webpack feature request: support code splitting by third parties #4541

Closed
@christopherthielen

Description

@christopherthielen

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:

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.

Metadata

Metadata

Assignees

Labels

P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgentfeatureIssue that requests a new featuretype: faq

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions