Angular - Standalone Components

Bilal UÇAR
Sahibinden Technology
6 min readFeb 1, 2023

Angular 14 ile birlikte duymaya başladığımız Standalone Components kavramı, 16 Kasım 2022 ‘de tanıtılan Angular 15 sürümüyle birlikte kararlı hale geldi.

Standalone Component Nedir?

Standalone component, bir web uygulamasında tekrar eden bir parçayı temsil eden bir component sınıfından oluşur. Bu componentler, bir Angular uygulamasının diğer componentleriyle etkileşime girerek bir web uygulamasının farklı özelliklerini oluşturur.

Standalone componentler NgModules ihtiyacını azaltarak kod yazma deneyimini kolaylaştırmayı amaçlıyor. Modül kullanmadan hatta AppModule bile oluşturmadan uygulama geliştirebilmemizi mümkün hale getiriyor.

Angular 14'ten önce bir component oluşturduğumuzda bu component bir modüle dahil edilmesi gerekirdi. Dahil etmediğimizde Angular bunu derlemez ve hata verirdi. Angular 14 ile birlikte bir modüle dahil olmayan componentler oluştururulabilir hale geliyoruz.

Angular ile çalıştıysanız modül kavramının proje inşasında ne kadar kritik öneme sahip olduğunu kavramışsınızdır. Angular öğrenmeye yeni başlayan birinin anlamakta güçlük çektiği konu bu modüler yapı olduğunu düşünüyorum.

Standalone componentlerin avantajlarına gelecek olursak,

  • Angular öğrenmeyi kolaylaştırması
  • Daha az dosya ve kod yazılması
  • Bir componentin hangi bağımlılıklara sahip olduğunu anlamanın daha kolay olması

standalone flag

Component, directive ve pipe sınıflarına artık standalone flag ekleyerek bir modüle dahil olmayacağını belirtebiliyoruz. Bu sınıfları standalone olarak belirttiğimizde bir NgModule ‘ün içindeki declarations dizisine dahil etmiyoruz. Etmeye çalıştığınızda hata alındığını gözlemleyebilirsiniz.

Örnek Hata: Component HomeComponent is standalone, and cannot be declared in an NgModule. Did you mean to import it instead?

Standalone componentler bağımlılıklarını NgModules yerine doğrudan component dekoratörü içerisinde verebiliyoruz ve imports dizisi sayesinde bir veya birden fazla standalone component ekleyebiliyoruz.

Standalone Component nasıl oluşturulur?

Angular 14 ve üstü olan bir projemizde ng g c home --standalone komutuyla standalone component oluşturabiliriz. Home yerine oluşturmak istediğiniz component ismini verebilirsiniz.c yerine p ve d kısaltmalarını kullanarak sırasıyla pipe ve directive de oluşturabilirsiniz. g ise generatekelimesinin kısa halidir.

Angular CLI kullanarak oluşturabileceğiniz yapıların komutlarına https://angular.io/cli/generate bağlantısından erişebilirsiniz.

İlk komutu çalıştırdığınızda aşağıdaki gibi bir component sınıfı oluşacaktır.

import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
selector: 'app-home',
standalone: true,
imports: [CommonModule],
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {

constructor() { }

ngOnInit(): void {
}

}

Bu örnekte HomeComponent sınıfı için standalone flag true verilerek standalone componenti olduğu belirtilmiştir.

imports ile belirtilen CommonModule Angular ‘ın NgIf, NgFor gibi temel directive ve pipe gibi özelliklerini kullanmamızı sağlayan modülüdür.

Standalone Component’e hangi bağımlıklıları eklenebilir?

Standalone componentin iki farklı türde bağımlılığı olabilir.

  • Standalone component, pipe veya directive
  • Modül

Yani standalone componente bir bağımlılık eklemek isterseniz ya bir modül veya standalone çalışabilen farklı bir component, pipe veya directive ekleyebilirsiniz.

Oluşturulan Standalone Component Nasıl Kullanılır?

Standalone Componentleri iki farklı şekilde kullanabilirsiniz.

1- Bir modüle import ederek

Burada dikkat etmemiz gereken nokta standalone componentler declarations dizisine değil imports dizisine eklenmelidir. Oluşturduğumuz HomeComponent standalone component olduğu için imports dizisine ekleyebiliriz.

// app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HomeComponent
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Aşağıdaki app.component.html içeriğindeki gibi selector ile kullanabiliriz.

<!--app.component.html-->

<h1>App Component</h1>
<app-home></app-home>

Bu şekilde NgModules ‘leri kullanarak tasarladığımız projelere sonradan standalone componentleri dahil edebiliriz.

2- Farklı bir standalone componente import ederek

ng g c products --standalone komutuyla yeni bir standalone component oluşturuyoruz. Bu componenti halihazırda olan HomeComponent ‘inin imports dizisine ekleyebiliriz.

// home.component.ts

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ProductsComponent } from '../products/products.component';

