Slide 1

Slide 1 text

Christian Liebel @christianliebel Consultant Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft

Slide 2

Slide 2 text

Hello, it’s me. Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Christian Liebel Twitter: @christianliebel Email: christian.liebel @thinktecture.com Angular & PWA Slides: thinktecture.com /christian-liebel

Slide 3

Slide 3 text

Motivation Standalone Components Standalone Applications Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Agenda

Slide 4

Slide 4 text

Angular 16+ – Signals (…and a Zone.js-less future) – Server-Side Rendering/Hydration – Built-in Control Flow ({#if cond.expr}{/if}) – Standalone Applications/Components Goals: Streamline & modernize APIs + improve performance Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft “The New Angular”

Slide 5

Slide 5 text

Modules // declare a module var myAppModule = angular.module('myApp', []); // configure the module. // in this example we will create a greeting filter myAppModule.filter('greet', function() { return function(name) { return 'Hello, ' + name + '!'; }; }); Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft AngularJS

Slide 6

Slide 6 text

Beta in 2015 @Component({ selector: 'app-my', template: `{{ item.name | myPipe }}`, directives: [NgFor, TooltipDirective], pipes: [MyPipe], }) export class MyComponent { @Input({ required: true }) items!: Item[]; } Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Angular 2

Slide 7

Slide 7 text

RC 5 Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Angular 2

Slide 8

Slide 8 text

@NgModule({ declarations: [AppComponent, HomeComponent, MenuComponent], imports: [BrowserModule], providers: [DataService], bootstrap: [AppComponent], }) export class AppModule { } Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft NgModules

Slide 9

Slide 9 text

Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft NgModules UI-related components (BookModule) UI-related components (TodoModule) Logic/ infrastructure components (BookModule) Logic/ infrastructure components (TodoModule) Components Directives Pipes High-Level Services Low-Level Services

Slide 10

Slide 10 text

@Component({ selector: 'app-my', template: `{{ item.name | myPipe }}`, }) export class MyComponent { @Input({ required: true }) items!: Item[]; } Question: Where does appTooltip and myPipe come from? Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft The problem with modules…

Slide 11

Slide 11 text

Dependencies ↑ Module ↑ Component Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft The problem with modules…

Slide 12

Slide 12 text

Component ↓ Modules ↓ Dependencies Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft The goal…

Slide 13

Slide 13 text

Motivation Standalone Components Standalone Applications Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Agenda

Slide 14

Slide 14 text

@Component({ selector: 'app-my', template: `{{ item.name | myPipe }}`, standalone: true, imports: [NgFor, TooltipDirective, MyPipe] }) export class MyComponent { @Input({ required: true }) items!: Item[]; } Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Components

Slide 15

Slide 15 text

Generating a new component ng generate component my-component --standalone --standalone is currently optional, and off by default. This also works for directives and pipes. Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Components

Slide 16

Slide 16 text

Lazy Loading export const ROUTES: Route[] = [ { path: 'admin', loadComponent: () => import('./admin/panel.component') .then(mod => mod.AdminPanelComponent), providers: [MyService] }, // … ]; https://angular.io/guide/standalone-components#lazy-loading-a-standalone-component Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Components

Slide 17

Slide 17 text

Lazy Loading Multiple Routes export const ROUTES: Route[] = [ {path: 'admin', loadChildren: () => import('./admin/routes')}, // … ]; export default [ {path: 'home', component: AdminHomeComponent}, {path: 'users', component: AdminUsersComponent}, // … ] as Route[]; https://angular.io/guide/standalone-components#lazy-loading-many-routes-at-once Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Components

Slide 18

Slide 18 text

“Modules” export const CAROUSEL_DIRECTIVES = [ ImageCarouselComponent, ImageSlideComponent ] as const; @Component({ standalone: true, imports: [CAROUSEL_DIRECTIVES] }) export class MyComponent {} https://angular.io/guide/standalone-components#standalone-components-for-library-authors Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Components

Slide 19

Slide 19 text

Interoperability with NgModules – Standalone components/directives/pipes can’t be part of NgModules – When used in non-standalone components, it needs to be imported @NgModule({ declarations: [MyStandaloneComponent], imports: [MyStandaloneComponent], }) export const MyModule {} Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Components

Slide 20

Slide 20 text

Interoperability with NgModules @Component({ selector: 'app-my', template: `{{ item.name | myPipe }}`, standalone: true, imports: [CommonModule, TooltipModule, PipeModule] }) export class MyComponent { @Input({ required: true }) items!: Item[]; } Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Components

Slide 21

Slide 21 text

Web Components Streamlined standalone API simplifies the creation of web components from Angular components Web components can be used in any context (not only Angular apps) ⚠ Problem: Zone.js is still used for change detection, should become less relevant in the future with signals Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Components

Slide 22

Slide 22 text

Angular Elements import { createCustomElement } from '@angular/elements'; import { createApplication } from '@angular/platform-browser'; import { MyComponent } from './app/my/my.component'; const {injector} = await createApplication({ providers: [/* add providers */] }); const myElement = createCustomElement(MyComponent, { injector }); customElements.define('my-element', myElement); Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Components

Slide 23

Slide 23 text

Motivation Standalone Components Standalone Applications Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Agenda

Slide 24

Slide 24 text

Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft

Slide 25

Slide 25 text

Getting Started ng new my-app --standalone --standalone is currently optional, and off by default. ⚠ Some ng add/ng update integrations may not work with standalone workspaces. Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Applications LIVE DEMO

Slide 26

Slide 26 text

Folder Structure Modules main.ts app/app-routing.module.ts app/app.module.ts Standalone Apps main.ts app/app.routes.ts app/app.config.ts Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Applications

Slide 27

Slide 27 text

Bootstrap API Modules import { platformBrowser } from '@angular/platform-browser'; import { AppModule } from './app/app.module'; platformBrowser() .bootstrapModule(AppModule) .catch(e => console.error(e)); Standalone Apps import { bootstrapApplication } from '@angular/platform-browser'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent) .catch(e => console.error(e)); Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Applications

Slide 28

Slide 28 text

Providers Modules @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(routes), HttpClientModule ] }) export class AppModule { } Standalone Apps export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes), provideHttpClient(), // fallback for modules: importProvidersFrom (TranslateModule) ] }; Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Applications

