Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): integrated bootstrap #483

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
4 changes: 3 additions & 1 deletion packages/rollup.config.common-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
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";
163 changes: 163 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,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<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();
};

/**
* 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<NgModuleRef<any>>) => {
if(ENV === "development") {
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.
* Adapt 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
1 change: 1 addition & 0 deletions packages/stark-ui/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions packages/stark-ui/tsconfig-build.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
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);
}
}
Loading