@Component({
selector: 'app-home',
standalone: true,
imports: [CommonModule, ProductsComponent],
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent {

}
<!--home.component.html-->
<h1>Home Standalone Component</h1>
<app-products></app-products>

Bu şekilde bir standalone componentin içerisine farklı bir standalone componentin nasıl eklenebileceğini gözlemlemiş olduk.

Angular Projesini Modül Kullanmadan Tasarlamak

Standalone Component yeni bir proje oluşturduğumuzda gelen AppModule ‘den de kurtulmamıza olanak tanır. Yeni bir proje oluşturup AppModule ‘den kurtulmayı deneyelim.

ng new routing-examplekomutu ile routing-example adında yeni bir proje oluşturuyoruz.

Angular Router eklensin mi sorusuna hayır, stil sayfası sorusuna ise scss seçip, bağımlılıkların yüklenmesini bekliyoruz.

Oluşan projenin içerisine gidip app-component.ts dosyasını standalone true olarak işaretliyoruz.

Template dosyası yani app.component.html dosyasına da <h1>Standalone Test</h1> ekliyoruz.

import { Component } from '@angular/core';

@Component({
selector: 'app-root',
standalone: true,
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'routing-example';
}

Projeyi oluşturduğumuzda main.ts dosyası aşağıdaki gibi görünür.

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';


platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

Bu dosyayı aşağıdaki gibi değiştirerek uygulamanın güncellediğimiz standalone olan AppComponent ten başlamasını söyleyebiliriz. platformBrowserDynamic yerine bootstrapApplication kullanıyoruz.

import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent);

Bu aşamada dikkatinizi çekmek istediğim bir nokta var. Eğer oluşturduğumuz standalone componentin selector değeri app-root değilse index.html deki app-root etiketini oluşturduğumuz standalone componentin selector değeri ile değiştirmeliyiz. Bizim örneğimizde app-root olduğu için index.html dosyasında bir güncelleme yapmıyoruz.

Artık modül dosyamızdan yani app.module.ts i silerek kurtulabiliriz.

Standalone Component ile Routing

Birçok Angular uygulaması routing kullanır. Yani birden fazla sayfaya sahiptir. Örneğin sahibinden.com u ele aldığımızda anasayfa, arama sonuç sayfası, ilan detay sayfası gibi birçok farklı sayfaya sahiptir. Standalone componentlerde routing yapısını kullanabilmeniz için yapmanız gerekenlere bakalım.

1- App componentimiz standalone bir componentti ve tüm modülleri kaldırıp uygulamanın App componentimizden başlayacak şekilde bir güncelleme yapmıştık. Bu componentimizde ilk olarak Angular ‘ın router modülünü yani RouterModule import etmemiz gerekir.

// app.component.ts

import { Component } from '@angular/core';
import { RouterModule } from '@angular/router';

@Component({
selector: 'app-root',
standalone: true,
imports: [RouterModule],
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'routing-example';
}

2- Template tarafına ise router alanını kapsayan router-outlet etiketini ekliyoruz.

<!--app.component.html-->
<h1>Standalone test</h1>
<router-outlet></router-outlet>

3- Artık route eklemeye başlayabiliriz. ng g c home --standalone komutu ile home adında yeni bir standalone component oluşturuyoruz. Ardından app.routing.ts adında bir dosya ekleyerek bu işleme başlayabiliriz.

// app-routing.ts

import { Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';

export const APP_ROUTES: Routes = [
{
path: '',
pathMatch: 'full',
redirectTo: 'home'
},
{
path: 'home',
component: HomeComponent
}
];

Örnek bir routing dosyası. Şimdi bu dosyayı main.ts dosyasında import edelim.

// main.ts

import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { importProvidersFrom } from '@angular/core';
import { RouterModule } from '@angular/router';
import { APP_ROUTES } from './app/app.routing';

bootstrapApplication(AppComponent, {
providers: [
importProvidersFrom(RouterModule.forRoot(APP_ROUTES))]
});

Bu şekilde routing yapısını standalone componentlerle birlikte kullanımını da deneyimlemiş olduk.

Standalone Component ile Lazy Loading

Daha önceden modüllerde olduğu gibi standalone componentlerde de lazyLoading kullanılabilir. Standalone componentleri loadComponent ile lazy load yüklenecek şekilde ayarlayabiliriz.

Yeni bir products adında standalone component oluşturuyoruz ve app.routing.ts dosyasına products pathini lazyLoad yüklenecek şekilde tanımlıyoruz.

import { Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';

export const APP_ROUTES: Routes = [
{
path: '',
pathMatch: 'full',
redirectTo: 'home'
},
{
path: 'home',
component: HomeComponent
},
{
path: 'products',
loadComponent: () => import('./products/products.component').then(m => m.ProductsComponent)
}
];

Uygulamayı çalıştırdığımızda sayfalar arasında dolaşırken ProductsComponent ‘in sonradan yüklendiğini kullandığınız tarayıcının Developer Tools ‘undaki Network sekmesinden gözlemleyebilirsiniz.

Kodun son halini incelemek isteyenler için github repo bağlantısı: https://github.com/bilalucar/angular-standalone-components

SONUÇ

Standalone componentler, özellikle Angular öğrenmeye yeni başlayan geliştiricilerin öğrenme eğrisini yumuşatan yeni bir çalışma yöntemi. Bu yöntem hem mevcut modül sistemiyle problemsiz bir şekilde çalışıyor hem de daha az kod yazmamızı sağlıyor.

Kaynaklar:

https://angular.io/guide/standalone-components

--

--