While doing Cool:GEN migratiotions to Java and C# we produce rather big Angular applications.
Everything is fine: server runs a REST APIs, and client is an Angular application with components per each window, dialog or screen. The only problem is with the word big.
We observe that enterprises that used Cool:GEN to develop their workflow come to migration stage with applications containing thousands of windows. In simple cases, after assessment, clients are able to split their monolith workflow into a set of independent applications. But even then we are dealing with Angular applications containing hundreds to many thousands components.
Now, lets look at Angular world. Best practices advice to (and actually almost force you to) use Ahead Of Time, Ivy compilation of all components and their templates.
Naive attempt to build such monolith Angular application will most surely fail. Angular uses nodejs for build, and chances are close to 100% of nodejs to run out of memory during the
You may fight and throw at it a capable build machine with 16 or better with 32GB of RAM, and instruct nodejs to use all of it.
Well, it's rather poor and extensive way of dealing with scale problems but it works.
Next hurdle you run into is time. We know it might take days just to build it.
You may ask why?
Well, angular is doing its best to validate templates!
Unfortunately the only viable workaround is to switch this nice feature off for such a big project.
With such setup you're able to build angular project in just 20-30 minutes!
Well, this is a big progress if you compare complete failure vs something that at least passes the build.
But what's next?
Sure, there are next problems:
- scripts both development and production are of nonsense size: like several dozen megabytes for production, and some even higher number for development.
ng serve eats even more memory and builds even longer making nightmare out of development and support of such an application;
- startup of such application, if it will start at all, is very slow.
So, what can be done? How can we create a manageable Angular application containing that many components?
Angular advices Lazy-loading feature modules.
That's reasonable advice!
We can create coarse grained modules containing subsets of components or fine grained modules containing one component.
So, does it help?
Yes, but it does not solve all problems:
ng build and
ng serve are still very slow;
- build produces multiple small scripts that are loaded on demand, so at least application works in browser.
Yet, other important problem is still there: we have multiple severly separated server REST controllers with components that represent them.
On the server side we have Java or C# REST controllers hosting business logic. They are separated per multiple projects probably managed by separate teams, and probably kept in separate GITs (or whatever). On the client side we have a fat angular project storing everything kept in single source repository.
This is not going to work from management perspective.
So the next step is try to split fat Angular project into multiple small projects. So, let's say we shall have 100 small angular libraries combinded by master project.
This is not going to work either due to nature of npm projects, as it will requre terabytes of cloned node_modules folders for each library, and many hours to build each of them.
It seems there is a room for improvments in npm area. There is no point to make dedicated copies of node_modules. It's much easier to have a local cache of artifacts.
So, what is the direction? How to create big angular project after all?
What we have here is:
- a big enterprise level application;
- it is modular but modules must work together to form desired workflow;
- different modules are supported by different teams (both server and client side);
- client Angular components correspond to REST controllers on the server.
- all pages use the same styles and the same set of UI controls;
Looking from this perspective all development can be seen as:
- development and support of unified styles and ui components that must be reused through the application;
- development of server side and REST controllers that implement business logic;
- development of templates of components (note that components themselves do nothing except expose their templates).
Studying this design suggests important and independent role of templates just like it is in AngularJS!
In contrast Angular templates are only a tool used by components. It's not obvious how to use thousands of templates without first building thousands components; neither it's obvious how to dynamically host those templates (routes do not help here).
Though not obvious it's still possible to do it though it requires use a bit lower level API than tutorials suggest. Ingredients are:
- use of Just In Time (in contrast to Ahead Of Time) compilation, and use View Enginev (in contrast to Ivy);
- use ViewContainerRef to host components dynamically;
- Dynamic components and modules that you can create on demand using templates loaded e.g. through
To make things short we shall show the example of dynamic components in next article.
Here we shall emphasize that such design allows us to create small angular application that builds under 20 seconds with component templates served along with the REST controllers, and stored in the same Git.
So, if you say have a server subproject exposing REST controller say in the form: api/area/MyComponent then its template may be exposed as resource: page/area/MyComponent. Templates are loaded and compiled on demand at runtime thus making application light. At the same time templates may be cached in browser cache thus reducing number of roundtrips to the server.