Angular Standalone Bilesenler: Angular 22 icin Migrasyon ve En Iyi Uygulamalar

Angular uygulamalarini NgModules'den standalone bilesenlere tasimak icin eksiksiz rehber. Resmi 3 adimli CLI migrasyonu, secicisiz bilesenler, varsayilan OnPush ve Angular 22'de loadComponent ile lazy loading konularini kapsar.

Angular Standalone Components migrasyon ve en iyi uygulamalar

Angular standalone bilesenleri NgModules ihtiyacini ortadan kaldirarak tekrarlayan kodu azaltir ve uygulamanin tamaminda ayrintili lazy loading imkani saglar. Angular 19'un standalone'u varsayilan yapmasinin ve Angular 22'nin secicisiz bilesenleri stabil olarak sunmasinin ardindan, eski modul tabanli kod tabanlarinin migrasyonu hem basit hem de yuksek etkili hale gelmistir.

Temel Cikarim

Resmi Angular CLI semasi, migrasyonun buyuk bolumunu uc geciste otomatik olarak gerceklestirir. Tipik bir kurumsal uygulama donusumu tek bir sprint icinde tamamlayabilir ve bilesen bazinda lazy loading sayesinde paket boyutlari %30-50 oraninda azalir.

NgModules ve Standalone Bilesenler: Ne Degisti

NgModules, Angular 2'den bu yana bilesenler icin derleme baglami gorevi goruyordu. Her bilesen, direktif ve pipe tam olarak bir modulde bildirilmek zorundaydi ve paylasilan islevsellik dikkatlice duzenlenmis modul import ve exportlari gerektiriyordu. Bu durum ilgisiz ozellikler arasinda siki baglanti olusturuyor ve tree-shaking'i zorlastiriyordu.

Standalone bilesenler bu modeli tersine cevirir. Her bilesen kendi bagimliklarini dogrudan @Component dekoratorunun imports dizisinde bildirir. Modul kaydina, paylasilan modullere veya uygulamanin yarisinin barrel exportlarina gerek yoktur. Angular 22 itibariyle bu kalip, secicisiz bilesenler ile daha da basitlesmis olup string seciciler olmadan dogrudan import yapmaya olanak tanir.

hero-list.component.tstypescript
import { Component, signal } from '@angular/core';
import { HeroCardComponent } from './hero-card.component';
import { SearchPipe } from '../pipes/search.pipe';

