Some aspects of complex Angular projects

As previously noted in the previous post, the concept of the Angular working directory naturally evolved to support full-fledged workspace – a proven and straightforward way to manage complexity while scaling the development process (Visual Studio Solution , SBT Multi-Project builds , Gradle Multi-Project Builds , RushJS , Lerna and etc. ).

For everyone who has practically come across an Angular project middle hand, it will not be a secret that angular.json can easily contain thousands of lines of small JSON, with an incredible, even deliberately redundant amount of duplicate information. The problem is by no means not new and making itself felt when scaling the process of developing a complex product. The compactness and human-readability of the format was clearly not a priority, and, as it were, hints that a person has nothing to do here. We will proceed from this.

Some problems

  1. Verbosity… To navigate in a long “footcloth” is very uncomfortable. When making changes, there is a high risk of making them in the wrong place. That also makes it difficult to understand when analyzing the history of changes.

  2. Violation of the principle DRY When changing file paths, you must carefully make multiple identical changes to many different parameters.

  3. Absence locality… It means that the file angular.json, describing the settings of a specific project, and the project itself are in different places. Which makes it somewhat difficult to quickly understand which projects are affected by what changes. It also makes it a little more difficult to create a new project based on an existing one.

Problem solving option

  1. The standard de facto in the industry for config files it has become the use of YAMLlike a little more human friendly format in terms of perception. Ability to define context variables and define parameter values ​​via interpolation would partially eliminate the worry of overriding the values ​​of many parameters.

  2. Decomposition of a large file into logically independent, and meaningful in context, smaller files (general settings, settings for specific projects, etc.) greatly simplifies the perception and understanding of their content. Specification JSON Reference quite organically capable of solving this problem, and also opens up the possibility of direct reuse of typical settings, instead of copying them multiple times.

  3. After the file is decomposed angular.json into logical components, it is logical to store the project settings in the folders of the corresponding projects.

As soon as everything is ready, it remains to perform the inverse task: for each project, calculate all the parameter values ​​based on the contextually defined variables and $ref links, and then combine all the final project configurations with global settings into a single angular.json file.

Implementation example

I would like to note right away that the implementation of the concept is technically not a difficult task and is quite within the power of one professional developer for a couple of days. In this connection, it is possible that the development of your own solution in your case will be a preferable option, because opens up almost limitless possibilities of its adaptation to specific requirements and wishes.

We’ve got a tool ngx-ws, on the example of which we will further consider how the idea works in practice.

Preparation

Let’s create small simple workspace c group of projects

Decomposition

We transform received angular.json into YAML format, decompose it into files angular-workspace.yaml and a series of files angular-project.yaml separately for each project.

We put the content of the original JSON into the property angular for angular-workspace.yaml, and the configuration of each project into a property project for each angular-project.yaml

Interpolation

Files support section varswhich defines the context variables of the file. For angular-project.yaml variable name is predefined by the name of the directory corresponding to the project and it is not necessary to declare it. For libraries, we get something like this:

Note: Quotation marks for parameter values ​​are required.
Note: Quotation marks for parameter values ​​are required.

Since, for obvious reasons, such a definition for all libraries in our case (in the general case for all projects of the same type) will be identical, then the definition can be postpone v angular-workspace.yaml:

but the very definition rewrite in a much more compact form:

Global predefined variable wsPath contains the full path
angular-workspace.yaml file and instruction implements the standard mechanism links to external resources

Similarly, you can reuse values ​​inside a separate file.

Resources

A typical situation is inclusion in different projects external dependencies, which usually requires the same type of settings in many places. For simplicity, we introduced the concept of resources and implemented a simple mechanism for connecting them to specific projects.

We define:

We connect:

It turns out like this:

Assembly

Installing the package

npm i -g ngx-ws

We start the build

rm angular.json; ngx-ws -v

or in our case, execute

npm run rebuild

We see that the generated angular.json identical to the original. The command can be included in the pipeline for CI assemblies or development, and the file angular.json considered as automatically generated.

Conclusion

Only some aspects are considered. There are others, such as full-fledged localization in the file structure of project dependencies, as, for example, it is done in RushJS … In general, this approach has worked well in practice and has been successfully used in a number of projects for several years now. The solution is designed to be compatible with potential format changes. angular.json and the standard ecosystem toolchain, which practically minimizes the risks associated with its implementation, while at the same time solving the problems described above.

Links

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *