Skip to content

Commit

Permalink
feat(core): integrated bootstrap
Browse files Browse the repository at this point in the history
Closes #112 #412
  • Loading branch information
dsebastien committed Jul 5, 2018
1 parent 9c3453d commit 83f41e9
Show file tree
Hide file tree
Showing 23 changed files with 344 additions and 311 deletions.
23 changes: 14 additions & 9 deletions docs/ENVIRONMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<any>): NgModuleRef<any>;
decorateModule(moduleRef: NgModuleRef<any>): NgModuleRef<any>;
}
```

Expand Down Expand Up @@ -63,17 +64,17 @@ 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 = {
production: true,
hmr: false,
ENV_PROVIDERS: [ProductionOnlyProvider],

decorateModuleRef(modRef: NgModuleRef<any>): NgModuleRef<any> {
disableDebugTools(); // disable debug tools in production
return modRef;
decorateModule(moduleRef: NgModuleRef<any>): NgModuleRef<any> {
// 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;
}
};
```
Expand Down Expand Up @@ -131,8 +132,10 @@ export const environment: StarkEnvironment = {
hmr: false,
ENV_PROVIDERS: [],

decorateModuleRef(modRef: NgModuleRef<any>): NgModuleRef<any> {
/* do something here */
decorateModule(moduleRef: NgModuleRef<any>): NgModuleRef<any> {
// 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;
}
};
```
Expand Down Expand Up @@ -178,8 +181,10 @@ export const environment: StarkEnvironment = {
ENV_PROVIDERS: [],
someProperty: "some value", // your new property

decorateModuleRef(modRef: NgModuleRef<any>): NgModuleRef<any> {
/* do something here */
decorateModule(moduleRef: NgModuleRef<any>): NgModuleRef<any> {
// 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;
}
};
```
Expand Down
1 change: 0 additions & 1 deletion packages/stark-build/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions packages/stark-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions packages/stark-core/src/common.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./common/bootstrap";
export * from "./common/environment";
export * from "./common/error";
export * from "./common/routes";
Expand Down
2 changes: 2 additions & 0 deletions packages/stark-core/src/common/bootstrap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./bootstrap/abstract-stark-main";
export * from "./bootstrap/stark-main.intf";
158 changes: 158 additions & 0 deletions packages/stark-core/src/common/bootstrap/abstract-stark-main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
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<any>;

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();
};

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 (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();
}
};

/**
* Calls 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.readyToGo();
}
};

/**
* 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<NgModuleRef<any>>) => {
console.log("Bootstrapping HMR");
let ngModule: NgModuleRef<any>;
module.hot.accept();
bootstrap().then(
(mod: NgModuleRef<any>) => (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<any>[] = appRef.components.map((c: ComponentRef<any>) => c.location.nativeElement);
const makeVisible: () => void = createNewHosts(elements);
ngModule.destroy();
makeVisible();
});
};

/**
* Modify/decorate the NgModule instance created by Angular.
* Adapts the configuration based on the current environment
* @param moduleRef - NgModule instance created by Angular for a given platform.
*/
public decorateModule = (moduleRef: NgModuleRef<any>): NgModuleRef<any> => {
// 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<any> = appRef.components[0];
enableDebugTools(cmpRef);

const _ng: any = (<any>window).ng;
(<any>window).ng.probe = _ng.probe;
(<any>window).ng.coreTokens = _ng.coreTokens;
}

return moduleRef;
};
}
23 changes: 23 additions & 0 deletions packages/stark-core/src/common/bootstrap/stark-main.intf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { NgModuleRef } from "@angular/core";

/**
* Main entry point
*/
export interface StarkMain {
/**
* Main function: responsible for starting the application.
*/
main: () => Promise<any>;

/**
* 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<any>): NgModuleRef<any>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<any>): NgModuleRef<any>;
decorateModule(moduleRef: NgModuleRef<any>): NgModuleRef<any>;
}

/**
Expand Down
8 changes: 4 additions & 4 deletions showcase/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
22 changes: 11 additions & 11 deletions showcase/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -116,7 +115,7 @@ export function logger(reducer: ActionReducer<State>): any {
export const metaReducers: MetaReducer<State>[] = 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],
Expand Down Expand Up @@ -167,6 +166,14 @@ export const metaReducers: MetaReducer<State>[] = 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,
Expand All @@ -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);
}
}
23 changes: 10 additions & 13 deletions showcase/src/environments/environment.e2e.prod.ts
Original file line number Diff line number Diff line change
@@ -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<any>): NgModuleRef<any> {
disableDebugTools();
return modRef;
},
ENV_PROVIDERS: []
decorateModule(moduleRef: NgModuleRef<any>): NgModuleRef<any> {
// 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;
}
};
Loading

0 comments on commit 83f41e9

Please sign in to comment.