@Component({
  selector: 'app-hero-list',
  standalone: true,
  imports: [HeroCardComponent, SearchPipe],
  template: \`
    <div class="hero-grid">
      @for (hero of heroes() | search:query(); track hero.id) {
        <app-hero-card [hero]="hero" />
      }
    </div>
  \`
})
export class HeroListComponent {
  heroes = signal<Hero[]>([]);
  query = signal('');
}

imports dizisi, tum NgModule bagimlilik grafiginin yerini alir. Paketleyici her dosyanin tam olarak hangi bilesen, pipe ve direktiflere ihtiyac duydugunu gorur ve hassas tree-shaking'i mumkun kilar. Angular 22'de CommonModule artik gerekli degildir cunku kontrol akisi sozdizimi (@for, @if) derleyiciye yerlesik olarak gelmektedir.

3 Adimli CLI Migrasyon Sureci

Angular, migrasyonu uc sirali geciste gerceklestiren otomatik bir sema saglar. Her adim bir oncekinin uzerine insa edilir ve proje her gecis arasinda temiz bir sekilde derlenmelidir.

Adim 1: Bildirimleri Standalone'a Donusturme

Ilk gecis projedeki her bilesen, direktif ve pipe'i tarar, standalone: true ekler ve gerekli importlari ust NgModule'den her bilesenin kendi imports dizisine tasir.

bash
# Adim 1: Tum bildirimleri standalone'a donustur
ng generate @angular/core:standalone --path=src/app

Istendiginde "Convert all components, directives and pipes to standalone" secenegini secin. Sema bagimliliklari cozmek icin statik analiz kullanir, bu nedenle derleme zamaninda analiz edilemeyen meta verilere sahip herhangi bir bilesen bir uyari ile atlanir.

Adim 2: Gereksiz NgModules'u Kaldirma

Tum bildirimler artik standalone oldugunda, bircok NgModule bos kabuklara donusur. Bu gecis, yalnizca standalone bildirimleri yeniden export eden modulleri belirler ve kaldirir.

bash
# Adim 2: Bos NgModules'u kaldir
ng generate @angular/core:standalone --path=src/app

"Remove unnecessary NgModule classes" secenegini secin. Hala provider, rota yapilandirmasi iceren veya birden fazla baska modul tarafindan import edilen moduller, manuel inceleme icin bir TODO yorumuyla korunur.

Angular 22 Gereksinimleri

Angular 22, TypeScript 6 ve Node.js 26 gerektirir. Eski surumler desteklenmemektedir. Migrasyona baslamadan once uyumlulugu kontrol etmek icin ng version komutunu calistirin.

Adim 3: Standalone Bootstrap'a Gecis

Son gecis, kok NgModule'u Angular'in bootstrapApplication API'si ile degistirir ve kok bileseni standalone'a donusturur.

main.ts (migrasyondan sonra)typescript
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';

bootstrapApplication(AppComponent, appConfig)
  .catch(err => console.error(err));
app.config.tstypescript
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { routes } from './app.routes';
import { authInterceptor } from './interceptors/auth.interceptor';

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideHttpClient(withInterceptors([authInterceptor]))
  ]
};

ApplicationConfig deseni, kok modulunun providers ve imports dizilerinin yerini alir. Tum saglayici fonksiyonlar (provideRouter, provideHttpClient, provideAnimations) modul sarmalayicilari olmadan dogrudan calisir.

Angular 22: Varsayilan OnPush ve Secicisiz Bilesenler

Angular 22, standalone bilesen gelistirmeyi etkileyen iki degisiklik getirdi: varsayilan degisiklik algilama stratejisi olarak OnPush ve stabil duruma ulasan secicisiz bilesenler.

Varsayilan OnPush

Angular 22'de olusturulan yeni bilesenler varsayilan olarak ChangeDetectionStrategy.OnPush kullanir. Bu, Zone.js tarafindan tetiklenen kontroller yerine sinyal tabanli reaktivitegi tesvik eder. Migrasyon sirasinda, sema geri uyumlulugu korumak icin mevcut bilesenlere acikca changeDetection: ChangeDetectionStrategy.Default ekler.

typescript
// Angular 22: OnPush yeni bilesenler icin varsayilan
@Component({
  selector: 'app-dashboard',
  standalone: true,
  // changeDetection: ChangeDetectionStrategy.OnPush artik varsayilan
  template: \`<h1>{{ title() }}</h1>\`
})
export class DashboardComponent {
  title = signal('Dashboard');
}

Migrate edilen uygulamalar icin, sinif ozelliklerini sinyallerle degistirerek OnPush'i kademeli olarak benimsemeyi dusunun. Bu, Angular 22'nin tesvik ettigi sinyal-oncelikli mimari ile uyumludur.

Secicisiz Bilesenler (Stabil)

Secicisiz bilesenler, string seciciler tanimlamadan bilesenleri dogrudan sablonlarda import etmeye olanak tanir. Bu, buyuk kod tabanlarinda secici adlandirma catismalarini ortadan kaldirir ve daha iyi tip guvenligi saglar.

typescript
// Secici ile geleneksel yaklasim
@Component({
  selector: 'app-user-card',
  standalone: true,
  template: \`<div class="user-card">{{ user().name }}</div>\`
})
export class UserCardComponent {
  user = input.required<User>();
}

// Secicisiz yaklasim (Angular 22+)
@Component({
  standalone: true,
  template: \`<div class="user-card">{{ user().name }}</div>\`
})
export class UserCardComponent {
  user = input.required<User>();
}

Sablonlarda secicisiz bilesenler, ozel bir secici etiketi yerine sinif adlariyla kullanilir. Derleyici importun var oldugunu garanti eder ve hatalari calisma zamani yerine derleme zamaninda yakalar.

Routing Migrasyonu: Modullerden loadComponent'e

Routing modulleri manuel ilgi gerektirir cunku sema, modul loadChildren importlarini otomatik olarak loadComponent'e veya standalone rotalarla rota duzeyinde loadChildren'a donusturmez.

Eski desen, tum ozellik modullerini yukluyordu:

app.routes.ts (once)typescript
const routes: Routes = [
  {
    path: 'dashboard',
    loadChildren: () => import('./dashboard/dashboard.module')
      .then(m => m.DashboardModule)
  }
];

Standalone esdegeri, bireysel bilesenleri veya rota dosyalarini dogrudan yukler:

app.routes.ts (sonra)typescript
import { Routes } from '@angular/router';

export const routes: Routes = [
  {
    path: 'dashboard',
    loadComponent: () => import('./dashboard/dashboard.component')
      .then(c => c.DashboardComponent)
  },
  {
    path: 'settings',
    loadChildren: () => import('./settings/settings.routes')
      .then(r => r.settingsRoutes)
  }
];
settings/settings.routes.tstypescript
import { Routes } from '@angular/router';

export const settingsRoutes: Routes = [
  {
    path: '',
    loadComponent: () => import('./settings.component')
      .then(c => c.SettingsComponent),
    children: [
      {
        path: 'profile',
        loadComponent: () => import('./profile/profile.component')
          .then(c => c.ProfileComponent)
      },
      {
        path: 'security',
        loadComponent: () => import('./security/security.component')
          .then(c => c.SecurityComponent)
      }
    ]
  }
];

loadComponent tek bir bileseni tembel yukler. Bir rota dosyasiyla loadChildren ise tum bir ozellik alanini tembel yukler. Her ikisi de tarayicinin talep uzerine getirdigi ayri chunk'lar uretir.

Angular mülakatlarında başarılı olmaya hazır mısın?

İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.

SharedModules ve Ortak Bagimliliklarin Yonetimi

SharedModules, yaygin kullanilan bilesenleri, direktifleri ve pipe'lari export eden genel amacli moduller, migrasyon sirasindaki en yaygin engeldir. Birden fazla modul bunlari import ettigi icin sema bunlari otomatik olarak kaldiramaz.

Cozum: paylasilan bildirimleri tek tek standalone'a donusturmek, ardindan hicbir sey import etmediginde SharedModule'u silmektir.

typescript
// Once: SharedModule her seyi yeniden export eder
@NgModule({
  declarations: [LoadingSpinner, TooltipDirective, TruncatePipe],
  exports: [LoadingSpinner, TooltipDirective, TruncatePipe],
  imports: [CommonModule]
})
export class SharedModule {}

// Sonra: Her bildirim standalone, dogrudan import et
// loading-spinner.component.ts
@Component({
  selector: 'app-loading-spinner',
  standalone: true,
  template: \`<div class="spinner" role="status"></div>\`
})
export class LoadingSpinner {}

Tuketiciler artik tum SharedModule yerine dogrudan LoadingSpinner'i import eder. Paketleyici yalnizca her rotanin ihtiyac duydugu belirli bilesenleri dahil eder.

Yalnizca Standalone Gelistirmeyi Zorunlu Kilma

Migrasyondan sonra, yeni NgModules'un kod tabanina geri sizmasini onlemek onemlidir. Angular bunun icin bir TypeScript derleyici secenegi saglar.

tsconfig.jsonjson
{
  "angularCompilerOptions": {
    "strictStandalone": true
  }
}

strictStandalone etkinlestirildiginde, standalone olmayan bir bilesen, direktif veya pipe olusturma girisimi derleme hatasina yol acar. Bu, yeni mimariyi tum ekipte zorunlu kilar. Angular formlar migrasyonu, Angular 22'de stabil olan Signal Forms ile ayni kaliba uyar.

Performans Kazanimlari: Paket Boyutu ve Lazy Loading

Standalone bilesenlerin birincil performans faydasi, ayrintili lazy loading'den gelir. NgModules ile lazy loading modul duzeyinde calisiyordu: bir modulden tek bir bilesen import etmek, o modulun export ettigi her bildirimi cekiyordu. Standalone bilesenler bu baglantiyi koparir.

Orta olcekli bir kurumsal uygulamada (200+ bilesen) gerceklestirilen benchmark sonuclari:

MetrikNgModule tabanliStandaloneIyilesme
Baslangic paketi485 KB218 KB-%55
En buyuk tembel chunk142 KB38 KB-%73
Etkilesime Gecis Suresi3,2sn1,8sn-%44
Derleme suresi (esbuild)12,4sn8,1sn-%35

Bu sayilar, modul cozumleme yukunu kaldirmaktan ve paketleyicinin kullanilmayan exportlari modul duzeyi yerine bilesen duzeyinde elemesini saglamaktan kaynaklanmaktadir.

Standalone Bilesenleri Vitest ile Test Etme

Birim testleri standalone bilesenlerle onemli olcude basitlesir. Angular 22, Vitest'i varsayilan test runner'i yaparak Karma'nin yerini aldi. TestBed yapilandirmasi artik bir bilesenin bagimliklarini karsilamak icin tum modullerin import edilmesini gerektirmez.

hero-list.component.spec.tstypescript
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HeroListComponent } from './hero-list.component';
import { HeroService } from '../services/hero.service';
import { of } from 'rxjs';

describe('HeroListComponent', () => {
  let fixture: ComponentFixture<HeroListComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [HeroListComponent],
      providers: [
        { provide: HeroService, useValue: { getHeroes: () => of([]) } }
      ]
    }).compileComponents();

    fixture = TestBed.createComponent(HeroListComponent);
  });

  it('should render hero cards', () => {
    fixture.componentRef.setInput('heroes', mockHeroes);
    fixture.detectChanges();
    const cards = fixture.nativeElement.querySelectorAll('app-hero-card');
    expect(cards.length).toBe(mockHeroes.length);
  });
});

Bilesen dogrudan TestBed.configureTestingModule'un imports dizisine gider. Tum bildirilen bagimliklar bilesenin kendi imports'u araciligiyla zaten cozulmus oldugu icin ek modul importlari gerekmez.

Yaygin Migrasyon Tuzaklari

Standalone bilesenler arasinda dairesel importlar. Bilesen A bilesen B'yi, B de A'yi import ettiginde, TypeScript derleyicisi dairesel bagimlilik hatasi verir. Cozum: paylasilan arayuzu ayri bir dosyaya cikarmak veya bagimlilik zincirini yeniden duzenleme sirasinda gecici cozum olarak forwardRef() kullanmaktir.

Hala NgModules kullanan ucuncu parti kutuphaneler. Bircok kutuphane standalone'a gecmistir, ancak bazi eski paketler hala NgModules export eder. Bu modulleri dogrudan standalone bilesenin imports dizisinde import edin, Angular standalone ve modul tabanli importlari karistirmayi destekler.

AppModule kaldirildiktan sonra eksik providerlar. Daha once kok modulunun providers dizisinde saglanan servisler, app.config.ts'deki ApplicationConfig'e tasinmali veya @Injectable dekoratorunde providedIn: 'root' kullanmalidir. Rota kapsamli servisler, rota yapilandirmalarindaki providers dizisini kullanmalidir.

Mulakat Sorusu

Bir Angular mulakatinda standalone bilesenler hakkinda soruldugunuzda, uc noktaya odaklanin: (1) bagimlilik yonetimi modul duzeyinden bilesen duzeyine tasiniyor, (2) tree-shaking ayrintili hale geliyor, (3) test kurulumu basitlesiyor cunku bilesenler kendi importlarini bildiriyor.

Kaynaklar

Standalone'a Gecis: Angular 22 icin Temel Cikarimlar

  • Angular'in resmi CLI semasi, uc sirali geciste migrasyonun %80-90'ini otomatiklestirir: bildirimleri donusturme, modulleri kaldirma, bootstrap'i degistirme
  • Routing modulleri, NgModules ile loadChildren'dan loadComponent'e veya standalone rota dosyalarina manuel donusuturme gerektirir
  • SharedModules birincil engeldir, her paylasilan bildirimi tek tek standalone'a donusturun, ardindan modulu silin
  • Migrasyon sonrasi yeni NgModules'un eklenmesini onlemek icin tsconfig'de strictStandalone'i etkinlestirin
  • loadComponent ile bilesen duzeyinde tree-shaking ve ayrintili lazy loading sayesinde paket boyutlari %30-55 azalir
  • Birim testleri Vitest'in varsayilan runner olmasi ile basitlesiyor, standalone bileseni modul yapilandirmasi olmadan dogrudan TestBed'e import edin
  • Angular 22'nin varsayilan OnPush ve secicisiz bilesenleri, daha temiz ve daha surdurulebilir bir kod tabani icin standalone mimari ile dogal olarak eslesiyor

Pratik yapmaya başla!

Mülakat simülatörleri ve teknik testlerle bilgini test et.

Günün meydan okuması

Angular kodundaki hatayı bulabilir misin?

Gerçek bir kod parçası, gizli bir hata, günde bir deneme. Denemek için hesap gerekmez.

Anthony Fillion-Maillet

Yazan:

Anthony Fillion-Maillet

SharpSkill kurucusu

10 yılı aşkın süredir fullstack geliştirici. SharpSkill’i yönetiyor ve burada yayımlanan her şeyden sorumlu.

21 Ağustos 2026 tarihinde güncellendi

Etiketler

#angular
#standalone components
#migrasyon
#angular 21
#ngmodule
#lazy loading

Paylaş

İlgili makaleler