Dart Sass 2.0'a Hazırlık: Deprecation'lar, --fatal-deprecation, Slash Division ve @import'un Sonu
Dart Sass 2.0'da 1.105.0'a kadar gelen deprecation'ların çoğu hataya dönüşüyor (slash-div, darken() gibi renk fonksiyonları, legacy JS API); @import, global built-in'ler ve eski if() 3.0'a kadar uyarı olarak kalıyor. --fatal-deprecation=dart-sass-2 ile bugünden hata alıyor, sass-migrator ile temizliyor ve Angular'ın sabit quietDeps ayarı yüzünden includePaths ile yüklenen dosyalardaki deprecation'ların build'de hiç görünmediğini gösteriyoruz.
Sürüm notu: Bu yazıdaki örnekler Dart Sass 1.108.2, Sass Migrator 2.7.0 ve Angular 22.2 (TypeScript 6.0; Angular CLI'ın içindeki Sass 1.104.1) ile denenmiştir. Dart Sass 2.0 bu yazının yazıldığı 14 Kasım 2026'da henüz yayınlanmadı; 2.0 ile ilgili bilgiler Sass ekibinin Eylül 2026 tarihli yol haritasına ve 1.108.2'nin kendi deprecation listesine dayanıyor.
Önce Tahmin Et
Sitedeki serilerin ortak örnek uygulaması Bookstore'un (bir online kitapçı) Angular istemcisinde Dart Sass 2.0'a hazırlık için ilk adım atıldı: angular.json'da slash-div deprecation'ı hataya çevrildi. Ortak abstracts klasöründe biri eski usulle bir fonksiyon yazmış, katalog component'i de onu kullanıyor:
// src/styles/abstracts/_breakpoints.scss
@function half($value) {
@return $value / 2;
}
// src/app/app.scss
@use "abstracts" as *;
.book-list {
row-gap: half(24px);
}
// angular.json
"stylePreprocessorOptions": {
"includePaths": ["src/styles"],
"sass": {
"fatalDeprecations": ["slash-div"]
}
}
ng build kırılır mı? En azından bir uyarı verir mi? Cevabı yazının Angular bölümünde; şimdilik tahminini not et.
Bu yazıda Dart Sass 1.x'in yedi yılda biriktirdiği deprecation'ları, 2.0'da hangilerinin hataya dönüşeceğini ve bugünden nasıl hazırlanılacağını konuşuyoruz. Önceki yazılarda tek tek gördüğümüz uyarıları (slash-div, import, global-builtin, color-functions) burada bir arada ele alacağız.
Dart Sass 1.x'te Neler Değişti?
Dart Sass 1.0 Mart 2018'de çıktı ve o günden beri ana sürüm numarası değişmedi. Ama 1.x içinde dil ciddi şekilde değişti. CHANGELOG'dan önemli kilometre taşları:
- 1.23.0 (2019): module sistemi, yani
@use,@forwardvesass:mathgibi built-in module'ler. Serinin dördüncü yazısının konusu. - 1.77.7: declaration'ların iç içe kurallardan sonra yazılması (mixed declarations) deprecated oldu; 1.92.0'da davranış değişti ve Sass artık bunları kaynaktaki sırayla, native CSS nesting'in yaptığı gibi yazıyor.
- 1.79.0: CSS Color Level 4 desteği (
oklch(),lab(), yeni color space'ler), RGB (kırmızı, yeşil, mavi kanallı renk modeli) kanallarının yuvarlanmaması,darken()gibi eski renk fonksiyonlarının deprecated olması ve legacy JS API'nin uyarı vermeye başlaması. - 1.80.0:
@importve global built-in function'lar (map-get(),percentage()) resmen deprecated. - 1.95.0: CSS'teki yeni
if()syntax'ı destekleniyor, Sass'ın eskiif($condition, $a, $b)fonksiyonu deprecated. - 1.107.0:
--fatal-deprecation'adart-sass-2değeri geldi.
Bu listede bir şey dikkat çekiyor: değişikliklerin çoğu Sass'ı CSS'e yaklaştırmak için. Eğik çizginin bölme değil ayraç olması, renk fonksiyonlarının CSS'teki color space'lerle uyumu, if()'in CSS syntax'ı. Sass ekibinin kuralı, CSS'te geçerli olan bir şeyin Sass'ta da aynı anlama gelmesi.
Dart Sass 2.0'da Ne Değişecek?
Sass ekibi 22 Eylül 2026'daki "The Road to Dart Sass 2" yazısında planı açıkladı: 1.x'teki deprecation'ların çoğu 2.0'da hataya dönüşecek; birkaç tanesi ise deprecation olarak kalıp Dart Sass 3.0'da kaldırılacak. Hedef tarih Aralık 2026; 14 Kasım 2026 itibarıyla npm'deki en son sürüm 1.108.2 ve 2.0'ın bir prerelease'i yok. Hangi deprecation'ların 2.0'da hata olacağını tahmin etmek yerine Sass'ın kendisine sordum; 1.108.2'nin JavaScript API'si bu kümeyi sass.deprecations.dartSass2 olarak veriyor. Küme, 1.105.0'a kadar eklenmiş bütün aktif deprecation'lardan dördünün çıkarılmasıyla oluşuyor ve 22 deprecation içeriyor. Bookstore'u ilgilendirenler:
| Deprecation | Örnek | Dart Sass 2.0 | Çözüm |
|---|---|---|---|
slash-div | $gap / 2 | Hata; / ayraç olur | math.div() ya da calc() |
color-functions | darken($brand, 10%) | Hata | color.adjust() ya da color.scale() |
legacy-js-api | sass.renderSync() | Hata | sass.compile() |
strict-unary | $a -$b | Hata | $a - $b |
import | @import "tokens" | Uyarı kalır, 3.0'da kalkar | @use / @forward |
global-builtin | map-get() | Uyarı kalır, 3.0'da kalkar | map.get() |
if-function | if($a, 700, 400) | Uyarı kalır, 3.0'da kalkar | if(sass($a): 700; else: 400) |
Dikkat edilmesi gereken bir ayrıntı: darken() ile map-get() ikisi de global built-in function ama farklı akıbetleri var. darken() ayrıca color-functions deprecation'ına da girdiği için 2.0'da hata veriyor; map-get() ise 3.0'a kadar çalışmaya devam ediyor.
--fatal-deprecation ile Bugünden Hata Almak
Eski bir Bookstore dosyasında bu tablonun neredeyse tamamı var:
@import "old-tokens";
.order-summary {
// slash-div: 2.0'da ayraç olur
padding: $gap / 2;
width: percentage(1 / $columns);
// color-functions: 2.0'da hata
border-color: darken($brand, 10%);
// global-builtin: 2.0'da hâlâ uyarı
color: map-get((sale: #b91c1c), sale);
// eski if(): ancak 3.0'da kalkıyor
font-weight: if($columns > 3, 700, 400);
}
Normal derlemede sekiz uyarı çıkıyor ve CSS üretiliyor. Dart Sass 2.0'ın bu dosyaya ne diyeceğini bugünden görmek için CLI'a --fatal-deprecation=dart-sass-2 veriyoruz. Bir not: blog yazılarında sık geçen --fatal-deprecations (çoğul) CLI'da yok; 1.108.2 Could not find an option named "--fatal-deprecations". diyerek duruyor. CLI flag'leri tekil (--fatal-deprecation, --silence-deprecation, --future-deprecation), JavaScript API'deki option'lar çoğul (fatalDeprecations).
npx sass --fatal-deprecation=dart-sass-2 07/checkout.scss
DEPRECATION WARNING [import]: Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0.
...
DEPRECATION WARNING [if-function]: The Sass if() syntax is deprecated in favor of the modern CSS syntax.
Suggestion: if(sass($columns > 3): 700; else: 400)
...
Error: Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0.
Recommendation: math.div($gap, 2) or calc($gap / 2)
More info and automated migrator: https://sass-lang.com/d/slash-div
This is only an error because you've set the slash-div deprecation to be fatal.
Remove this setting if you need to keep using this feature.
╷
5 │ padding: $gap / 2;
│ ^^^^^^^^
╵
07/checkout.scss 5:14 root stylesheet
import ve if-function uyarı olarak kalıyor, slash-div derlemeyi durduruyor. dart-sass-2 değeri 1.107.0'da geldi; daha eski bir Sass'ta Sass blogundaki uzun listeyi kullanmak gerekiyor: --fatal-deprecation=1.79.0,compile-string-relative-url,misplaced-rest,with-private,function-name,adjacent-compounds. Bir sürüm numarası vermek "o sürümde ve öncesinde deprecated olan her şey" demek. 1.107.0 bir de istisna syntax'ı getirdi: --fatal-deprecation=dart-sass-2,import 3.0'a kalan @import'u da hata yapıyor, -import ise bir sürümle seçilen kümeden çıkarıyor.
sass-migrator ile Temizlik
Migrator'ın her deprecation için ayrı bir komutu var. Dosyanın bir kopyasında sırayla dördünü çalıştırdım:
npx sass-migrator division 07/migrated/checkout.scss
npx sass-migrator color 07/migrated/checkout.scss
npx sass-migrator if-function 07/migrated/checkout.scss
npx sass-migrator module --migrate-deps 07/migrated/checkout.scss
@use "sass:color";
@use "sass:math";
@use "sass:map";
@use "old-tokens";
.order-summary {
// slash-div: 2.0'da ayraç olur
padding: old-tokens.$gap * 0.5;
width: math.percentage(math.div(1, old-tokens.$columns));
// color-functions: 2.0'da hata
border-color: color.adjust(old-tokens.$brand, $lightness: -10%, $space: hsl);
// global-builtin: 2.0'da hâlâ uyarı
color: map.get((sale: #b91c1c), sale);
// eski if(): ancak 3.0'da kalkıyor
font-weight: if(sass(old-tokens.$columns > 3): 700; else: 400);
}
Migrator'ın kararları ilginç. $gap / 2'yi math.div() yerine $gap * 0.5 yaptı: ikiye bölmek yarıyla çarpmakla aynı ve daha okunur. darken()'ı color.adjust(..., $space: hsl)'e çevirirken $space'i açıkça yazdı, çünkü eski fonksiyon HSL'de (ton, doygunluk, açıklık ile tanımlanan renk modeli) çalışıyordu ve yeni API'de bu artık varsayılan değil. @use satırları arasındaki boş satırlar kozmetik; elle toparlanabilir. Sonra en katı ayarla derledim ve eski çıktıyla karşılaştırdım:
npx sass --fatal-deprecation=dart-sass-2,import,global-builtin,if-function 07/migrated/checkout.scss
.order-summary {
padding: 6px;
width: 25%;
border-color: rgb(51.5406162465%, 23.7659508248%, 2.5770308123%);
color: #b91c1c;
font-weight: 700;
}
Hiç uyarı yok ve diff eski dosyanın çıktısıyla birebir aynı olduğunu söylüyor. Gerçek bir projede sıra önemli: önce module değil, division ve color gibi küçük, mekanik migrator'ları çalıştırıp her birinin ardından çıktıyı karşılaştırmak, bir sorun çıktığında hangi adımın sebep olduğunu bulmayı kolaylaştırıyor.
Legacy JS API'den Modern API'ye
Sass'ı kendi build script'inden çağırıyorsan (Gulp görevi, özel bir webpack loader'ı, eski bir CLI aracı) render()/renderSync() kullanıp kullanmadığına bak. Aynı dosyayı iki API'yle derledim:
// aynı dosya legacy API (render) ve modern API (compile) ile
import * as sass from "sass";
const file = "07/migrated/checkout.scss";
// Dart Sass 2.0'da hata olacak her deprecation'ı bugünden hata yap
const fatalDeprecations = [sass.deprecations.dartSass2];
const legacy = sass.renderSync({ file });
console.log(`legacy renderSync: ${legacy.css.length} bytes`);
try {
sass.renderSync({ file, fatalDeprecations });
} catch (error) {
console.log(`legacy renderSync, fatal: ${error.message.split("\n")[0]}`);
}
const modern = sass.compile(file, { fatalDeprecations });
console.log(`modern compile, fatal: ${modern.css.length} bytes, ${modern.loadedUrls.length} files loaded`);
DEPRECATION WARNING [legacy-js-api]: The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0.
More info: https://sass-lang.com/d/legacy-js-api
legacy renderSync: 154 bytes
legacy renderSync, fatal: The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0.
modern compile, fatal: 154 bytes, 2 files loaded
Legacy API'nin kendisi bir deprecation; dartSass2 kümesi fatal olduğunda renderSync() stil dosyasına hiç bakmadan hata veriyor. Modern API aynı CSS'i üretiyor ve loadedUrls gibi watch modu için gerekli bilgileri de döndürüyor. Angular ve Vite bu geçişi zaten yaptı: Angular 22.2'nin build kodu compileStringAsync() kullanıyor, Vite 8 ise initAsyncCompiler() ve compileStringAsync(). Bu araçları kullanan projelerin yapması gereken bir şey yok; sorun genelde kimsenin dokunmadığı eski bir yardımcı script'te çıkıyor.
Üçüncü Parti Kütüphaneler: quietDeps ve silenceDeprecations
Bir kütüphanenin içindeki deprecation'ı sen düzeltemezsin. Sass bunun için iki ayar sunuyor. --quiet-deps (JS API'de quietDeps) load path ya da importer üzerinden yüklenen dosyalardan gelen uyarıları gizliyor. --silence-deprecation (silenceDeprecations) ise belirli bir deprecation'ı her yerde susturuyor. Bakımını yapmadığımız eski bir grid kütüphanesini load path ile yükleyen bir dosyayla denedim:
// bakımını yapmadığımız eski bir grid kütüphanesi
$grid-gutter: 24px !default;
@mixin row {
display: flex;
margin-inline: -($grid-gutter / 2);
}
npx sass --load-path=07/vendor-lib 07/catalog.scss
npx sass --load-path=07/vendor-lib --quiet-deps 07/catalog.scss
npx sass --load-path=07/vendor-lib --quiet-deps --fatal-deprecation=dart-sass-2 07/catalog.scss
İlk komut slash-div uyarısını gösteriyor. İkincisi uyarıyı gizliyor. Üçüncüsü önemli: --quiet-deps açıkken --fatal-deprecation=dart-sass-2 da kütüphanedeki slash-div'i yakalamıyor; derleme hatasız bitiyor ve margin-inline: -12px üretiyor. Yani quietDeps yalnız uyarıyı değil, bu dosyalar için fatal ayarını da etkisiz bırakıyor. Kütüphane Dart Sass 2.0'da kırılacak, ama sen bunu ancak 2.0'a geçtiğin gün göreceksin.
Bu yüzden bu ayarların meşru olduğu durum dar: güncellenmesini beklediğin, sürümünü sabitlediğin ve takip ettiğin bir kütüphanenin gürültüsünü günlük build'den kaldırmak. Bunu yaparken ayrı bir kontrolde (CI'da haftada bir gibi) quietDeps olmadan derleyip kütüphanelerin durumunu görmeye devam etmek gerekiyor. silenceDeprecations'ı kendi kodundaki bir deprecation'ı susturmak için kullanmak ise borcu ertelemekten başka bir şey değil.
Angular'da: Kendi Sass Sürümü ve Gizlenen Uyarılar
Angular'da bu ayarlar angular.json'daki stylePreprocessorOptions.sass altından veriliyor: fatalDeprecations, silenceDeprecations ve futureDeprecations. quietDeps bu listede yok, çünkü Angular'ın build kodu onu her zaman true olarak sabit veriyor (@angular/build'in sass-language.js dosyasında quietDeps: true).
Yazının başındaki tahminin cevabı bu ayrıntıda. fatalDeprecations: ["slash-div"] açıkken abstracts'taki half() fonksiyonuyla ng build:
Application bundle generation complete.
Hata yok, uyarı da yok. Sebep includePaths: Angular load path'leri kendi importer'ına çeviriyor, Sass açısından bu yoldan yüklenen her dosya bir "dependency" ve quietDeps: true onları hem susturuyor hem de fatal ayarından muaf tutuyor. Aynı fonksiyonu @use "../styles/abstracts" gibi göreli bir yolla yükleyince build bekleneni yapıyor:
✘ [ERROR] Error: Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0.
...
This is only an error because you've set the slash-div deprecation to be fatal.
...
../../../../src/styles/abstracts/_breakpoints.scss 19:13 half()
Bookstore'un bütün global stil ağacı ve her component'in abstracts'ı includePaths üzerinden yükleniyor. Yani Angular build'i, kodumuzun büyük kısmındaki deprecation'ları bize hiç göstermiyor. Göreli yollara geri dönmek dördüncü yazıda çözdüğümüz sorunu geri getirir; ben bunun yerine kontrolü build'den ayırdım.
İkinci ayrıntı Sass sürümü. Angular 22.2 kendi Sass 1.104.1'iyle derliyor ve dart-sass-2 değeri 1.107.0'da geldiği için onu tanımıyor:
▲ [WARNING] Invalid deprecation id or version "dart-sass-2". [plugin angular-sass]
Build durmuyor, değer sessizce yok sayılıyor. Angular 22.2'de doğru ayar blogdaki uzun liste:
"sass": {
"fatalDeprecations": [
"1.79.0",
"compile-string-relative-url",
"misplaced-rest",
"with-private",
"function-name",
"adjacent-compounds"
]
}
Bu liste 1.104.1'de uyarısız kabul ediliyor. npm'deki @angular/build@22.3.0-rc.0'ın bağımlılıklarında Sass 1.108.2 görünüyor; 22.3 çıktığında dart-sass-2 Angular içinde de kullanılabilecek.
Gizlenen uyarılar için bookstore-web'e projenin kendi Sass'ıyla (sass@1.108.2, dev dependency) çalışan küçük bir kontrol script'i ekledim. Script src altındaki partial olmayan her .scss dosyasını Angular'la aynı load path'lerle, quietDeps olmadan ve dartSass2 kümesi fatal olarak derliyor:
npm run check:sass2
3 files, 0 failed, warnings: {}
half()'ı geri koyduğumda aynı script Angular build'inin görmediğini yakalıyor:
FAIL src/app/app.scss
Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0.
styles/abstracts/_breakpoints.scss:19
3 files, 1 failed, warnings: {}
Script, @angular/material'ı da node_modules load path'i üzerinden derliyor; Material 22.2.7'den hiçbir uyarı gelmedi.
Üretimde Dikkat
Sass 2.0 kontrolünü CI'a koy ve build'den ayrı tut. Angular'ın quietDeps davranışı yüzünden fatalDeprecations tek başına yeterli değil; check:sass2 gibi bir adım hem kendi kodunu hem kütüphaneleri görüyor. Dart Sass 2.0 çıktığında bu script'in Sass sürümünü 2.0'a çekmek, Angular'ın kendi güncellemesini beklemeden durumu görmenin en hızlı yolu.
Sass sürümünü iki yerde takip et. Angular projesinde iki Sass var: @angular/build'in sabitlediği (22.2'de 1.104.1) ve senin kontrol için kurduğun. npm ls sass sass-embedded hangisinin nerede olduğunu gösteriyor. Angular güncellemesinde Sass da değiştiği için güncelleme pull request'inde derlenmiş CSS'i karşılaştırmak, birinci yazıdaki "potentially breaking bug fix" maddelerine karşı en ucuz önlem.
2.0 çıkınca release notes'u oku. Bu yazıdaki 2.0 tablosu yol haritasına ve 1.108.2'nin dartSass2 kümesine dayanıyor; blog yazısı da son kararın release notes'ta olacağını söylüyor. Aralık'ta 2.0 yayınlandığında listeyi oradan doğrulamak gerekiyor.
Sık Düşülen Tuzaklar
Uyarıları silenceDeprecations ile susturup unutmak. Bugün susturulan her slash-div, Dart Sass 2.0'a geçilen gün build hatası olarak geri geliyor; üstelik o gün hepsi birden.
Angular'da fatalDeprecations verip işin bittiğini sanmak. Yukarıda gördüğün gibi includePaths ile yüklenen dosyalar bu ayarın dışında kalıyor ve dart-sass-2 gibi tanınmayan bir değer yalnız bir uyarıyla yok sayılıyor. Ayarı verdikten sonra bilerek bir deprecation ekleyip build'in gerçekten kırıldığını görmeden ayara güvenme.
CLI'da --fatal-deprecations yazmak. Çoğul hâli JavaScript API'nin option adı; CLI'da flag tekil ve hata mesajı bunu açıkça söylüyor. CI script'lerinde bu hata genelde ilk koşuda yakalanır, ama bir || true ile birleşmişse sessizce hiçbir şey yapmayan bir adım kalır.
Migrator'ları tek seferde bütün projede çalıştırıp tek bir commit atmak. module migrator'ı yüzlerce dosyayı değiştirebiliyor; division ve color ile aynı commit'te olursa bir regresyonun hangi adımdan geldiğini bulmak zorlaşıyor. Her migrator ayrı bir commit ve her birinin ardından derlenmiş CSS'in diff'i.
Küçük Bir Deneme
★☆☆ 07/checkout.scss'i --fatal-deprecation=1.79.0 ile derle ve dart-sass-2 ile aldığın sonuçla karşılaştır. Bu dosya için iki ayar arasında bir fark var mı?
★★☆ 07/vendor-lib/_legacy-grid.scss'i 07/ altına taşı ve catalog.scss'ten göreli yolla yükle. --quiet-deps ve --fatal-deprecation=dart-sass-2 ile derlediğinde sonuç neden değişiyor?
★★★ check:sass2 script'ini her deprecation türünden kaç tane olduğunu ve hangi dosyalardan geldiğini bir JSON raporu olarak yazacak şekilde genişlet, raporu CI'da artifact olarak sakla ve iki rapor arasında yeni bir deprecation eklendiyse adımı başarısız yap.
Serinin başında sorduğumuz soruya döndüğümüzde cevap artık daha net: değişken, nesting ve renk matematiği için artık native CSS yetiyor; Sass'ın değeri module sisteminde, veriden kural ve custom property üretmekte, derleme zamanı hatalarında ve büyük bir stil ağacını düzenli tutmakta. Serinin bundan sonraki yazıları günlük araç kutusuna geçiyor: built-in module'leri tek tek, responsive mixin'ler ve utility üretimi, kendi Sass kütüphaneni yazmak ve Sass'ı build'e bağlamak. Utility-first yaklaşım için Tailwind CSS serisine, Sass'ın build zincirindeki yeri için Build Araçları serisine de bakabilirsin.