Put your Angular app config very close to production

Peter Momot

Why? The simple answer is: you just need to. Otherwise you will face some strange production configuration errors, right in the process of development.

The main thing, that I’m referring to in this post is Angular’s Ahead-of-Time compiler. By default it’s disabled in Angular cli  ng build  command and enabled in ng build --prod command. So, to avoid some time of pain in future you can simply add  --aot flag to every build command that you have.

There are three issues described here, but the problem was mostly in one thing,—in providers list on  NgModule  configuration step we were supposed to provide values via useFactory and not via  useValue (tested it now on the first error with newer version of the framework and it seems to be working fine with both options—it means that angular devs probably fixed this on their side).

Consequence of using  useValue

First thing is window —at some point we needed to add event listener to window resize event, and we did (decided to provide it in the module configuration step). The consequences of using useValue were really bad — router prepended new states to the body, leaving previous ones at the bottom of the page, dialogs and some other material components behaved weird and all of this was with just one error in the console about window provider. Fortunately at that point production environment was not fully setup and we didn’t have actual users there 🙂

Problems with JWT Configuration

Second and third issues are related to JWT configuration. We are using JWT tokens in our platform so the package angular-jwt (that needs to be configured on the module setup level) was included in order to use it in the WebApp. This configuration caused two errors with --aot in different moments of development. One was in tokenGetter function and another in passing value into regular expression and using this expression in whitelistedDomains list for JWT.

So, the issue with tokenGetter was causing trouble right on the login page?—?Log in button just didn’t work for the user and console didn’t show any error. We could catch an error only by debugging and we found out that the compiled ES6 getter failed. Due to all this login method didn’t run at all. And again, replacing useValue with useFactory did the job.

Problem with RegEx and it’s value that depends on environment was a bit harder to solve. We faced a need of contacting projects on our platform directly from the front end and each one of them has it’s own subdomain which looks like projectId.app.jexia.com where IDs are UUID. In this URL we knew only last part on module configuration step, but fortunately JWT library supports RegEx in list of whitelistedDomains.

Here we did the following for our Angular app:

– Created dynamic regular expression as a factory on module level

– Passed config options to jwt through provider with regular expression factory as a dependency and config options as a factory

– Used dependency in config options factory

Only after these manipulations (O_o) we were able to get regular expression properly initialized. With initial config it was just removed by AoT.

As a conclusion we can say (again), that it’s always better to catch errors or possible failing scenarios sooner than later and fix them during the development or testing process, but not after deploy to production.