Issue
I have a question about the bootstrap call in main.ts
in the Angular 17 standalone API configuration. In particular: should providers/imports be added to the bootstrap call in addition to being imported into the standalone components, directives and pipes?
Some context:
I migrated a legacy Angular app to the new standalone API configuration. I used the official standalone migration guide. This schematic contains four migration steps, the third of which is:
Run ng g @angular/core:standalone and select "Bootstrap the project using standalone APIs"
This step copies the providers/imports from the root - NgModule
- module into the new bootstrap call in main.ts
. Mine now looks like this:
bootstrapApplication(AppComponent, {
providers: [
importProvidersFrom(AppRoutingModule, BrowserModule, ReactiveFormsModule,
MatToolbarModule, MatButtonModule, MatIconModule, FormsModule, MatFormFieldModule, MatInputModule, MatProgressSpinnerModule),
provideAnimations(),
provideHttpClient(withInterceptorsFromDi())
]
}).catch(err => console.error(err));
You can see that, for example, the Angular Material imports have been added to the providers
array in the bootstrap call. These have also imported individually in the components where they are needed, as is necessary in the standalone API setup.
So:
why are they also imported in the bootstrap call?
should I add any new imports I use in future to the bootstrap call as well? i.e.: if in future I decide to use an Autocomplete, should I add the
MatAutocompleteModule
to the bootstrap call as well as in the component?
Update
As per the comments/answers below, the migration schematic adds more to the bootstrapApplication
method than is necessary/desirable (to ensure a smooth migration).
I recommend refactoring it to the app.config.ts
pattern.
After refactoring my setup is:
main.ts
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));
app.config.ts
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideAnimations(),
provideHttpClient()
]
};
The other imports (see bootstrapApplication
in the original post) were either obsolete or should only be imported at component level.
Some further information: Getting started with standalone components
Solution
To me your target should look like this.
bootstrapApplication(AppComponent, {
providers: [
provideRouter(myRoutes)
importProvidersFrom(ReactiveFormsModule),
provideAnimations(),
provideHttpClient(withInterceptorsFromDi())
]
}).catch(err => console.error(err));
The
BrowserModule
is automaticially imported by thebootstrapApplication
function.Routing should be provided by passing the routes to
provideRouter
Every Material import should be at a component level. Each standalone component should only import the material module it needs
As improvements, you should look into replacing
provideAnimations
withprovideAnimationsAsync
, to lazy load the animation packageFormsModule still requires to be loading, so it could be fine here.
You could replace
withInterceptorsFromDi()
withprovideInterceptors
if you convert your interceptors toInterceptorFn
Answered By - Matthieu Riegler
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.