Your code’s bug-free, or maybe not. Don’t trust Angular to tell you either way!
If you don’t know what you’re doing with Angular, it may have a nasty surprise up its sleeve as you put your code into Production.
ng build Command
I was working on an Angular project today. The code picks up some data from a back-end API and displays it in a table with some editable fields. I’d only run the code in Dev Mode, i.e via an
ng serve command at the command line, and had confirmed that it worked as it should in the browser. Neither the browser, the Angular CLI compiler nor my code editor (SublimeText) reported any errors.
I was curious to see what the final build file sizes would be, so I issued an
ng build in the console. That seemed to compile successfully. but finished up with a message telling me to use the
--prod switch for a proper Production build. That sounded like a good idea, so I ran it again with the switch, i.e.
ng build --prod command.
Things Go South
That’s when everything went to shit.
The result of that
ng build --prod command was that I was now staring at console showing 40+ errors, all in glorious red, and a project that refused to compile. And these weren’t build config errors either; no, the Angular CLI compiler was now flagging multiple errors in my code!!! And all errors that I’d never seen previously.
I had to double check to see that I hadn’t pulled down the wrong branch from the Git repository. But no, I hadn’t. This was the exact same code that was working perfectly with
ng serve. How could that possibly be?
Doctor JIT and Mr AoT
It seems that the Angular CLI’s compiler has a split personality. I won’t bore you with full details, which you can read for yourself in the docs. But briefly, it has a Just in Time (JIT) mode for Development and and Ahead of Time (AoT) compilation mode that’s intended for Production.
What’s not immediately obvious, however, (because it’s, basically, insane), is that AoT compilation holds your code to a higher standard of conformity to Angular standards than JIT mode does. It seems that JIT compilation lets you get away with a degree of coding sloppiness that AoT simply won’t allow. But crucially, nowhere in the console are you ever actually told this is happening when you’re using a JIT compilation option. Nope, not until you run right smack up against it the hard way, are you ever aware that this issue even exists.
Fit For Purpose?
I simply can’t comprehend the thinking behind a “feature” like this. How did anybody in the Angular Team possibly think that this could be a good idea? Did nobody in the room that day think to put their hand up and say something like:
Hey, maybe it’s not such a good idea to tell Devs that their code is A-OK one minute, but crap the next, when they haven’t actually changed a single line of it?
How to Workaround
In truth, it’s not a huge deal to work around this issue, once you know about. It’s the finding about it in the first place that’s the thing.
The extra errors are mainly to do with trying to exposing variables in your templates that are not reachable in your components. I was able to fix a number of them by simply redeclaring Private variables as Public, for example.
Other things that you can do to make sure that you don’t get bitten by this:
- Stick with JIT for Production. You don’t have to use AoT in the first place, of course, although it’s the Angular Team’s preferred option. You can stick with the JIT build — i.e run
ng buildwithout no switches. But you’re likely to end up with a build that is bigger and slower than that which AoT would have delivered.
ng serve --aotto serve up your Dev code in preference to
ng serve. That
--aotswitch forces use of AoT mode, and so will uncover all those extra “errors” nice and early. Preferable to having them lurking around until you do your AoT build for Prod. Note: your build times will be slower with the
- Install the Angular Language Services extension in your code editor. It’s available for most of the biggies. I was not able to get it working in Sublime 😢, but it flagged these extra “bugs” for me when I installed it in VSCode.