Bu yayın, DevTools'un mimarisinde yaptığımız değişiklikleri ve nasıl oluşturulduğunu açıklayan bir dizi blog yayınının bir parçasıdır.
JavaScript modüllerine geçiş ve Web bileşenlerine geçiş ile ilgili olarak, bugün Devtools'un mimarisinde yaptığımız değişiklikler ve bu mimarinin nasıl oluşturulduğu konulu blog yayını serimize devam ediyoruz. (Henüz görmediyseniz DevTools'un mimarisini modern web'e yükseltme çalışmamızla ilgili bir video yayınladık. Bu videoda, web projelerinizi iyileştirmeyle ilgili 14 ipucu yer alıyor.)
Bu yayında, Closure Compiler tür kontrol aracından TypeScript'e geçiş sürecimizi 13 ay boyunca nasıl yönettiğimizi anlatacağız.
Giriş
DevTools kod tabanının boyutu ve üzerinde çalışan mühendislere güven vermenin gerekliliği göz önüne alındığında, tür denetleyici kullanmak zorunludur. Bu amaçla, Geliştirici Araçları 2013'te Closure Compiler'ı kullanmaya başladı. Closure'u kullanmaya başlamak, DevTools mühendislerinin güvenle değişiklik yapmasına olanak tanıdı. Closure derleyicisi, tüm sistem entegrasyonlarının doğru şekilde yazılmasını sağlamak için tür kontrolleri gerçekleştiriyordu.
Ancak zaman geçtikçe modern web geliştirmede alternatif tür kontrolörleri popüler hale geldi. TypeScript ve Flow bu tür dillere örnek olarak verilebilir. Ayrıca TypeScript, Google'da resmi bir programlama dili oldu. Bu yeni tür kontrol araçlarının popülerliği artarken, bir tür kontrol aracı tarafından yakalanması gereken gerilemelerin yayınlandığını da fark ettik. Bu nedenle, tür kontrol cihazı seçimimizi yeniden değerlendirmeye ve DevTools'da geliştirmeyle ilgili sonraki adımları belirlemeye karar verdik.
Tür denetleyicilerini değerlendirme
Geliştirici Araçları zaten bir tür kontrol cihazı kullandığından yanıtlamamız gereken soru şuydu:
Closure Compiler'ı kullanmaya devam edecek miyiz yoksa yeni bir tür kontrol cihazına mı geçeceğiz?
Bu soruyu yanıtlamak için tür doğrulayıcıları çeşitli özellikler açısından değerlendirmemiz gerekiyordu. Tür kontrol cihazını kullanmamız mühendis güvenine odaklandığından bizim için en önemli husus tür doğruluğudur. Başka bir deyişle: Tür denetleyiciler gerçek sorunları keşfetmede ne kadar güvenilir?
Değerlendirmemiz, yayınladığımız gerilemelere ve bunların temel nedenlerinin ne olacağını belirlemeye odaklandı. Buradaki varsayım, Closure Compiler'ı zaten kullandığımız için Closure'un bu sorunları yakalayamayacağıdır. Bu nedenle, başka bir tür kontrol cihazının bunu yapıp yapamayacağını belirlememiz gerekir.
TypeScript'te tür doğruluğu
TypeScript, Google'da resmi olarak desteklenen ve popülerliği hızla artan bir programlama dili olduğundan önce TypeScript'i değerlendirmeye karar verdik. TypeScript ekibi, JavaScript tür denetimi açıkken uyumluluklarını izlemek için DevTools'u test projelerinden biri olarak kullandığından TypeScript ilginç bir seçimdi. Referans test çıkışı, TypeScript'in çok sayıda tür sorunu yakaladığını (Closure derleyicisinin mutlaka tespit etmediği sorunlar) gösteriyordu. Bu sorunların çoğu, yayınladığımız gerilemelerin temel nedeni olabilir. Bu da TypeScript'in Geliştirici Araçları için uygun bir seçenek olabileceğine inanmamızı sağladı.
JavaScript modüllerine geçişimiz sırasında Closure Compiler'ın daha önce olduğundan daha fazla sorun tespit ettiğini fark etmiştik. Standart bir modül biçimine geçmek, Closure'un kod tabanımızı anlama becerisini ve dolayısıyla tür denetleyicilerinin etkinliğini artırdı. Ancak TypeScript ekibi, DevTools'un JavaScript modülleri taşıma işleminden önceki bir temel sürümünü kullanıyordu. Bu nedenle, JavaScript modüllerine geçişin TypeScript derleyicisinin yakalayacağı hata miktarını da azaltıp azaltmadığını öğrenmemiz gerekiyordu.
TypeScript'i değerlendirme
Geliştirici Araçları on yıldan uzun bir süredir var ve bu süre zarfında önemli ölçüde büyük ve zengin özelliklere sahip bir web uygulamasına dönüştü. Bu blog yayınının yazıldığı sırada DevTools yaklaşık 150.000 satır birinci taraf JavaScript kodu içermektedir. TypeScript derleyicisini kaynak kodumuzda çalıştırdığımızda hata sayısı çok fazlaydı. TypeScript derleyicisi kod çözümlemeyle ilgili daha az hata (yaklaşık 2.000 hata) yayınlasa da kod tabanımızda tür uyumluluğuyla ilgili 6.000 hata daha olduğunu tespit ettik.
Bu, TypeScript'in türlerin nasıl çözüleceğini anlayabilmesine rağmen kod tabanımızda önemli miktarda tür uyumsuzluğu bulduğunu gösterdi.
Bu hataların manuel olarak analiz edilmesi, TypeScript'in (çoğu zaman) doğru olduğunu göstermiştir.
TypeScript'in bunları tespit edebilmesinin ve Closure'un bunu yapamasının nedeni, Closure derleyicisinin genellikle bir türün Any
olduğunu çıkarması, TypeScript'in ise atamalar temel alınarak tür çıkarım işlemi gerçekleştirmesi ve daha doğru bir tür çıkarmasıdır.
Bu nedenle, TypeScript, nesnelerimizin yapısını anlama konusunda gerçekten daha iyiydi ve sorunlu kullanımları keşfetti.
Bununla ilgili önemli bir nokta, DevTools'ta Closure derleyicisinin kullanımının @unrestricted
'ün sık kullanılmasını içermesidir.
Bir sınıfa @unrestricted
notu eklemek, Closure derleyicisinin söz konusu sınıf için katı mülk kontrollerini etkili bir şekilde devre dışı bırakır. Bu da geliştiricinin, sınıf tanımını tür güvenliği olmadan istediği gibi artırabileceği anlamına gelir.
DevTools kod tabanında @unrestricted
kullanımının neden yaygın olduğuyla ilgili herhangi bir geçmiş bağlam bulamadık ancak bu durum, kod tabanının büyük bölümlerinde Closure derleyicisinin daha az güvenli bir çalışma modunda çalıştırılmasına neden oldu.
TypeScript'in bulduğu tür hatalarıyla geriye dönük analizlerimizin çapraz analizi de bir çakışma olduğunu gösterdi. Bu da TypeScript'in (türlerin doğru olması koşuluyla) bu sorunları önleyebileceğine inanmamıza yol açtı.
any
araması yapma
Bu noktada, Closure Compiler kullanımımızı iyileştirmek veya TypeScript'e geçmek arasında karar vermemiz gerekiyordu. (Flow, Google'da veya Chromium'da desteklenmediğinden bu seçenekten vazgeçmek zorunda kaldık.) JavaScript/TypeScript araçlarıyla çalışan Google mühendisleriyle yaptığımız görüşmeler ve aldıklarımız öneriler doğrultusunda TypeScript derleyicisini seçtik. (Kısa süre önce Puppeteer'ı TypeScript'e taşıma hakkında bir blog yayını da yayınladık.)
TypeScript derleyicisinin birincil nedeni, geliştirilmiş tür doğruluğudur. Diğer avantajlar arasında Google'ın dahili TypeScript ekiplerinden destek ve TypeScript dilinin interfaces
(JSDoc'taki typedefs
yerine) gibi özellikleri yer alır.
TypeScript derleyicisini seçmek, DevTools kod tabanına ve dahili mimarisine önemli ölçüde yatırım yapmamız gerektiği anlamına geliyordu. Bu nedenle, TypeScript'e geçiş için en az bir yıla ihtiyacımız olduğunu tahmin ettik (3. çeyrek 2020'de hedeflenmektedir).
Taşıma işlemini gerçekleştirme
Karşımıza çıkan en büyük soru şuydu: TypeScript'e nasıl geçeceğiz? 150.000 satır kodumuz var ve bunu tek seferde taşıyamayacağımızı biliyorduk. Ayrıca,kod tabanımızda TypeScript'i çalıştırmanın binlerce hatayı ortaya çıkaracağını da biliyorduk.
Birden fazla seçeneği değerlendirdik:
- Tüm TypeScript hatalarını alın ve bunları "ideal" bir çıkışla karşılaştırın. Bu yaklaşım, TypeScript ekibinin yaklaşımına benzer. Bu yaklaşımın en büyük dezavantajı, aynı kod tabanında düzinelerce mühendis çalıştığından birleştirme çakışmalarının sıklıkla yaşanmasıdır.
- Sorunlu tüm türleri
any
olarak ayarlayın. Bu, TypeScript'in hataları bastırmasına neden olur. Taşıma işleminde amacımız, engellemenin zayıflatacağı tür doğruluğu olduğundan bu seçeneği tercih etmedik. - Tüm TypeScript hatalarını manuel olarak düzeltin. Bu, binlerce hatayı düzeltmeyi gerektirir ve zaman alıcıdır.
Beklenen büyük çabaya rağmen 3. seçeneği tercih ettik. Bu seçeneği tercih etmemizin başka nedenleri de vardı. Örneğin, tüm kodu denetlememize ve uygulama dahil tüm işlevleri on yılda bir kez incelememize olanak tanıdı. İşletme açısından bakıldığında, yeni bir değer sunmuyor, mevcut durumu koruyorduk. Bu durum, 3. seçeneğin doğru seçenek olduğunu açıklamayı zorlaştırdı.
Ancak TypeScript'i benimseyerek özellikle gerilemelerle ilgili gelecekteki sorunları önleyebileceğimizi düşünüyorduk. Bu nedenle, "yeni iş değeri ekliyoruz" yerine "elde ettiğimiz iş değerini kaybetmediğimizden emin oluyoruz" şeklinde bir yaklaşım benimsedik.
TypeScript derleyicisinin JavaScript desteği
Desteği aldıktan ve hem Closure hem de TypeScript derleyicisini aynı JavaScript kodunda çalıştırmaya yönelik bir plan geliştirdikten sonra küçük dosyalarla başladık. Yaklaşımımız çoğunlukla aşağıdan yukarıya doğruydu: Temel koddan başlayıp üst düzey panellere ulaşana kadar mimaride yukarı doğru ilerledik.
DevTools'taki her dosyaya önceden @ts-nocheck
ekleyerek çalışmamızı paralelleştirebildik. "TypeScript'i düzeltme" işlemi, @ts-nocheck
ek açıklamasını kaldırmak ve TypeScript'in bulduğu hataları çözmektir. Bu, her dosyanın kontrol edildiğinden ve mümkün olduğunca çok sayıda tür sorununun çözüldüğünden emin olduğumuz anlamına geliyordu.
Genel olarak bu yaklaşım, birkaç sorunla karşılaşılmasına rağmen işe yaradı. TypeScript derleyicisinde birkaç hatayla karşılaştık ancak bunların çoğu belirsizdi:
any
döndüren bir işlev türüne sahip isteğe bağlı parametre zorunlu olarak değerlendirilir: #38551- Sınıfın statik bir yöntemine atanan özellik, beyanla ilgili kesinti oluşturuyor: #38553
- Parametresiz bir kurucuya sahip alt sınıf ve parametreli bir kurucuya sahip üst sınıfın tanımında alt kurucu atlanıyor: #41397
Bu hatalar, TypeScript derleyicisinin% 99 oranında sağlam bir temel olduğunu gösterir. Evet, bu anlaşılması zor hatalar bazen DevTools'ta sorunlara neden oluyordu ancak çoğu zaman bu hataları kolayca atlatacak kadar anlaşılmazdı.
Kafa karışıklığına neden olan tek sorun, .tsbuildinfo
dosyalarının kararlı olmayan çıkışıydı: #37156.
Chromium'da, aynı Chromium taahhütünün iki derlemesinin de tam olarak aynı çıkışı sağlaması gerekir.
Maalesef Chromium derleme mühendislerimiz, .tsbuildinfo
çıktısının kesin olmadığını tespit etti: crbug.com/1054494.
Bu sorunu gidermek için .tsbuildinfo
dosyasını (temel olarak JSON içerir) monkey-patch'lememiz ve kesin bir çıkış döndürmek için son işlemden geçirmemiz gerekiyordu: https://crrev.com/c/2091448
Neyse ki TypeScript ekibi yayın öncesi sorunu çözdü ve kısa süre içinde geçici çözümümüzü kaldırabildik. Hata raporlarına açık davranıp bu sorunları hızlı bir şekilde düzelttiği için TypeScript ekibine teşekkür ederiz.
Genel olarak TypeScript derleyicisinin (tür) doğruluğundan memnunuz. Büyük bir açık kaynak JavaScript projesi olan Devtools'un, TypeScript'te JavaScript desteğinin sağlamlaştırılmasına yardımcı olduğunu umuyoruz.
Sonucu analiz etme
Bu tür hataları çözme ve TypeScript tarafından kontrol edilen kod miktarını yavaş yavaş artırma konusunda önemli ilerleme kaydettik. Ancak Ağustos 2020'de (bu taşıma işleminin 9. ayında) yaptığımız bir inceleme sonucunda, mevcut hızımızla son tarihe yetişemeyeceğimizi fark ettik. Mühendislerimizden biri, "TypeScript'e dönüştürme"nin (bu taşıma işlemine verdiğimiz ad) ilerleme durumunu gösteren bir analiz grafiği oluşturdu.
TypeScript taşıma işleminin ilerleme durumu - Taşınması gereken kalan kod satırlarını izleme
Kalan satır sayısının sıfıra düşeceği tahminler, son tarihimizden yaklaşık bir yıl sonra olan Temmuz 2021 ile Aralık 2021 arasında değişiyordu. Yönetim ve diğer mühendislerle yaptığımız görüşmelerin ardından, TypeScript derleyici desteğine geçiş üzerinde çalışan mühendislerin sayısını artırmayı kabul ettik. Taşıma işlemini, birden fazla farklı dosya üzerinde çalışan birden fazla mühendisin birbiriyle çakışmaması için paralel olarak gerçekleştirilebilecek şekilde tasarladığımız için bu mümkün oldu.
Bu noktada TypeScript'e dönüştürme süreci ekip çapında bir çalışma haline geldi. Ek yardım sayesinde, geçişimizi Kasım 2020'nin sonunda, yani başladığımızdan 13 ay sonra ve ilk tahminimizden bir yıldan uzun bir süre önce tamamlayabildik.
Toplamda 18 mühendis tarafından gönderilen 771 değişiklik listesi (pull isteğine benzer) vardı. Takip hatamız (https://crbug.com/1011811) 1.200'den fazla yorum aldı (bunlardan neredeyse tamamı, değişiklik listelerindeki otomatik yayınlar). İzleme sayfamızda, TypeScript'e dönüştürülecek tüm dosyalar, bu dosyaların atandıkları kullanıcılar ve "TypeScript'e dönüştürüldükleri" değişiklik listesi için 500'den fazla satır vardı.
TypeScript derleyicisinin performansının etkisini azaltma
Şu anda yaşadığımız en büyük sorun, TypeScript derleyicisinin yavaş performansıdır. Chromium ve DevTools'u geliştiren mühendislerin sayısı göz önüne alındığında bu darboğaz maliyetli bir durumdur. Maalesef bu riski taşıma işleminden önce tespit edemedik ve yalnızca dosyaların çoğunu TypeScript'e taşıdığımız noktada Chromium derlemelerinde harcanan sürede belirgin bir artış olduğunu fark ettik: https://crbug.com/1139220
Bu sorunu Microsoft TypeScript derleyici ekibine bildirdik ancak maalesef bu davranışın kasıtlı olduğu belirlendi. Bu sorunun yeniden değerlendirileceğini umuyoruz. Bu arada, Chromium tarafında yavaş performans etkisini mümkün olduğunca azaltmak için çalışıyoruz.
Maalesef şu anda kullanabileceğimiz çözümler, Google çalışanı olmayan katkıda bulunanlar için her zaman uygun değildir. Chromium'a yapılan açık kaynak katkıları (özellikle Microsoft Edge ekibinden gelenler) çok önemli olduğundan, tüm katkıda bulunanlar için işe yarayacak alternatifler arıyoruz. Ancak şu anda uygun bir alternatif çözüm bulamadık.
Geliştirici Araçları'nda TypeScript'in mevcut durumu
Şu anda Closure derleyicisi tür kontrol cihazını kod tabanımızdan kaldırdık ve yalnızca TypeScript derleyicisini kullanıyoruz. TypeScript ile yazılmış dosyalar oluşturabiliyor ve TypeScript'e özgü özelliklerden (ör. arayüzler, geneller vb.) yararlanabiliyoruz. Bu da bize günlük olarak yardımcı oluyor. TypeScript derleyicisinin tür hatalarını ve geriye gidişleri yakalayacağına dair güvenimiz arttı. Bu taşıma işlemine ilk başladığımızda bu gerçekleşmesini umuyorduk. Birçok taşıma işlemi gibi bu da yavaş, ayrıntılı ve çoğu zaman zorluydu ancak avantajlarını gördüğümüz için buna değdiğini düşünüyoruz.
Önizleme kanallarını indirme
Varsayılan geliştirme tarayıcınız olarak Chrome Canary, Yeni Geliştirilenler veya Beta sürümünü kullanabilirsiniz. Bu önizleme kanalları, en son DevTools özelliklerine erişmenizi sağlar, en yeni web platformu API'lerini test etmenize olanak tanır ve sitenizdeki sorunları kullanıcılarınızdan önce bulmanıza yardımcı olur.
Chrome Geliştirici Araçları Ekibi ile iletişime geçme
Yeni özellikler, güncellemeler veya Geliştirici Araçları ile ilgili başka herhangi bir konu hakkında konuşmak için aşağıdaki seçenekleri kullanın.
- crbug.com adresinden bize geri bildirim ve özellik isteği gönderin.
- Geliştirici Araçları'nda Diğer seçenekler > Yardım > Geliştirici Araçları sorunu bildir'i kullanarak bir Geliştirici Araçları sorununu bildirin.
- @ChromeDevTools hesabına tweet gönderin.
- Geliştirici Araçları'ndaki yenilikler veya Geliştirici Araçları'yla ilgili ipuçları konulu YouTube videolarına yorum bırakın.