diff --git a/docs/ENVIRONMENTS.md b/docs/ENVIRONMENTS.md index 195ace1ed5..4b40fc8dc1 100644 --- a/docs/ENVIRONMENTS.md +++ b/docs/ENVIRONMENTS.md @@ -34,8 +34,9 @@ export interface StarkEnvironment { /** * Function to modify/decorate the NgModule Instance created by Angular for a given platform. * Useful to enable/disable some Angular specifics such as the debug tools. + * @param moduleRef - NgModule instance created by Angular for a given platform. */ - decorateModuleRef(modRef: NgModuleRef): NgModuleRef; + decorateModule(moduleRef: NgModuleRef): NgModuleRef; } ``` @@ -63,7 +64,6 @@ Then in each file, an `environment` constant of type `StarkEnvironment` should b // environment.prod.ts import { NgModuleRef } from "@angular/core"; -import { disableDebugTools } from "@angular/platform-browser"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; export const environment: StarkEnvironment = { @@ -71,9 +71,10 @@ export const environment: StarkEnvironment = { hmr: false, ENV_PROVIDERS: [ProductionOnlyProvider], - decorateModuleRef(modRef: NgModuleRef): NgModuleRef { - disableDebugTools(); // disable debug tools in production - return modRef; + decorateModule(moduleRef: NgModuleRef): NgModuleRef { + // perform any module customization needed for this specific environment here + // and make sure to invoke this function by passing it the NgModule created by Angular + return moduleRef; } }; ``` @@ -131,8 +132,10 @@ export const environment: StarkEnvironment = { hmr: false, ENV_PROVIDERS: [], - decorateModuleRef(modRef: NgModuleRef): NgModuleRef { - /* do something here */ + decorateModule(moduleRef: NgModuleRef): NgModuleRef { + // perform any module customization needed for this specific environment here + // and make sure to invoke this function by passing it the NgModule created by Angular + return moduleRef; } }; ``` @@ -178,8 +181,10 @@ export const environment: StarkEnvironment = { ENV_PROVIDERS: [], someProperty: "some value", // your new property - decorateModuleRef(modRef: NgModuleRef): NgModuleRef { - /* do something here */ + decorateModule(moduleRef: NgModuleRef): NgModuleRef { + // perform any module customization needed for this specific environment here + // and make sure to invoke this function by passing it the NgModule created by Angular + return moduleRef; } }; ``` diff --git a/packages/rollup.config.common-data.js b/packages/rollup.config.common-data.js index ac8aad7377..8d8276848b 100644 --- a/packages/rollup.config.common-data.js +++ b/packages/rollup.config.common-data.js @@ -7,10 +7,12 @@ const commonjs = require("rollup-plugin-commonjs"); const sourcemaps = require("rollup-plugin-sourcemaps"); const globals = { + "@angularclass/hmr": "angularclass.hmr", "@angular/cdk": "ng.cdk", "@angular/core": "ng.core", - "@angular/common/http": "angular.common.http", + "@angular/common/http": "ng.common.http", "@angular/material": "ng.material", + "@angular/platform-browser": "ng.platform.browser", "@nationalbankbelgium/stark-core": "stark.core", "@nationalbankbelgium/stark-ui": "stark.ui", "@ngrx/store": "@ngrx/store", diff --git a/packages/stark-build/package.json b/packages/stark-build/package.json index 370d5cac3f..b10cb94d06 100644 --- a/packages/stark-build/package.json +++ b/packages/stark-build/package.json @@ -21,7 +21,6 @@ "dependencies": { "@angular-devkit/build-angular": "0.6.8", "@angular-devkit/build-optimizer": "0.6.8", - "@angularclass/hmr": "2.1.3", "@types/source-map": "0.5.7", "@types/uglify-js": "3.0.2", "@types/webpack": "4.4.0", diff --git a/packages/stark-core/package.json b/packages/stark-core/package.json index 818a989041..234a215530 100644 --- a/packages/stark-core/package.json +++ b/packages/stark-core/package.json @@ -26,6 +26,7 @@ "npm": ">=5.3.0" }, "dependencies": { + "@angularclass/hmr": "2.1.3", "@ng-idle/core": "2.0.0-beta.15", "@ng-idle/keepalive": "2.0.0-beta.15", "@ngrx/effects": "6.0.1", diff --git a/packages/stark-core/src/common.ts b/packages/stark-core/src/common.ts index d70bd92b54..d649e6649f 100644 --- a/packages/stark-core/src/common.ts +++ b/packages/stark-core/src/common.ts @@ -1,3 +1,4 @@ +export * from "./common/bootstrap"; export * from "./common/environment"; export * from "./common/error"; export * from "./common/routes"; diff --git a/packages/stark-core/src/common/bootstrap.ts b/packages/stark-core/src/common/bootstrap.ts new file mode 100644 index 0000000000..7b48336655 --- /dev/null +++ b/packages/stark-core/src/common/bootstrap.ts @@ -0,0 +1,2 @@ +export * from "./bootstrap/abstract-stark-main"; +export * from "./bootstrap/stark-main.intf"; diff --git a/packages/stark-core/src/common/bootstrap/abstract-stark-main.ts b/packages/stark-core/src/common/bootstrap/abstract-stark-main.ts new file mode 100644 index 0000000000..5063e36268 --- /dev/null +++ b/packages/stark-core/src/common/bootstrap/abstract-stark-main.ts @@ -0,0 +1,163 @@ +import { ApplicationRef, ComponentRef, enableProdMode, NgModuleRef } from "@angular/core"; +import { disableDebugTools, enableDebugTools } from "@angular/platform-browser"; +import { createNewHosts } from "@angularclass/hmr"; + +import { StarkMain } from "./stark-main.intf"; +import { StarkEnvironment } from "environments/environment"; + +/** + * Parent class for bootstrapping Stark applications. + * It handles the DOMContentLoaded event of the Web browser in order to bootstrap the application. + * This class also supports HMR in development mode. + */ +export abstract class AbstractStarkMain implements StarkMain { + protected constructor(protected environment: StarkEnvironment) { + // no-op + } + + /** + * Must be implemented by children classes. Called within bootstrapDomReady (i.e., when the DOM has been loaded) + */ + public abstract main: () => Promise; + + public mainWrapper = (): void => { + // written like this because otherwise "this" will not be captured :) + // no need for the event listener after this + document.removeEventListener("DOMContentLoaded", this.mainWrapper, false); + + this.initialize(); + }; + + /** + * Call the main() method and log an error in case of failure + */ + private invokeMain(): void { + // FIXME handle errors nicely (UX!) + this.main().catch((err: any) => console.error(err)); + + // TODO reintroduce later + // bootstrap the app as long as the app root element is there (it won't be there in case the browser is outdated) + // if (document.getElementsByClassName("stark-app")[0]) { + // // add anything relevant here + // } else { + // console.error("Could not bootstrap the App: unsupported browser."); + // } + } + + /** + * Initialize by configuring HMR if it is enabled or normally instead. + */ + protected initialize = (): void => { + if (ENV === "development" && this.environment.hmr) { + if (module["hot"]) { + this.bootstrapHmr(module, this.main); + } else { + console.error("HMR is not enabled for webpack-dev-server! This is most probably due to a bug in Stark."); + } + } else { + this.invokeMain(); + } + }; + + /** + * Call the main function once the DOM has loaded + */ + protected bootstrapDomReady = (): void => { + switch (document.readyState) { + case "loading": + document.addEventListener("DOMContentLoaded", this.mainWrapper, false); + break; + case "interactive": + case "complete": + default: + this.initialize(); + } + }; + + /** + * Bootstrap after document is ready + */ + public bootstrap(): void { + console.log(` +NNNNNNNN NNNNNNNNBBBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBB +N:::::::N N::::::NB::::::::::::::::B B::::::::::::::::B +N::::::::N N::::::NB::::::BBBBBB:::::B B::::::BBBBBB:::::B +N:::::::::N N::::::NBB:::::B B:::::BBB:::::B B:::::B +N::::::::::N N::::::N B::::B B:::::B B::::B B:::::B +N:::::::::::N N::::::N B::::B B:::::B B::::B B:::::B +N:::::::N::::N N::::::N B::::BBBBBB:::::B B::::BBBBBB:::::B +N::::::N N::::N N::::::N B:::::::::::::BB B:::::::::::::BB +N::::::N N::::N:::::::N B::::BBBBBB:::::B B::::BBBBBB:::::B +N::::::N N:::::::::::N B::::B B:::::B B::::B B:::::B +N::::::N N::::::::::N B::::B B:::::B B::::B B:::::B +N::::::N N:::::::::N B::::B B:::::B B::::B B:::::B +N::::::N N::::::::NBB:::::BBBBBB::::::BBB:::::BBBBBB::::::B +N::::::N N:::::::NB:::::::::::::::::B B:::::::::::::::::B +N::::::N N::::::NB::::::::::::::::B B::::::::::::::::B +NNNNNNNN NNNNNNNBBBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBB + +We need great software developers like you! https://jobs.nbb.be + `); + + this.bootstrapDomReady(); + } + + /** + * Configure HMR + * Code based on: https://github.com/angular/angular-cli/wiki/stories-configure-hmr + * Reference: https://github.com/gdi2290/angular-hmr + * @ignore + */ + protected bootstrapHmr: Function = (module: any, bootstrap: () => Promise>) => { + if(ENV === "development") { + console.log("Bootstrapping HMR"); + let ngModule: NgModuleRef; + module.hot.accept(); + bootstrap().then( + (mod: NgModuleRef) => (ngModule = mod), + (reason: any) => console.error("HMR bootstrap: bootstrap failed due to ", reason) + ); + + module.hot.dispose(() => { + const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef); + const elements: ComponentRef[] = appRef.components.map((c: ComponentRef) => c.location.nativeElement); + const makeVisible: () => void = createNewHosts(elements); + ngModule.destroy(); + makeVisible(); + }); + } + }; + + /** + * Modify/decorate the NgModule instance created by Angular. + * Adapt the configuration based on the current environment + * @param moduleRef - NgModule instance created by Angular for a given platform. + */ + public decorateModule = (moduleRef: NgModuleRef): NgModuleRef => { + // written like this because otherwise "this" will not be captured :) + if (this.environment.production) { + console.log("Customizing configuration for production!"); + enableProdMode(); + disableDebugTools(); + } else { + console.log("Customizing configuration for development!"); + + // Ensure that we get detailed stack tracks during development (useful with node & Webpack) + // Reference: http://stackoverflow.com/questions/7697038/more-than-10-lines-in-a-node-js-stack-error + Error.stackTraceLimit = Infinity; + require("zone.js/dist/long-stack-trace-zone"); + + // Enable Angular debug tools in the dev console + // https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md + const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef); + const cmpRef: ComponentRef = appRef.components[0]; + enableDebugTools(cmpRef); + + const _ng: any = (window).ng; + (window).ng.probe = _ng.probe; + (window).ng.coreTokens = _ng.coreTokens; + } + + return moduleRef; + }; +} diff --git a/packages/stark-core/src/common/bootstrap/stark-main.intf.ts b/packages/stark-core/src/common/bootstrap/stark-main.intf.ts new file mode 100644 index 0000000000..8a10395ee6 --- /dev/null +++ b/packages/stark-core/src/common/bootstrap/stark-main.intf.ts @@ -0,0 +1,23 @@ +import { NgModuleRef } from "@angular/core"; + +/** + * Main entry point + */ +export interface StarkMain { + /** + * Main function: responsible for starting the application. + */ + main: () => Promise; + + /** + * Bootstrap the loading process. + */ + bootstrap(): void; + + /** + * Function to modify/decorate the module instance created by Angular for a given platform. + * Useful to enable/disable some Angular specifics such as the debug tools. + * @param moduleRef - NgModule instance created by Angular for a given platform. + */ + decorateModule(moduleRef: NgModuleRef): NgModuleRef; +} diff --git a/packages/stark-core/src/common/environment/environment.intf.ts b/packages/stark-core/src/common/environment/environment.intf.ts index 853d3982fa..e7d6af91d9 100644 --- a/packages/stark-core/src/common/environment/environment.intf.ts +++ b/packages/stark-core/src/common/environment/environment.intf.ts @@ -20,10 +20,11 @@ export interface StarkEnvironment { */ ENV_PROVIDERS: any[]; /** - * Function to modify/decorate the NgModule Instance created by Angular for a given platform. + * Function to modify/decorate the module instance created by Angular for a given platform. * Useful to enable/disable some Angular specifics such as the debug tools. + * @param moduleRef - NgModule instance created by Angular for a given platform. */ - decorateModuleRef(modRef: NgModuleRef): NgModuleRef; + decorateModule(moduleRef: NgModuleRef): NgModuleRef; } /** diff --git a/packages/stark-ui/karma.conf.js b/packages/stark-ui/karma.conf.js index ca18b8e4df..210cc20dab 100644 --- a/packages/stark-ui/karma.conf.js +++ b/packages/stark-ui/karma.conf.js @@ -15,6 +15,7 @@ const karmaTypescriptBundlerAliasResolution = { "@nationalbankbelgium/stark-core": "../../dist/packages-dist/stark-core/bundles/stark-core.umd.js", "@nationalbankbelgium/stark-core/testing": "../../dist/packages-dist/stark-core/bundles/stark-core-testing.umd.js", // adapt the resolution of the 3rd party modules used in stark-core + "@angularclass/hmr": "../stark-core/node_modules/@angularclass/hmr/dist/index.js", "@ng-idle/core": "../stark-core/node_modules/@ng-idle/core/bundles/core.umd.js", "@ng-idle/keepalive": "../stark-core/node_modules/@ng-idle/keepalive/bundles/keepalive.umd.js", "@ngrx/store": "../stark-core/node_modules/@ngrx/store/bundles/store.umd.js", diff --git a/packages/stark-ui/tsconfig-build.json b/packages/stark-ui/tsconfig-build.json index e271650e21..f1e2b471fd 100644 --- a/packages/stark-ui/tsconfig-build.json +++ b/packages/stark-ui/tsconfig-build.json @@ -10,6 +10,7 @@ ], "lib": ["dom", "dom.iterable", "es2017"], "paths": { + "@angularclass/hmr": ["../stark-core/node_modules/@angularclass/hmr"], "@angular/animations": ["../../node_modules/@angular/animations"], "@angular/cdk": ["../../node_modules/@angular/cdk"], "@angular/common": ["../../node_modules/@angular/common"], diff --git a/showcase/package.json b/showcase/package.json index 7d600dd807..e292a9c605 100644 --- a/showcase/package.json +++ b/showcase/package.json @@ -121,8 +121,8 @@ "@angular/platform-browser-dynamic": "6.0.4", "@angular/platform-server": "6.0.4", "@angular/router": "6.0.4", - "@nationalbankbelgium/stark-core": "file:../dist/packages-dist/stark-core/nationalbankbelgium-stark-core-10.0.0-alpha.3-6796ad0.tgz", - "@nationalbankbelgium/stark-ui": "file:../dist/packages-dist/stark-ui/nationalbankbelgium-stark-ui-10.0.0-alpha.3-6796ad0.tgz", + "@nationalbankbelgium/stark-core": "file:../dist/packages-dist/stark-core/nationalbankbelgium-stark-core-10.0.0-alpha.3-6fc4fb3.tgz", + "@nationalbankbelgium/stark-ui": "file:../dist/packages-dist/stark-ui/nationalbankbelgium-stark-ui-10.0.0-alpha.3-6fc4fb3.tgz", "@uirouter/visualizer": "6.0.0", "angular-highlight-js": "^2.0.1", "basscss": "^8.0.2", @@ -141,8 +141,8 @@ "zone.js": "0.8.26" }, "devDependencies": { - "@nationalbankbelgium/stark-build": "file:../dist/packages-dist/stark-build/nationalbankbelgium-stark-build-10.0.0-alpha.3-6796ad0.tgz", - "@nationalbankbelgium/stark-testing": "file:../dist/packages-dist/stark-testing/nationalbankbelgium-stark-testing-10.0.0-alpha.3-6796ad0.tgz", + "@nationalbankbelgium/stark-build": "file:../dist/packages-dist/stark-build/nationalbankbelgium-stark-build-10.0.0-alpha.3-6fc4fb3.tgz", + "@nationalbankbelgium/stark-testing": "file:../dist/packages-dist/stark-testing/nationalbankbelgium-stark-testing-10.0.0-alpha.3-6fc4fb3.tgz", "@types/core-js": "2.5.0", "@types/hammerjs": "2.0.35", "@types/node": "8.10.15", diff --git a/showcase/src/app/app.module.ts b/showcase/src/app/app.module.ts index 0e4654ca21..8056596779 100644 --- a/showcase/src/app/app.module.ts +++ b/showcase/src/app/app.module.ts @@ -55,9 +55,8 @@ import { AppComponent } from "./app.component"; import { AppState } from "./app.service"; import { HomeComponent } from "./home"; import { NoContentComponent } from "./no-content"; - /* tslint:disable:no-import-side-effect */ -// load PCSS styles +// load PostCSS styles import "../styles/styles.pcss"; // load SASS styles import "../styles/styles.scss"; @@ -116,7 +115,7 @@ export function logger(reducer: ActionReducer): any { export const metaReducers: MetaReducer[] = ENV !== "production" ? [logger, storeFreeze] : []; /** - * `AppModule` is the main entry point into Angular2's bootstrapping process + * `AppModule` is the main entry point into Angular's bootstrapping process */ @NgModule({ bootstrap: [AppComponent], @@ -167,6 +166,14 @@ export const metaReducers: MetaReducer[] = ENV !== "production" ? [logger ] }) export class AppModule { + private user: StarkUser = { + uuid: "abc123", + username: "John", + firstName: "Doe", + lastName: "Smith", + roles: ["dummy role"] + }; + public constructor( private translateService: TranslateService, @Inject(STARK_SESSION_SERVICE) private sessionService: StarkSessionService, @@ -176,13 +183,6 @@ export class AppModule { initializeTranslation(this.translateService); registerMaterialIconSet(matIconRegistry, domSanitizer); - const user: StarkUser = { - uuid: "abc123", - username: "John", - firstName: "Doe", - lastName: "Smith", - roles: ["dummy role"] - }; - this.sessionService.login(user); + this.sessionService.login(this.user); } } diff --git a/showcase/src/environments/environment.e2e.prod.ts b/showcase/src/environments/environment.e2e.prod.ts index 8cb0e994c7..fe000b8a20 100644 --- a/showcase/src/environments/environment.e2e.prod.ts +++ b/showcase/src/environments/environment.e2e.prod.ts @@ -1,21 +1,18 @@ -import { enableProdMode, NgModuleRef } from "@angular/core"; -import { disableDebugTools } from "@angular/platform-browser"; -import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; +import { NgModuleRef } from "@angular/core"; -enableProdMode(); +import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; export const environment: StarkEnvironment = { production: true, hmr: false, - + ENV_PROVIDERS: [], /** - * Angular debug tools in the dev console - * https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md - * @param modRef - NgModule Instance created by Angular for a given platform. + * Customize the app module. + * @param moduleRef - NgModule Instance created by Angular for a given platform. */ - decorateModuleRef(modRef: NgModuleRef): NgModuleRef { - disableDebugTools(); - return modRef; - }, - ENV_PROVIDERS: [] + decorateModule(moduleRef: NgModuleRef): NgModuleRef { + // perform any module customization needed for this specific environment here + // and make sure to invoke this function by passing it the NgModule created by Angular + return moduleRef; + } }; diff --git a/showcase/src/environments/environment.hmr.ts b/showcase/src/environments/environment.hmr.ts index 1e8df766fd..0fdb2bf706 100644 --- a/showcase/src/environments/environment.hmr.ts +++ b/showcase/src/environments/environment.hmr.ts @@ -1,30 +1,17 @@ -import { ApplicationRef, ComponentRef, NgModuleRef } from "@angular/core"; -import { enableDebugTools } from "@angular/platform-browser"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; - -// Ensure that we get detailed stack tracks during development (useful with node & Webpack) -// Reference: http://stackoverflow.com/questions/7697038/more-than-10-lines-in-a-node-js-stack-error -Error.stackTraceLimit = Infinity; -require("zone.js/dist/long-stack-trace-zone"); +import { NgModuleRef } from "@angular/core"; export const environment: StarkEnvironment = { production: false, hmr: true, - + ENV_PROVIDERS: [], /** - * Angular debug tools in the dev console - * https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md - * @param modRef - NgModule Instance created by Angular for a given platform. + * Customize the app module. + * @param moduleRef - NgModule Instance created by Angular for a given platform. */ - decorateModuleRef(modRef: NgModuleRef): NgModuleRef { - const appRef: ApplicationRef = modRef.injector.get(ApplicationRef); - const cmpRef: ComponentRef = appRef.components[0]; - - const _ng: any = (window).ng; - enableDebugTools(cmpRef); - (window).ng.probe = _ng.probe; - (window).ng.coreTokens = _ng.coreTokens; - return modRef; - }, - ENV_PROVIDERS: [] + decorateModule(moduleRef: NgModuleRef): NgModuleRef { + // perform any module customization needed for this specific environment here + // and make sure to invoke this function by passing it the NgModule created by Angular + return moduleRef; + } }; diff --git a/showcase/src/environments/environment.prod.ts b/showcase/src/environments/environment.prod.ts index 8cb0e994c7..a8ba48e4a0 100644 --- a/showcase/src/environments/environment.prod.ts +++ b/showcase/src/environments/environment.prod.ts @@ -1,21 +1,17 @@ -import { enableProdMode, NgModuleRef } from "@angular/core"; -import { disableDebugTools } from "@angular/platform-browser"; +import { NgModuleRef } from "@angular/core"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; -enableProdMode(); - export const environment: StarkEnvironment = { production: true, hmr: false, - + ENV_PROVIDERS: [], /** - * Angular debug tools in the dev console - * https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md - * @param modRef - NgModule Instance created by Angular for a given platform. + * Customize the app module. + * @param moduleRef - NgModule Instance created by Angular for a given platform. */ - decorateModuleRef(modRef: NgModuleRef): NgModuleRef { - disableDebugTools(); - return modRef; - }, - ENV_PROVIDERS: [] + decorateModule(moduleRef: NgModuleRef): NgModuleRef { + // perform any module customization needed for this specific environment here + // and make sure to invoke this function by passing it the NgModule created by Angular + return moduleRef; + } }; diff --git a/showcase/src/environments/environment.ts b/showcase/src/environments/environment.ts index 883f95d72d..4e2aa4e6fe 100644 --- a/showcase/src/environments/environment.ts +++ b/showcase/src/environments/environment.ts @@ -1,30 +1,17 @@ -import { ApplicationRef, ComponentRef, NgModuleRef } from "@angular/core"; -import { enableDebugTools } from "@angular/platform-browser"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; - -// Ensure that we get detailed stack tracks during development (useful with node & Webpack) -// Reference: http://stackoverflow.com/questions/7697038/more-than-10-lines-in-a-node-js-stack-error -Error.stackTraceLimit = Infinity; -require("zone.js/dist/long-stack-trace-zone"); +import { NgModuleRef } from "@angular/core"; export const environment: StarkEnvironment = { production: false, hmr: false, - + ENV_PROVIDERS: [], /** - * Angular debug tools in the dev console - * https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md - * @param modRef - NgModule Instance created by Angular for a given platform. + * Customize the app module. + * @param moduleRef - NgModule Instance created by Angular for a given platform. */ - decorateModuleRef(modRef: NgModuleRef): NgModuleRef { - const appRef: ApplicationRef = modRef.injector.get(ApplicationRef); - const cmpRef: ComponentRef = appRef.components[0]; - - const _ng: any = (window).ng; - enableDebugTools(cmpRef); - (window).ng.probe = _ng.probe; - (window).ng.coreTokens = _ng.coreTokens; - return modRef; - }, - ENV_PROVIDERS: [] + decorateModule(moduleRef: NgModuleRef): NgModuleRef { + // perform any module customization needed for this specific environment here + // and make sure to invoke this function by passing it the NgModule created by Angular + return moduleRef; + } }; diff --git a/showcase/src/hmr.ts b/showcase/src/hmr.ts deleted file mode 100644 index b36d9f86bb..0000000000 --- a/showcase/src/hmr.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Config from https://github.com/angular/angular-cli/wiki/stories-configure-hmr -// Maybe we should use this: https://github.com/gdi2290/angular-hmr - -import { NgModuleRef, ApplicationRef, ComponentRef } from "@angular/core"; -import { createNewHosts } from "@angularclass/hmr"; - -export const hmrBootstrap: any = (module: any, bootstrap: () => Promise>) => { - let ngModule: NgModuleRef; - module.hot.accept(); - bootstrap().then( - (mod: NgModuleRef) => (ngModule = mod), - (reason: any) => console.error("HMR bootstrap: bootstrap failed due to ", reason) - ); - module.hot.dispose(() => { - const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef); - const elements: ComponentRef[] = appRef.components.map((c: ComponentRef) => c.location.nativeElement); - const makeVisible: () => void = createNewHosts(elements); - ngModule.destroy(); - makeVisible(); - }); -}; diff --git a/showcase/src/main.browser.ts b/showcase/src/main.browser.ts index 9ef3674b57..dd90422fd7 100644 --- a/showcase/src/main.browser.ts +++ b/showcase/src/main.browser.ts @@ -1,57 +1,36 @@ -/** - * Angular bootstrapping - */ -import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; -import { environment } from "./environments/environment"; /** * App Module * our top level module that holds all of our components */ import { AppModule } from "./app"; -import { hmrBootstrap } from "./hmr"; +import { AbstractStarkMain, StarkEnvironment } from "@nationalbankbelgium/stark-core"; +import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; -/** - * Bootstrap our Angular app with a top level NgModule - */ -export function main(): Promise { - return platformBrowserDynamic() - .bootstrapModule(AppModule) - .then(environment.decorateModuleRef) - .catch((err: any) => console.error(err)); -} +import { environment } from "environments/environment"; -/** - * Needed for hmr - * in prod this is replace for document ready +/* + * Bootstrap our Angular app with a top level component `App` and inject + * our Services and Providers into Angular's dependency injection system */ -switch (document.readyState) { - case "loading": - document.addEventListener("DOMContentLoaded", _domReadyHandler, false); - break; - case "interactive": - case "complete": - default: - if (HMR) { - if (module["hot"]) { - hmrBootstrap(module, main); - } else { - console.error("HMR is not enabled for webpack-dev-server!"); - } - } else { - main().catch((err: any) => console.error(err)); - } -} - -function _domReadyHandler(): void { - document.removeEventListener("DOMContentLoaded", _domReadyHandler, false); - if (HMR) { - if (module["hot"]) { - hmrBootstrap(module, main); - } else { - console.error("HMR is not enabled for webpack-dev-server!"); - } - } else { - main().catch((err: any) => console.error(err)); +class Main extends AbstractStarkMain { + public constructor(env: StarkEnvironment) { + super(env); } + + public main = (): Promise => { + console.log("Bootstrapping the App"); + + // Bootstrap our Angular app with a top level NgModule + return ( + platformBrowserDynamic() + .bootstrapModule(AppModule) + // the line below adapts the module depending on the environment + // if you don't like what stark does by default, you can instead do your own customizations through the environment.* files + // and use environment.customizeAppModule instead + .then(this.decorateModule) + ); + }; } + +new Main(environment).bootstrap(); diff --git a/starter/package.json b/starter/package.json index 899854aafb..68bebdb2bc 100644 --- a/starter/package.json +++ b/starter/package.json @@ -124,8 +124,8 @@ "@angular/platform-browser-dynamic": "6.0.4", "@angular/platform-server": "6.0.4", "@angular/router": "6.0.4", - "@nationalbankbelgium/stark-core": "file:../dist/packages-dist/stark-core/nationalbankbelgium-stark-core-10.0.0-alpha.3-6796ad0.tgz", - "@nationalbankbelgium/stark-ui": "file:../dist/packages-dist/stark-ui/nationalbankbelgium-stark-ui-10.0.0-alpha.3-6796ad0.tgz", + "@nationalbankbelgium/stark-core": "file:../dist/packages-dist/stark-core/nationalbankbelgium-stark-core-10.0.0-alpha.3-6fc4fb3.tgz", + "@nationalbankbelgium/stark-ui": "file:../dist/packages-dist/stark-ui/nationalbankbelgium-stark-ui-10.0.0-alpha.3-6fc4fb3.tgz", "@uirouter/visualizer": "6.0.0", "core-js": "2.5.7", "eligrey-classlist-js-polyfill": "1.2.20180112", @@ -140,8 +140,8 @@ "zone.js": "0.8.26" }, "devDependencies": { - "@nationalbankbelgium/stark-build": "file:../dist/packages-dist/stark-build/nationalbankbelgium-stark-build-10.0.0-alpha.3-6796ad0.tgz", - "@nationalbankbelgium/stark-testing": "file:../dist/packages-dist/stark-testing/nationalbankbelgium-stark-testing-10.0.0-alpha.3-6796ad0.tgz", + "@nationalbankbelgium/stark-build": "file:../dist/packages-dist/stark-build/nationalbankbelgium-stark-build-10.0.0-alpha.3-6fc4fb3.tgz", + "@nationalbankbelgium/stark-testing": "file:../dist/packages-dist/stark-testing/nationalbankbelgium-stark-testing-10.0.0-alpha.3-6fc4fb3.tgz", "@types/core-js": "2.5.0", "@types/hammerjs": "2.0.35", "@types/node": "8.10.15", diff --git a/starter/src/environments/environment.e2e.prod.ts b/starter/src/environments/environment.e2e.prod.ts index 2016e43d3d..49e1601798 100644 --- a/starter/src/environments/environment.e2e.prod.ts +++ b/starter/src/environments/environment.e2e.prod.ts @@ -1,24 +1,20 @@ -import { enableProdMode, NgModuleRef } from "@angular/core"; -import { disableDebugTools } from "@angular/platform-browser"; +import { NgModuleRef } from "@angular/core"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; -enableProdMode(); - /** * @ignore */ export const environment: StarkEnvironment = { production: true, hmr: false, - + ENV_PROVIDERS: [], /** - * Angular debug tools in the dev console - * https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md - * @param modRef - NgModule Instance created by Angular for a given platform. + * Customize the app module. + * @param moduleRef - NgModule Instance created by Angular for a given platform. */ - decorateModuleRef(modRef: NgModuleRef): NgModuleRef { - disableDebugTools(); - return modRef; - }, - ENV_PROVIDERS: [] + decorateModule(moduleRef: NgModuleRef): NgModuleRef { + // perform any module customization needed for this specific environment here + // and make sure to invoke this function by passing it the NgModule created by Angular + return moduleRef; + } }; diff --git a/starter/src/environments/environment.hmr.ts b/starter/src/environments/environment.hmr.ts index a6c48f374c..810d5d7778 100644 --- a/starter/src/environments/environment.hmr.ts +++ b/starter/src/environments/environment.hmr.ts @@ -1,33 +1,20 @@ -import { ApplicationRef, ComponentRef, NgModuleRef } from "@angular/core"; -import { enableDebugTools } from "@angular/platform-browser"; +import { NgModuleRef } from "@angular/core"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; -// Ensure that we get detailed stack tracks during development (useful with node & Webpack) -// Reference: http://stackoverflow.com/questions/7697038/more-than-10-lines-in-a-node-js-stack-error -Error.stackTraceLimit = Infinity; -require("zone.js/dist/long-stack-trace-zone"); - /** * @ignore */ export const environment: StarkEnvironment = { production: false, hmr: true, - + ENV_PROVIDERS: [], /** - * Angular debug tools in the dev console - * https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md - * @param modRef - NgModule Instance created by Angular for a given platform. + * Customize the app module. + * @param moduleRef - NgModule Instance created by Angular for a given platform. */ - decorateModuleRef(modRef: NgModuleRef): NgModuleRef { - const appRef: ApplicationRef = modRef.injector.get(ApplicationRef); - const cmpRef: ComponentRef = appRef.components[0]; - - const _ng: any = (window).ng; - enableDebugTools(cmpRef); - (window).ng.probe = _ng.probe; - (window).ng.coreTokens = _ng.coreTokens; - return modRef; - }, - ENV_PROVIDERS: [] + decorateModule(moduleRef: NgModuleRef): NgModuleRef { + // perform any module customization needed for this specific environment here + // and make sure to invoke this function by passing it the NgModule created by Angular + return moduleRef; + } }; diff --git a/starter/src/environments/environment.prod.ts b/starter/src/environments/environment.prod.ts index 2016e43d3d..49e1601798 100644 --- a/starter/src/environments/environment.prod.ts +++ b/starter/src/environments/environment.prod.ts @@ -1,24 +1,20 @@ -import { enableProdMode, NgModuleRef } from "@angular/core"; -import { disableDebugTools } from "@angular/platform-browser"; +import { NgModuleRef } from "@angular/core"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; -enableProdMode(); - /** * @ignore */ export const environment: StarkEnvironment = { production: true, hmr: false, - + ENV_PROVIDERS: [], /** - * Angular debug tools in the dev console - * https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md - * @param modRef - NgModule Instance created by Angular for a given platform. + * Customize the app module. + * @param moduleRef - NgModule Instance created by Angular for a given platform. */ - decorateModuleRef(modRef: NgModuleRef): NgModuleRef { - disableDebugTools(); - return modRef; - }, - ENV_PROVIDERS: [] + decorateModule(moduleRef: NgModuleRef): NgModuleRef { + // perform any module customization needed for this specific environment here + // and make sure to invoke this function by passing it the NgModule created by Angular + return moduleRef; + } }; diff --git a/starter/src/environments/environment.ts b/starter/src/environments/environment.ts index 1a66c49364..685ec73ac5 100644 --- a/starter/src/environments/environment.ts +++ b/starter/src/environments/environment.ts @@ -1,11 +1,5 @@ -import { ApplicationRef, ComponentRef, NgModuleRef } from "@angular/core"; -import { enableDebugTools } from "@angular/platform-browser"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; - -// Ensure that we get detailed stack tracks during development (useful with node & Webpack) -// Reference: http://stackoverflow.com/questions/7697038/more-than-10-lines-in-a-node-js-stack-error -Error.stackTraceLimit = Infinity; -require("zone.js/dist/long-stack-trace-zone"); +import { NgModuleRef } from "@angular/core"; /** * @ignore @@ -13,21 +7,14 @@ require("zone.js/dist/long-stack-trace-zone"); export const environment: StarkEnvironment = { production: false, hmr: false, - + ENV_PROVIDERS: [], /** - * Angular debug tools in the dev console - * https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md - * @param modRef - NgModule Instance created by Angular for a given platform. + * Customize the app module. + * @param moduleRef - NgModule Instance created by Angular for a given platform. */ - decorateModuleRef(modRef: NgModuleRef): NgModuleRef { - const appRef: ApplicationRef = modRef.injector.get(ApplicationRef); - const cmpRef: ComponentRef = appRef.components[0]; - - const _ng: any = (window).ng; - enableDebugTools(cmpRef); - (window).ng.probe = _ng.probe; - (window).ng.coreTokens = _ng.coreTokens; - return modRef; - }, - ENV_PROVIDERS: [] + decorateModule(moduleRef: NgModuleRef): NgModuleRef { + // perform any module customization needed for this specific environment here + // and make sure to invoke this function by passing it the NgModule created by Angular + return moduleRef; + } }; diff --git a/starter/src/hmr.ts b/starter/src/hmr.ts deleted file mode 100644 index 193884bbd3..0000000000 --- a/starter/src/hmr.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Config from https://github.com/angular/angular-cli/wiki/stories-configure-hmr -// Maybe we should use this: https://github.com/gdi2290/angular-hmr - -import { NgModuleRef, ApplicationRef, ComponentRef } from "@angular/core"; -import { createNewHosts } from "@angularclass/hmr"; - -/** - * @ignore - */ -export const hmrBootstrap: any = (module: any, bootstrap: () => Promise>) => { - let ngModule: NgModuleRef; - module.hot.accept(); - bootstrap().then( - (mod: NgModuleRef) => (ngModule = mod), - (reason: any) => console.error("HMR bootstrap: bootstrap failed due to ", reason) - ); - module.hot.dispose(() => { - const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef); - const elements: ComponentRef[] = appRef.components.map((c: ComponentRef) => c.location.nativeElement); - const makeVisible: () => void = createNewHosts(elements); - ngModule.destroy(); - makeVisible(); - }); -}; diff --git a/starter/src/main.browser.ts b/starter/src/main.browser.ts index cac212a437..dd90422fd7 100644 --- a/starter/src/main.browser.ts +++ b/starter/src/main.browser.ts @@ -1,60 +1,36 @@ -/** - * Angular bootstrapping - */ -import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; -import { environment } from "./environments/environment"; /** * App Module * our top level module that holds all of our components */ import { AppModule } from "./app"; -import { hmrBootstrap } from "./hmr"; +import { AbstractStarkMain, StarkEnvironment } from "@nationalbankbelgium/stark-core"; +import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; -/** - * Bootstrap our Angular app with a top level NgModule - */ -export function main(): Promise { - return platformBrowserDynamic() - .bootstrapModule(AppModule) - .then(environment.decorateModuleRef) - .catch((err: any) => console.error(err)); -} +import { environment } from "environments/environment"; -/** - * Needed for hmr - * in prod this is replace for document ready +/* + * Bootstrap our Angular app with a top level component `App` and inject + * our Services and Providers into Angular's dependency injection system */ -switch (document.readyState) { - case "loading": - document.addEventListener("DOMContentLoaded", _domReadyHandler, false); - break; - case "interactive": - case "complete": - default: - if (HMR) { - if (module["hot"]) { - hmrBootstrap(module, main); - } else { - console.error("HMR is not enabled for webpack-dev-server!"); - } - } else { - main().catch((err: any) => console.error(err)); - } -} - -/** - * @ignore - */ -function _domReadyHandler(): void { - document.removeEventListener("DOMContentLoaded", _domReadyHandler, false); - if (HMR) { - if (module["hot"]) { - hmrBootstrap(module, main); - } else { - console.error("HMR is not enabled for webpack-dev-server!"); - } - } else { - main().catch((err: any) => console.error(err)); +class Main extends AbstractStarkMain { + public constructor(env: StarkEnvironment) { + super(env); } + + public main = (): Promise => { + console.log("Bootstrapping the App"); + + // Bootstrap our Angular app with a top level NgModule + return ( + platformBrowserDynamic() + .bootstrapModule(AppModule) + // the line below adapts the module depending on the environment + // if you don't like what stark does by default, you can instead do your own customizations through the environment.* files + // and use environment.customizeAppModule instead + .then(this.decorateModule) + ); + }; } + +new Main(environment).bootstrap();