Ana içeriğe geç

Barrel File: index.ts Dosyası Gerekli mi?

Teknik2 dk

Barrel file kullanmayı tercih eden biriydim; ViraStack AI kurallarında da bunu önermiştim. Kaynakları okuyunca fikrim değişti ve kuralı güncelliyorum.

Barrel File Nedir?

Barrel file, bir klasörün index.ts dosyasında içindeki modülleri tek noktadan dışarı açmak. Feature-Driven Proje Yapısı yazımda feature'ları böyle anlatmıştım:

// src/features/auth/index.ts
export { LoginForm } from "./components/login-form"
export { useAuth } from "./hooks/use-auth"
import { LoginForm, useAuth } from "@/features/auth"

Import yolu kısalıyor, feature'ın dışarıya açtığı kısım tek dosyada görünüyor. Bu yüzden seviyordum.

Bulletproof React rehberi de feature'ların index.ts ile dışarı açılmasını öneriyordu (Mayıs 2024 sürümü). Güncel sürüm bunu bırakmış: barrel file'ların Vite'ta tree shaking'i zorlaştırabildiğini ve performans sorunlarına yol açabildiğini yazıyor, dosyaları doğrudan import etmeyi öneriyor.

Bedeli Ne?

@/features/auth'tan yalnızca LoginForm'u import ettiğinde, JavaScript barrel'ın re-export ettiği her modülü yükleyip çalıştırıyor. Kullanmadıkların da dahil. Marvin Hagemeister bunu içinde yalnızca import satırı olan boş dosyalarla ölçmüş. M1 Air'de 1.000 modül 0,31 saniye, 10.000 modül 3,12 saniye, 50.000 modül 48,44 saniye sürüyor. Vercel'e göre tree shaking de çözmüyor: bu bir bundler özelliği ve external bir paketin içine bakamıyor.

Bir de döngüsel import riski var. TkDodo'nun örneğinde tab-panel.ts içinde useTabState'i ./use-tab-state yerine barrel'dan (@/tab) import etmek döngü oluşturuyor: tab-panel.ts barrel'ı, barrel de tab-panel.ts'i import ediyor. Bundler'lar bu yüzden anlaşılmaz hata mesajlarıyla çökebiliyor.

Gerçek projelerde fark şöyle:

KaynakNe yapıldıSonuç
TkDodoNext.js projesinde iç barrel'lar silindiBazı sayfalarda yüklenen modül sayısı 11 binden fazlaydı, yaklaşık 3,5 bine indi (%68)
AtlassianJira frontend'inde barrel import'ları doğrudan import'a çevrildiYerel unit testler ortalama %50, TypeScript highlighting %30'dan fazla hızlandı; commit başına build dakikası %75 azaldı
VercelNext.js'te optimizePackageImports ile paketlerin barrel'ları build sırasında doğrudan import'a çevrildiDev başlangıcı %15-70 hızlandı; bir App Router sayfasında production build yaklaşık %28 hızlandı

Bu sayıların çoğu binlerce modüllü kod tabanlarından geliyor. Marvin'e göre birkaç barrel genelde sorun değil, her klasörde bir tane olması sorun.

Vazgeçince Ne Değişiyor?

Doğrudan import'a geçiyorsun: @/features/auth/components/login-form. Atlassian ekibi bedelini açıkça yazmış: paketler public API'yi artık barrel'la kontrol edemiyor, bir dosyayı taşıdığında ona doğrudan import eden her yeri güncellemen gerekiyor.

Kütüphane yazıyorsan durum farklı. TkDodo, package.json'daki main alanının gösterdiği tek giriş noktasını tek istisna sayıyor; @tanstack/react-query bunun örneği. Uygulama kodunda ise index.ts dosyalarının işi zorlaştırdığını söylüyor. Biome'un noBarrelFile kuralı da yalnızca type export'larını (export type { Foo } from "foo") ve .d.ts dosyalarını muaf tutuyor.

Yeni bir projede ilk index.ts'i açmadan önce Biome'un noBarrelFile kuralını açmak, barrel'ları baştan işaretletmek için yeterli.

Kaynaklar