What's new in Angular 7

The calm before the storm?

According to the self-imposed semi-annual release cycle, it was that time again in October 2018: The Angular team released a new major release. We are now at version 7. The transition to this version is refreshingly straightforward - the only breaking change is that you also have to install the new TypeScript 3.1. And even this simple migration was automated with a script.

The new version comes with a few bug fixes and a very manageable number of new features. The reason for this small feature increase is that the core team is currently investing all resources in the next big coup: the new Ivy compiler, which on the one hand ensures smaller bundles and on the other hand makes Angular a lot more flexible. This should appear in the next few months and can be activated via a feature flag.

This article describes the most important new features of Angular 7 and the associated Angular CLI 7.

Upgrade

Thanks to the relatively young CLI command update updating the framework is almost too easy to be true. The following instruction is sufficient:

ng update @ angular / cli @ angular / core

This causes the CLI to load the latest packages and the package.json to update. The application should then start with the new Angular version.

Shadow DOM 1.0 and Content Projection

Fig. 1: Web Component with Shadow DOM 1 and Content Projection

Shadow DOM is one of the standards Angular has been guided by from the start. The idea, which comes from the world of Web Components, is to give a component its own styles without affecting other components. Since not all browsers support Shadow DOM, the framework uses an emulation by default. This is usually quite acceptable, but cannot offer the full scope of a browser-based implementation.

To activate the latter is the property encapsulation in the Component-Decorator on ViewEncapsulation.Native to put. However, this option only uses the so-called version 0 of Shadow DOM. The browser manufacturers have now agreed on version 1 and are now implementing it on a broad basis.

Since Angular version 6.1, this can be used with the property ViewEncapsulation.ShadowDom activate. What is new with version 7, however, is that Angular, in conjunction with Shadow DOM 1, also allows content projection. This means that the component receives HTML fragments when it is called and places them at certain points in its template.

To illustrate this possibility, I am using the component in illustration 1.

While the component receives the three values ​​for the diagram via a property binding, the caller injects the heading and the text at the end via content projection. In the context of Shadow DOM 1 (Listing 1), the component template with the new slot elements can refer to it (Listing 2).

@Component ({selector: 'app-dashboard-tile', templateUrl: './dashboard-tile.component.html', encapsulation: ViewEncapsulation.ShadowDom}) export class DashboardTileComponent implements OnInit {@Input () a: number; @Input () b: number; @Input () c: number; […]}

Default value

< div class = "content">

Standard value

Standard value

These slots are only placeholders for the transferred HTML markup and can contain a standard value. The template can also define multiple slots. This can include a standard slot and any number of other slots. The latter must have a name over that Surname-Attribute received.

The caller then transfers any markup to the component. The attribute slot assigns the individual elements to a slot (Listing 3). Everything that is not explicitly assigned to a slot in this way is placed in the standard slot.

<div class="col-sm-3"> <dashboard-tile a="10" b="5" c="15"> <span slot="title">Important Stuff</span> <span slot="legend">A, B and C show the values of A, B and C.</span> Only believe in statistics you've faked yourself. </dashboard-tile> </div>

Code generation prompts

For some time now, the Angular CLI has been making it easier to generate recurring code with so-called Schematics. This code generator generates, for example, when calling ng new the basic structure of a new application or when calling ng generate among others new components, services or modules.

In order to determine the details of the code generation, these instructions take a large number of parameters. That can be tiring. That is why Schematics now offers the possibility of obtaining information interactively (Fig. 2).

Fig. 2: The CLI can now collect information interactively

Behind this seemingly simple mechanism is a well thought-out program design. The type of information gathering can be determined, for example, by specifying a PromptProviders can be exchanged and all information obtained is described via metadata.

If you want to provide your own code generator with schematics, you only have to provide a JSON schema with the desired parameters. Parameters that are to be queried via the console are given the property x prompt.

Listing 4 illustrates this using a schematic that generates product names with a logic that is not to be taken very seriously.

{"$ schema": "http://json-schema.org/schema", "id": "AwesomeProductNameSchematic", "title": "Schematic for Product Names", "type": "object", "properties" : {"internalName": {"type": "string", "description": "The short and boring internal name", "x-prompt": "What is the short and boring internal name?" }, "coolness": {"type": "number", "description": "Degree of coolness", "default": 2, "x-prompt": {"type": "list", "message": "How cool shall the new name be?", "Items": [[…] {"value": 2, "label": "Very cool"}, […]]}}}}