Slide 29

Slide 29 text

Environment Injectors Modules @NgModule({ providers: [{ provide: PhotosService, useClass: CustomPhotosService, }] }) export class MyModule { constructor() { // My logic } } Standalone Apps createEnvironmentInjector([ { provide: PhotosService, useClass: CustomPhotosService }, { provide: ENVIRONMENT_INITIALIZER, useValue: () => {/* My logic */} } ]); Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Applications

Slide 30

Slide 30 text

Migration ng g @angular/core:standalone Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Applications

Slide 31

Slide 31 text

Migration 1. Run ng g @angular/core:standalone and select "Convert all components, directives and pipes to standalone" 2. Run ng g @angular/core:standalone and select "Remove unnecessary NgModule classes" 3. Run ng g @angular/core:standalone and select "Bootstrap the project using standalone APIs" 4. Run any linting and formatting checks, fix any failures, and commit the result https://angular.io/guide/standalone-migration#migrations-steps Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Applications LIVE DEMO

Slide 32

Slide 32 text

Migration – Migration can be partly automated – Manual changes will be required – Effort for mid-size projects: 4–8 hours – No functional difference – ⚠ Changes to the project setup may lead to the migration to break – ⚠ Replacements in unit tests may be incorrect – ⚠ Migration does not introduce the new folder structure (app config) Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Standalone Applications

Slide 33

Slide 33 text

Standalone components are fun! IDEs already have tooling support Foundation for driving Angular forward à get ready for upcoming features Matches other frameworks (e.g., React, Lit) In my opinion… – New projects should be started using the standalone API – Existing projects should be migrated as soon as possible – Where this is not possible, add new parts using the standalone API Hallo Standalone Components, tschüss NgModules! So bauen Sie Angular-Apps der Zukunft Summary

Slide 34

Slide 34 text

Thank you for your kind attention! Christian Liebel @christianliebel [email protected]