diff --git a/aio/scripts/_payload-limits.json b/aio/scripts/_payload-limits.json index 14cf8a8afb..13f6a2bc0d 100755 --- a/aio/scripts/_payload-limits.json +++ b/aio/scripts/_payload-limits.json @@ -2,8 +2,8 @@ "aio": { "master": { "uncompressed": { - "runtime-es5": 2980, - "runtime-es2015": 2986, + "runtime-es5": 2516, + "runtime-es2015": 2522, "main-es5": 504760, "main-es2015": 443497, "polyfills-es5": 128751, diff --git a/aio/src/app/custom-elements/custom-elements.module.ts b/aio/src/app/custom-elements/custom-elements.module.ts index f2000a391f..2975720d80 100644 --- a/aio/src/app/custom-elements/custom-elements.module.ts +++ b/aio/src/app/custom-elements/custom-elements.module.ts @@ -2,9 +2,9 @@ import { NgModule, NgModuleFactoryLoader, SystemJsNgModuleLoader } from '@angula import { ROUTES} from '@angular/router'; import { ElementsLoader } from './elements-loader'; import { - ELEMENT_MODULE_PATHS, - ELEMENT_MODULE_PATHS_AS_ROUTES, - ELEMENT_MODULE_PATHS_TOKEN + ELEMENT_MODULE_LOAD_CALLBACKS, + ELEMENT_MODULE_LOAD_CALLBACKS_AS_ROUTES, + ELEMENT_MODULE_LOAD_CALLBACKS_TOKEN } from './element-registry'; import { LazyCustomElementComponent } from './lazy-custom-element.component'; @@ -14,12 +14,12 @@ import { LazyCustomElementComponent } from './lazy-custom-element.component'; providers: [ ElementsLoader, { provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader }, - { provide: ELEMENT_MODULE_PATHS_TOKEN, useValue: ELEMENT_MODULE_PATHS }, + { provide: ELEMENT_MODULE_LOAD_CALLBACKS_TOKEN, useValue: ELEMENT_MODULE_LOAD_CALLBACKS }, // Providing these routes as a signal to the build system that these modules should be // registered as lazy-loadable. // TODO(andrewjs): Provide first-class support for providing this. - { provide: ROUTES, useValue: ELEMENT_MODULE_PATHS_AS_ROUTES, multi: true }, + { provide: ROUTES, useValue: ELEMENT_MODULE_LOAD_CALLBACKS_AS_ROUTES, multi: true }, ], }) export class CustomElementsModule { } diff --git a/aio/src/app/custom-elements/element-registry.ts b/aio/src/app/custom-elements/element-registry.ts index 0a80932e9a..b4a7cadd5a 100644 --- a/aio/src/app/custom-elements/element-registry.ts +++ b/aio/src/app/custom-elements/element-registry.ts @@ -1,44 +1,45 @@ import { InjectionToken, Type } from '@angular/core'; +import { LoadChildrenCallback } from '@angular/router'; // Modules containing custom elements must be set up as lazy-loaded routes (loadChildren) // TODO(andrewjs): This is a hack, Angular should have first-class support for preparing a module // that contains custom elements. -export const ELEMENT_MODULE_PATHS_AS_ROUTES = [ +export const ELEMENT_MODULE_LOAD_CALLBACKS_AS_ROUTES = [ { selector: 'aio-announcement-bar', - loadChildren: './announcement-bar/announcement-bar.module#AnnouncementBarModule' + loadChildren: () => import('./announcement-bar/announcement-bar.module').then(mod => mod.AnnouncementBarModule) }, { selector: 'aio-api-list', - loadChildren: './api/api-list.module#ApiListModule' + loadChildren: () => import('./api/api-list.module').then(mod => mod.ApiListModule) }, { selector: 'aio-contributor-list', - loadChildren: './contributor/contributor-list.module#ContributorListModule' + loadChildren: () => import('./contributor/contributor-list.module').then(mod => mod.ContributorListModule) }, { selector: 'aio-file-not-found-search', - loadChildren: './search/file-not-found-search.module#FileNotFoundSearchModule' + loadChildren: () => import('./search/file-not-found-search.module').then(mod => mod.FileNotFoundSearchModule) }, { selector: 'aio-resource-list', - loadChildren: './resource/resource-list.module#ResourceListModule' + loadChildren: () => import('./resource/resource-list.module').then(mod => mod.ResourceListModule) }, { selector: 'aio-toc', - loadChildren: './toc/toc.module#TocModule' + loadChildren: () => import('./toc/toc.module').then(mod => mod.TocModule) }, { selector: 'code-example', - loadChildren: './code/code-example.module#CodeExampleModule' + loadChildren: () => import('./code/code-example.module').then(mod => mod.CodeExampleModule) }, { selector: 'code-tabs', - loadChildren: './code/code-tabs.module#CodeTabsModule' + loadChildren: () => import('./code/code-tabs.module').then(mod => mod.CodeTabsModule) }, { selector: 'live-example', - loadChildren: './live-example/live-example.module#LiveExampleModule' + loadChildren: () => import('./live-example/live-example.module').then(mod => mod.LiveExampleModule) } ]; @@ -51,10 +52,10 @@ export interface WithCustomElementComponent { } /** Injection token to provide the element path modules. */ -export const ELEMENT_MODULE_PATHS_TOKEN = new InjectionToken('aio/elements-map'); +export const ELEMENT_MODULE_LOAD_CALLBACKS_TOKEN = new InjectionToken>('aio/elements-map'); /** Map of possible custom element selectors to their lazy-loadable module paths. */ -export const ELEMENT_MODULE_PATHS = new Map(); -ELEMENT_MODULE_PATHS_AS_ROUTES.forEach(route => { - ELEMENT_MODULE_PATHS.set(route.selector, route.loadChildren); +export const ELEMENT_MODULE_LOAD_CALLBACKS = new Map(); +ELEMENT_MODULE_LOAD_CALLBACKS_AS_ROUTES.forEach(route => { + ELEMENT_MODULE_LOAD_CALLBACKS.set(route.selector, route.loadChildren); }); diff --git a/aio/src/app/custom-elements/elements-loader.spec.ts b/aio/src/app/custom-elements/elements-loader.spec.ts index acb2befd82..d2ccf28780 100644 --- a/aio/src/app/custom-elements/elements-loader.spec.ts +++ b/aio/src/app/custom-elements/elements-loader.spec.ts @@ -1,13 +1,13 @@ import { ComponentFactory, - ComponentFactoryResolver, ComponentRef, Injector, NgModuleFactory, NgModuleFactoryLoader, + ComponentFactoryResolver, ComponentRef, Injector, NgModuleFactory, NgModuleRef, Type } from '@angular/core'; import { TestBed, fakeAsync, flushMicrotasks } from '@angular/core/testing'; import { ElementsLoader } from './elements-loader'; -import { ELEMENT_MODULE_PATHS_TOKEN, WithCustomElementComponent } from './element-registry'; +import { ELEMENT_MODULE_LOAD_CALLBACKS_TOKEN, WithCustomElementComponent } from './element-registry'; interface Deferred { @@ -22,10 +22,9 @@ describe('ElementsLoader', () => { const injector = TestBed.configureTestingModule({ providers: [ ElementsLoader, - { provide: NgModuleFactoryLoader, useClass: FakeModuleFactoryLoader }, - { provide: ELEMENT_MODULE_PATHS_TOKEN, useValue: new Map([ - ['element-a-selector', 'element-a-module-path'], - ['element-b-selector', 'element-b-module-path'] + { provide: ELEMENT_MODULE_LOAD_CALLBACKS_TOKEN, useValue: new Map Promise>>([ + ['element-a-selector', () => Promise.resolve(new FakeModuleFactory('element-a-module'))], + ['element-b-selector', () => Promise.resolve(new FakeModuleFactory('element-b-module'))] ])}, ] }); @@ -148,7 +147,7 @@ describe('ElementsLoader', () => { // Verify the right component was loaded/registered. const Ctor = definedSpy.calls.argsFor(0)[1]; - expect(Ctor.observedAttributes).toEqual(['element-a-module-path']); + expect(Ctor.observedAttributes).toEqual(['element-a-module']); })); it('should wait until the element is defined', fakeAsync(() => { @@ -282,13 +281,6 @@ class FakeModuleFactory extends NgModuleFactory { } } -class FakeModuleFactoryLoader extends NgModuleFactoryLoader { - load(modulePath: string): Promise> { - const fakeModuleFactory = new FakeModuleFactory(modulePath); - return Promise.resolve(fakeModuleFactory); - } -} - function returnPromisesFromSpy(spy: jasmine.Spy): Deferred[] { const deferreds: Deferred[] = []; spy.and.callFake(() => new Promise((resolve, reject) => deferreds.push({resolve, reject}))); diff --git a/aio/src/app/custom-elements/elements-loader.ts b/aio/src/app/custom-elements/elements-loader.ts index b2ee24cf4f..7156164a16 100644 --- a/aio/src/app/custom-elements/elements-loader.ts +++ b/aio/src/app/custom-elements/elements-loader.ts @@ -1,24 +1,24 @@ import { Inject, Injectable, - NgModuleFactoryLoader, + NgModuleFactory, NgModuleRef, } from '@angular/core'; -import { ELEMENT_MODULE_PATHS_TOKEN } from './element-registry'; +import { ELEMENT_MODULE_LOAD_CALLBACKS_TOKEN, WithCustomElementComponent } from './element-registry'; import { from, Observable, of } from 'rxjs'; import { createCustomElement } from '@angular/elements'; +import { LoadChildrenCallback } from '@angular/router'; @Injectable() export class ElementsLoader { /** Map of unregistered custom elements and their respective module paths to load. */ - private elementsToLoad: Map; + private elementsToLoad: Map; /** Map of custom elements that are in the process of being loaded and registered. */ private elementsLoading = new Map>(); - constructor(private moduleFactoryLoader: NgModuleFactoryLoader, - private moduleRef: NgModuleRef, - @Inject(ELEMENT_MODULE_PATHS_TOKEN) elementModulePaths: Map) { + constructor(private moduleRef: NgModuleRef, + @Inject(ELEMENT_MODULE_LOAD_CALLBACKS_TOKEN) elementModulePaths: Map) { this.elementsToLoad = new Map(elementModulePaths); } @@ -47,9 +47,8 @@ export class ElementsLoader { if (this.elementsToLoad.has(selector)) { // Load and register the custom element (for the first time). - const modulePath = this.elementsToLoad.get(selector)!; - const loadedAndRegistered = this.moduleFactoryLoader - .load(modulePath) + const modulePathLoader = this.elementsToLoad.get(selector)!; + const loadedAndRegistered = (modulePathLoader() as Promise>) .then(elementModuleFactory => { const elementModuleRef = elementModuleFactory.create(this.moduleRef.injector); const injector = elementModuleRef.injector;