Standalone components

Artikel uit Frontmania Magazine 2022

 

In release 14 of Angular, a new feature was introduced that may prove to be a gamechanger in the way we structure Angular applications. With standalone components, we do not longer need to use the ngModule to declare a component in Angular. The component can declare itself and all its dependencies and exports. The introduction of standalone components is still in an experimental phase but it is probably the greatest change in Angular since the introduction of Ivy. What does this change entail and what impact will it have on developing in Angular?

 

The introduction of standalone components doesn’t mean the end of the Angular module (ngModule). The concept is also coined as ‘optional modules’, from which we can take that modules are from now on optional. The two concepts are interchangeable: a standalone component can import from a module and vice versa. This will make it easy to introduce the new concept in an existing codebase.

 

{ What does a standalone component look like? }

For a component to be treated as standalone, the decorator is extended with the new – optional – property ‘standalone’. If set to true, Angular will treat the component as standalone. All properties we know for the ngModule also apply to a standalone component.

 

To demonstrate this feature: In the following code snippet a standalone component is declared. The components’ template has a dependency on another standalone component and on a component declared in an ngModule. The template also contains a condition in the form of an ngIf. In order to be able to use the ngIf directive, we need to import Angulars’ common module as well. Finally, the component exports itself so it can be used by other components or modules.

import { CommonModule } from ‘@angular/common’;
import { Component } from ‘@angular/core’;
import { ClassicComponentModule} from ‘@classic-component.module”;
import { ChildStandaloneComponent } from ‘./child-standalone.component’;

@Component({
selector: ‘sa-component’,
standalone: true,
imports: [
CommonModule,
AnotherStandaloneComponent,
ClassicComponentModule
],
exports: [StandaloneComponent]
template:
`<div *ngIf=”foo”>
<sa-another-standalone></sa-another-standalone>
<classic-component></classic-component>
</div>`
})
export class StandAloneComponent  {
foo = true;
}
{ What about bootstrapping and routing? }

An Angular app bootstraps through a module at root level and its routes are also declared through modules. Does this mean we still need to use at least a few modules in our project? The answer is: no. Angular has created a solution to allow main.ts to load a component instead of a module. And since the introduction of Ivy, it was already possible to lazy-load components inside another component. So with these new introductions, it is fairly easy to set up a small Angular app with, theoretically, just one component, a main.ts and an index.html.

 

{ Flattening the learning curve }

One of the arguments why the Angular team introduced standalone components is to make it easier for new developers to adapt to the framework. Angular has always been somewhat intimidating to developers and the ngModule is without doubt one of the reasons why.

 

Learning Angular while using standalone components, it should be easier to understand the concepts, while developing Angular should become less cumbersome. Dependencies are often ‘implicitly’ imported through the module and can easily be forgotten when importing a component. For many developers, it is not clear when to use modules at all and in one codebase you can find libraries using a module for each component, while in others there is just one big module handling all. This kind of confusion should no longer exist when using standalone components.

 

So the benefits for beginning Angular developers are clearly there, but for more experienced developers the new feature is also easy to grasp as the standalone component looks pretty much like an ngModule. On top of this all, the new concept should not have any negative impact on performance and build-time. In fact, standalone components are expected to shorten the build-time somewhat.

 

{ All good news so far, are there any cons? }

Standalone components certainly have their benefits for anyone picking up the Angular framework. Considering the projects that I’ve worked on, I clearly see benefits when it comes to small units such as directives and pipes. It will make life easier if you can just import one single directive or pipe. Small, representational components will be easier to share when they are standalone.

 

When developing more complex features, it is less obvious what standalone components bring us. It is still up to the developer to decide how big a component can grow. Another concern: introducing standalone components in a large, existing codebase will be a considerable undertaking, while mixing the two concepts is potentially confusing.

 

Finally, we do reduce some boilerplate in our projects when taking out the ngModule, but each and every standalone component will need to import modules like Angulars’ CommonModule. Suggestions have been made to cut up the CommonModule so you only have to import what is needed, or that features like the *ngIf directive are imported by default. Currently there are no concrete plans by the Angular team in this direction.

 

{ Conclusion }

With standalone components, the Angular team will introduce a new way of working that will make the learning curve for beginning Angular developers less steep. This introduction will not be ‘breaking’ in any respect, but will co-exist peacefully with the existing module system. The benefits offered by standalone components will be mostly felt in clearly defined, smaller pieces of code. Migrating an existing codebase to standalone components, if wanted at all, may be a challenge.