TIL, 2022-11-29, Angular 15
Angular’s Future Without NgModules – Part 1: Lightweight Solutions Using Standalone Components
Angular’s Future Without NgModules – Part 2: What Does That Mean for Our Architecture?
Routing and Lazy Loading with Angular’s Standalone Components
- Why again? Because we needed a way to group building blocks that are used together - for devs and for the Angular compiler. This is so the Angular compiler knows which things are supposed to compile.
- Community not happy, because it becomes another module system besides ECMAScript.
- Ivy - The compiled application works without modules at runtime.
- With standalone components, it will be possible to bootstrap a single component via
bootstrapApplication
.importProvidersFrom
- allows bridging the gap to existingNgModules
.
bootstrapApplication(AppComponent, {
providers: [
importProvidersFrom(HttpClientModule),
provideRouter(APP_ROUTES,
withPreloading(PreloadAllModules),
withDebugTracing(),
),
[...]
importProvidersFrom(TicketsModule),
provideAnimations(),
importProvidersFrom(LayoutModule),
]
});
- You can lazily load a component directly:
// Option 1: Lazy Loading another Routing Config
{
path: 'flight-booking',
loadChildren: () =>
import('./booking/flight-booking.routes')
.then(m => m.FLIGHT_BOOKING_ROUTES)
},
// Option 2: Directly Lazy Loading a Standalone Component
{
path: 'next-flight',
loadComponent: () =>
import('./next-flight/next-flight.component')
.then(m => m.NextFlightComponent)
},
- Services for specific routes: With
NgModule
, each lazy module introduced a new injector and hence a new injection scope. To cover such cases, you can now add introducing providers for each route.
export const FLIGHT_BOOKING_ROUTES: Routes = [{
path: '',
component: FlightBookingComponent,
providers: [
provideBookingDomain(config)
],
- Technically, adding
providers
introduces a new injector at the level of the route. Such an injector is called Environment Injector and replaces the concept of the formerNgModule
injectors. - NgRx: Can do
provideStore
,provideEffects
now.
import { provideStore } from '@ngrx/store';
import { provideEffects } from '@ngrx/effects';
import { provideStoreDevtools } from '@ngrx/store-devtools';
import { reducer } from './app/+state';
[...]
bootstrapApplication(AppComponent, {
providers: [
importProvidersFrom(HttpClientModule),
provideRouter(APP_ROUTES,
withPreloading(PreloadAllModules),
withDebugTracing(),
),
// Setup NGRX:
provideStore(reducer),
provideEffects([]),
provideStoreDevtools(),
- Can also have
provideState
andprovideEffects
in the respective routing configuration. ENVIRONMENT_INITIALIZER
: a function executed when the environment injector is initialized.
Angular v15 is now available!
- Standalone APIs are out of the developer preview.
- Router and
HttpClient
are tree-shakeable standalone APIs. provideRouter
is tree-shakeable (!).- Directive composition: Adding directives to a host element via
hostDirectives
. - Image directive is now stable - automatic
srcset
generation (ngOptimizedImage
). - Functional router guards.
- Router unwraps default imports.
- Auto-unwrapping the standalone component
{
path: 'lazy',
loadComponent: () => import('./lazy-file').then(m => m.LazyComponent),
}
to
{
path: 'lazy',
loadComponent: () => import('./lazy-file'),
}
- Refactoring Angular material components based on Material Design Components for Web.
- Moving some components to use design tokens and CSS variables under the hood.
esbuild
.