Angular Templates & Time To First Commit
One of my favorite things about Angular is how the template is just a simple HTML file.
This is really great; especially if you care about Collective Ownership. With some basic HTML knowledge, anyone can contribute to the application’s development: other teams, external web designers… or even the Product Owner! Why not!?
In other words, using HTML templates reduces the TTFC (Time To First Commit) which is the average time it takes for someone new in your team to make his first change.
Tired of Importing Modules
Now, the thing that I don’t like that much about Angular is how the template is just a simple HTML file. Wait wait wait! Let me try to explain!
In Angular, every component, directive or pipe has some kind of selector (or name) that we can use in our components’ templates. When the template is compiled, the implementation is resolved depending on the component’s module imports.
To interpret the content of a template, the runtime needs to know what component and directives to apply to the element and what pipes are referenced by binding expressions. The list of candidate components, directives and pipes are determined by the
NgModulein which the component is declared.
The official and complete explanation is here: https://github.com/angular/angular/blob/master/packages/compiler/design/architecture.md#the-selector-problem
The problem with this approach is that we need to import the right module every time we want to use another component, a directive or a pipe.
Which Module Should I Import Again?
A while ago, I was explaining reactive forms during a training so I wrote this:
… it produced the expected error
Can’t bind to ‘formGroup’ since it isn’t a known property of ‘form’
… and I explained that we have to import
Then someone asked:
How did you know which module you should import?
That’s when I realized that for someone very new to Angular, this was not intuitive at all. That’s also when I noticed that the related question on stackoverflow had more than 300 000 views.
Can't bind to 'formGroup' since it isn't a known property of 'form'
THE SITUATION: Please help! I am trying to make what should be a very simple form in my Angular2 app but no matter what…
I started thinking about a new way of writing Angular templates so I stumbled upon this brilliant initiative called Ng-VDom.
But still, it was not exactly what I was looking for as I just wanted a new way for writing templates and not a new way of rendering components.
A New Way of Writing Templates
That’s when I got inspiration from htm which stands for Hyperscript Tagged Markup.
I liked how it was simply using standard tagged templates so I came up with the
ngMarkup tagged template which works like this:
- Red is an Angular directive.
- Up is an Angular pipe.
The working example’s source code is here: https://github.com/wishtack/wishtack-experiments/blob/ng-markup/src/app/app.module.ts
The main advantage of this syntax is that the components, directives, and pipes used in the template are explicitly imported.
The current implementation doesn’t survive AOT as it would need a pre-compiler or upgrading IVY compiler:
Getting rid of explicit
ngModule declarations & exports
As you can see in the given example’s source code, the components, directives, and pipes are still explicitly declared or imported in
In order to fix the last issue, it would be nice to let
ngMarkup import the dependencies in the component’s local scope at compile time.
There’s a great article about this here: https://blog.angularindepth.com/angular-revisited-tree-shakable-components-and-optional-ngmodules-329a4629276d by Lars Gyrup Brink Nielsen
I was looking forward to using the someday-maybe-upcoming
deps property in component configuration which appears in this Pull Request https://github.com/angular/angular/pull/27481 by Minko Gechev ... but the work on this feature seems to be stalled for the moment.
I am really looking forward to hearing from any feedback about this kind of syntax.
Does it sound easier to read and maintain?
Is it too hacky?
Do you think it somewhat violates the separation of concerns or is it fair?
IDEs To The Rescue
Luckily, lately, I was explaining the exact same thing and the error didn’t happen.
Actually, I used WebStorm’s Angular module auto-import without noticing.
Maybe in some near future, IDEs magic might make this whole post and experiment useless 😅
If you want to learn more about Angular and if you can read French (or if you don’t mind using google translate meanwhile I translate the content), you can have a look at our FREE Angular Guide https://guide-angular.wishtack.io/.