diff --git a/build.sh b/build.sh index d5b332430..d0b126e01 100755 --- a/build.sh +++ b/build.sh @@ -11,3 +11,8 @@ npm run build:ng-aspnetcore-engine cp modules/ng-aspnetcore-engine/package.json dist/ng-aspnetcore-engine/package.json cp modules/ng-aspnetcore-engine/README.md dist/ng-aspnetcore-engine/README.md + +npm run build:ng-module-map-ngfactory-loader + +cp modules/ng-module-map-ngfactory-loader/package.json dist/ng-module-map-ngfactory-loader/package.json +cp modules/ng-module-map-ngfactory-loader/README.md dist/ng-module-map-ngfactory-loader/README.md diff --git a/modules/ng-module-map-ngfactory-loader/README.md b/modules/ng-module-map-ngfactory-loader/README.md new file mode 100644 index 000000000..af1818d90 --- /dev/null +++ b/modules/ng-module-map-ngfactory-loader/README.md @@ -0,0 +1,24 @@ +# Module Map NgFactory Loader + +This is a NgFactory Loader which uses a map of modules instead of resolving modules lazily. + +This is useful when executing in node because lazy loading serves no purpose + +## Usage with `@angular/cli` + +`npm install @nguniversal/module-map-ngfactory-loader --save` + +`@angular/cli` will generate this map in its main output bundle if you put app.platform = 'server'. + +```ts +const { provideModuleMap } = require('@nguniversal/module-map-ngfactory-loader'); +const { AppModuleNgFactory, LAZY_MODULE_MAP } = require('main.bundle.js'); + +renderModuleFactory(AppModuleNgFactory, { + document: '', + url: '/', + extraProviders: [ + provideModuleMap(LAZY_ROUTE_MAP) + ] +}) +``` diff --git a/modules/ng-module-map-ngfactory-loader/index.ts b/modules/ng-module-map-ngfactory-loader/index.ts new file mode 100644 index 000000000..8420b1093 --- /dev/null +++ b/modules/ng-module-map-ngfactory-loader/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/modules/ng-module-map-ngfactory-loader/package.json b/modules/ng-module-map-ngfactory-loader/package.json new file mode 100644 index 000000000..7bd307b3a --- /dev/null +++ b/modules/ng-module-map-ngfactory-loader/package.json @@ -0,0 +1,22 @@ +{ + "name": "@nguniversal/module-map-ngfactory-loader", + "main": "index.js", + "types": "index.d.ts", + "version": "1.0.0-beta.0", + "description": "NgFactoryLoader which uses a Map to load ngfactories without lazy loading", + "homepage": "https://github.com/angular/universal", + "license": "MIT", + "contributors": [ + "FrozenPandaz" + ], + "repository": { + "type": "git", + "url": "https://github.com/angular/universal" + }, + "bugs": { + "url": "https://github.com/angular/universal/issues" + }, + "peerDependencies": { + "@angular/core": "^4.0.0" + } +} diff --git a/modules/ng-module-map-ngfactory-loader/src/index.ts b/modules/ng-module-map-ngfactory-loader/src/index.ts new file mode 100644 index 000000000..7a8ca4a8e --- /dev/null +++ b/modules/ng-module-map-ngfactory-loader/src/index.ts @@ -0,0 +1,2 @@ +export * from './module-map-loader.module'; +export * from './module-map-ngfactory-loader'; diff --git a/modules/ng-module-map-ngfactory-loader/src/module-map-loader.module.ts b/modules/ng-module-map-ngfactory-loader/src/module-map-loader.module.ts new file mode 100644 index 000000000..b3cab6898 --- /dev/null +++ b/modules/ng-module-map-ngfactory-loader/src/module-map-loader.module.ts @@ -0,0 +1,45 @@ +import { NgModule, NgModuleFactoryLoader, ModuleWithProviders, Provider } from '@angular/core'; + +import { ModuleMapNgFactoryLoader, ModuleMap, MODULE_MAP } from './module-map-ngfactory-loader'; + +/** + * Helper function for getting the providers object for the MODULE_MAP + * + * @param {ModuleMap} moduleMap Map to use as a value for MODULE_MAP + */ +export function provideModuleMap(moduleMap: ModuleMap): Provider { + return { + provide: MODULE_MAP, + useValue: moduleMap + }; +} + +/** + * Module for using a NgModuleFactoryLoader which does not lazy load + */ +@NgModule({ + providers: [ + { + provide: NgModuleFactoryLoader, + useClass: ModuleMapNgFactoryLoader + } + ] +}) +export class ModuleMapLoaderModule { + /** + * Returns a ModuleMapLoaderModule along with a MODULE_MAP + * + * @param {ModuleMap} moduleMap Map to use as a value for MODULE_MAP + */ + static withMap(moduleMap: ModuleMap): ModuleWithProviders { + return { + ngModule: ModuleMapLoaderModule, + providers: [ + { + provide: MODULE_MAP, + useValue: moduleMap + } + ] + }; + } +} diff --git a/modules/ng-module-map-ngfactory-loader/src/module-map-ngfactory-loader.ts b/modules/ng-module-map-ngfactory-loader/src/module-map-ngfactory-loader.ts new file mode 100644 index 000000000..4238deecf --- /dev/null +++ b/modules/ng-module-map-ngfactory-loader/src/module-map-ngfactory-loader.ts @@ -0,0 +1,40 @@ +import { Injectable, NgModuleFactoryLoader, InjectionToken, NgModuleFactory, Inject, Type, Compiler } from '@angular/core'; + +/** + * A map key'd by loadChildren strings and Modules or NgModuleFactories as vaules + */ +export type ModuleMap = { + [key: string]: Type | NgModuleFactory; +}; + +/** + * Token used by the ModuleMapNgFactoryLoader to load modules + */ +export const MODULE_MAP: InjectionToken = new InjectionToken('MODULE_MAP'); + +/** + * NgModuleFactoryLoader which does not lazy load + */ +@Injectable() +export class ModuleMapNgFactoryLoader implements NgModuleFactoryLoader { + constructor(private compiler: Compiler, @Inject(MODULE_MAP) private moduleMap: ModuleMap) { } + + load(loadChildrenString: string): Promise> { + const offlineMode = this.compiler instanceof Compiler; + const type = this.moduleMap[loadChildrenString]; + + if (!type) { + throw new Error(`${loadChildrenString} did not exist in the MODULE_MAP`); + } + + return offlineMode ? this.loadFactory(> type) : this.loadAndCompile(> type); + } + + private loadFactory(factory: NgModuleFactory): Promise> { + return new Promise(resolve => resolve(factory)); + } + + private loadAndCompile(type: Type): Promise> { + return this.compiler.compileModuleAsync(type); + } +} diff --git a/modules/ng-module-map-ngfactory-loader/tsconfig.json b/modules/ng-module-map-ngfactory-loader/tsconfig.json new file mode 100644 index 000000000..f53045ad1 --- /dev/null +++ b/modules/ng-module-map-ngfactory-loader/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/ng-module-map-ngfactory-loader" + }, + "angularCompilerOptions": { + "genDir": "ngfactory" + }, + "files": [ + "index.ts" + ] +} diff --git a/package.json b/package.json index 957aed68b..b0fce5cd0 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "jasmine": "jasmine", "build:ng-express-engine": "ngc -p modules/ng-express-engine/tsconfig.json", "build:ng-aspnetcore-engine": "ngc -p modules/ng-aspnetcore-engine/tsconfig.json", + "build:ng-module-map-ngfactory-loader": "ngc -p modules/ng-module-map-ngfactory-loader/tsconfig.json", "build": "./build.sh", "test": "exit 0" },