Angular Standalone Components: Welcome to a World Without NgModule
The powers that be have spoken, and based on the community’s feedback, the often maligned NgModule
is on its way out (partially). Angular 14 introduces an alternative way to write applications — Standalone components, directives, and pipes.
The term “standalone” refers to components, directives, or pipes that can be used independently of NgModule
. Although you’ll still need to use the core and external NgModules
, you probably won’t need to create new ones.
Let’s create an application without NgModules
. First, we need to generate it using the angular-cli:
npm init @angular ng14
The next step is to delete app.module.ts
and replace the bootstrapModule()
function in main.ts
with bootstrapApplication()
:
The bootstrapApplication()
can take a list of providers
that should be available to the root component and all its children:
As the name suggests, the function extracts the providers
from the provided module.
Now we need to change the AppComponent
to be a standalone component. Simply set the standalone
property to true:
You should see the AppComponent
’s template in your browser. As our component is standalone, we can use the new imports
property. The imports
property specifies the template dependencies of the component — those directives, components, and pipes it can use.
Standalone components can import other standalone components, directives, pipes, and existing NgModules
. For example, we can create a standalone directive, and use it in our component:
npx ng g directive foo --standalone
That’s neat. Now, let’s add routing to the application. You might be tempted to add it to the AppComponent
:
Unfortunately, that isn’t possible because Angular doesn’t allow you to use ModuleWithProvider
in a standalone component. Next, we might try using the new importProvidersFrom
function in the component’s providers:
Using in-app navigation will work; however, the router will miss the first navigation. Initialization of the router should be performed in the bootstrap
process:
Now it works as expected. The TodosPageComponent
is eagerly loaded. Let’s change it to load lazily and add a TodoPageComponent
:
Instead of using loadChildren
and passing a NgModule
, we use the loadComponent
property and pass a component
. We can also declare providers
for this Route and its children using the new providers
property:
We can also pass an array of routes to loadChildren
:
There will be more to come, so stay tuned 😋
Follow me on Medium or Twitter to read more about Angular and JS!