The property x prompt is used here initially in its short form. This stipulates that it only contains the question to be asked. The long form used afterwards offers a more precise control of the user interaction and can provide a list of possible options.

Pay attention to the line with budgets

One of the main goals of Angular is performance. This architectural goal is taken into account in various ways. A fairly recent measure is defining budgets for the size of bundles. The project team stores this in the file for this purpose angular.json Size limits for the generated bundles. If it exceeds this, there will be warnings or even errors depending on the setting during the build.

The CLI 7 takes up this possibility and by default configures a budget for the bundle, which is initially loaded:

"budgets": [{"type": "initial", "maximumWarning": "2mb", "maximumError": "5mb"}]

A warning is issued from a size of 2 megabytes; from 5 megabytes to an error. As an alternative to initial sets the setting Alles a budget for the overall size of the application and any for the size of each individual file. In addition, the option is deposited bundle a budget for a very specific bundle:

budgets: [{"type": "bundle", "name": "vendor", "minimumWarning": "300kb", "minimumError": "400kb",}]

If you exceed the budget, you can take a look at the imported libraries. The Webpack Bundle Analyzer, available via npm, shows the distribution of the individual libraries in a graphical manner and thus enables the perpetrators to be tracked down. In order to use it, a build with the switch is first required statsJson to create. This takes care of providing statistics on the content of the bundles:

ng build --prod --statsJson

in the distFolder, the Webpack Bundle Analyzer can then be started. It takes the name of the statistics file that the CLI calls stats.json:

webpack-bundle-analyzer stats.json

The result is then as in Figure 3.

Fig. 3: The Webpack Bundle Analyzer provides information about the bundle content

If you discover in this way that an npm package is causing the problem, its authorization does not have to be questioned immediately. Often there are several options for referencing the package and here it is important to find a memory-saving variant. A look at the documentation can provide information here. If, on the other hand, you discover that your own program code is too large, you can use lazy loading.

Outlook on ngIvy

As mentioned at the beginning, most of the resources of the Angular team are currently flowing into the new Ivy compiler. This represents the biggest internal change since the framework was released a little more than two years ago. The idea is to put the substructure of Angular on a new footing, so that bundles should become noticeably smaller. Ivy accomplishes this goal by turning Angular code into code that supports tree shaking on build. This means that the parts of Angular that are not required can be removed even better.

As a result, UI components are converted into code that is very close to the DOM and then almost work without Angular. This is also essential for Web Components or Custom Elements, because here you don't want to deliver the entire framework with every reusable component. The first numbers are already promising. A hello world application based on Angular can thus be reduced to less than 3 KB if compression is used in addition to the new optimizations.

It is particularly important to the Angular team to enable the switch to Ivy without breaking changes. That's why it's better to take a little longer here. It is currently being tested at Google in some of the hundreds of Angular projects. The general public should be able to receive Ivy in the next few months and activate it via a feature flag.

View of Bazel

While the CLI is currently based on the popular webpack build tool, the CLI team is also currently working on a Bazel integration. This is the open source version of the build solution used by Google. Your strength is the incremental compilation, which means that only the really changed program parts have to be recompiled. This gives you constant build times regardless of the project size. This is particularly important for large projects and allows you to see the effects of a program change immediately. In addition, Bazel is not limited to JavaScript projects, but can take care of building any type of code base, including server-side ones.

Even if that sounds tempting, the Angular team will not impose Bazel on us, but merely offer it as an option in addition to the webpack integration that has been used as standard up to now. This is made possible by the builders introduced with CLI 6, which enable a plug-in system for build tasks.

Conclusion

Apart from the need to update TypeScript to version 3.1, Angular 7 could also pass as a minor release. The new features offer a nice rounding off, but are also very manageable at the same time. But that's not a bad thing, because Angular is now mature and the large community provides many additional libraries.

Nevertheless, the product team is working at full speed on the next innovation, which should bring out even more performance and flexibility: Ivy. This is a demanding undertaking that has the potential to shrink some bundles many times over. At the same time, this shows once again that the team at Google is consistently pursuing its architecture goals and that performance is right at the forefront.

However, the current approach also shows that the core team stands behind its promise to make transitions to new major versions easy. That's why Ivy is first tested on Google and only then presented to the general public. If you then activate the feature flag for Ivy in your project, you shouldn't notice any difference at first, except that the application performs better thanks to smaller bundles.