Over the last year, I have helped my team develop and deliver many Angular applications into production. This included Desktop web, RWD, Hybrid, etc. Over this period, I started feeling the need to have a ready starter kit for the teams — which include more enterprisy features. Angular CLI is a great starter kit to get Angular app setup. It gives you the foundation piece but that’s pretty much where it leaves ya! So I decided to build a enterprise ready seed app for Angular using Angular-CLI as foundation.
Every project has possibility to see success, if it had some good goals defined. Goals for this project would be:
- Add few libraries / custom implementations to provide for enterprise focused features— Busy indicators, Authorization check in templates and functions (along with route-guards, of course)
- Provide lazy loading of routes by default, including home page and thereby reduce the bundle size of main bundle to absolute minimum.
- Keep bundle size in check, after every iterations. Discard any library that proves to add too much deadweight.
- Add notifications — in page as well as floating
- Add form validation sample
- Slim scrollbars
- Conditional Logging (disable certain logs in PROD automatically)
- Make it open-source under MIT license!
I am planning to write series of best practices (at a code level) here based on how this seed shapes up.
TL;DR; Where is my code?
Here is the code for Angular CLI based Enterprise App Seed which I developed! Remember to 🌟️ the project on github for bookmarking it!
But I do urge you to read through this entire piece to understand various code pieces of the seed and why they exist.
This code implements many best practices and hence I have decided to split this post into multiple posts with 3–4 best practices at a time.
Architecturally Significant Best Practices — part I
1. Defaulting to SCSS
SCSS provide far more advantages than regular CSS e.g. variables support (helpful in global changes, theming etc), compact style definition by adapting tree structure, mixins, code generation, etc. Almost all mature styling libraries and component libraries use SCSS as their style definition engine. Any enterprise app should definitely use SCSS.
new command by default generates application with css as styling option. While this is OK for some naive implementations, any application that uses bootstrap or any other css system — should know that they are adding way too much of CSS by adding entire distribution css file. Bootstrap4 is OOTB sass enabled. Bootstrap v3 has
bootstrap-sass npm package which is fully supported.
So — its important that our application supports SCSS and you include only the required parts of any CSS library using scss.
If you are about run
new then — please add additional option
--style scss. That’s it! Now newly generated code will default to SCSS. Any new components you will generate will also have .scss as default extension for styles. If you have already generated the app, you can still make change in
.angular-cli.json file in
defaults section for future component generations.
Pro Tip: While you are doing this — you might also want to add
--skip-install options if you do not intend to write tests and if you don’t want Angular CLI to start running the install (using Yarn if you have it installed).
--routing option is also highly recommended for enterprise apps.
2. CSS reset (normalize)
Its very important to use a good style reset so that most basic rendering of html components appears identical in all browsers. If you use bootstrap / Zurb foundation — they have resets built into it. If you are starting from scratch though, a reset is a MUST. You can go for one of the normalize.css + sanitize.css / meyerweb reset / simple css reset / html5 boilerplate reset.
For this seed — I have used normalize.css + sanitize.css option. While normalize is a great reset. It does not provide
box-sizing: border-box and other such defaults. These are added by sanitize.css — which is written by co-author of normalize.css.
If you are planning to use bootstrap — you can remove this combo are those things are taken care of by bootstrap.
3. Ready-made Authorization directives
One more key ask from all enterprise applications is to have authorization support. After sifting through multiple libraries, I narrowed down my selection to ngx-permissions.
- ngx-permissions provide 3 directives to quickly describe the authorization requirements in templates.
- The directives are AOT ready.
- It also provides comprehensive routeguard and redirection to another route when user is not authorized for that route.
- Both canActivate as well as canLoad guards are supported.. so you can exclude modules from getting downloaded when the user does not have right permissions.
How to include this in your code?
package.json — (
yarn add ngx-permissions)
src/app/app.module.ts — Add
NgxPermissionsModule.forRoot() in imports. IMPORTANT: This must be in your applications main module (often app.module in Angular-CLI generated projects)
src/app/app.component.ts — retrieve set of permissions from backend service call / OAuth2 redirect headers, etc and push them ngx-permissions’ PermissionService and RoleService instances.
src/app/<yourcompoent>/<your comp.html> — add ngxPermisssions* directives. e.g.
<div>Viewable List of Experts here.. accessible to permission “listExperts”</div>
4. Using shared modules
If you have not been creating modules in your Angular application; you should stop now and first read about benefits of doing so. One of the important reason being Lazy Loading of rest of the application. Other being re-usability.
Shared modules help providing commons services and components which can be re-used across multiple application modules. Any enterprise app — I can envision — to have at least one shared modules.
Take a look at
src/app/appcommon/appcommon.module.ts for understand how to write common modules.. Especially, see the
exports property to understand how we make shared-module code accessible to rest of the world.
For the sake of content length, I would stop here. Next parts of this post would elaborate below items. The code on github already has the required implementation for many of these items:
- UX Improvement — Thin scrollbars
- High productivity — PrimeNG Component Library
- Using Animations in various parts of application
- Dynamic log level setting to do effective debugging
- Lazy-loading everything including the home page.
- Common HTTP Headers using HTTP_INTERCEPTORS
- Global Shared state using AppState
- Keeping Track of your bundle size
- Settle between NPM and Yarn (via yarn-or-die)
- IE11 Support
- json-server and freedom from backend integration to a certain extent
- Adverse impacts of calling forRoot() call for various 3rd party modules in shared modules.
- Why using Async pipes (
| async) in templates is awesome
- LocalStorage / IndexedDB for persistent.
You are welcome to contribute to the code via code-review, feature requests, PRs and other ways.
To ensure you get the rest of the posts — please follow me on Medium by clicking my “follow” button next to my name below this line.