Kodu birleştirdikten ve küçülttikten sonra bile performansı etkilemeden istemci tarafı kodunuzu okunabilir ve daha da önemlisi hata ayıklanabilir durumda tutabilmeyi istediğiniz oldu mu? Bunu kaynak haritaların sihriyle yapabilirsiniz.
Kaynak eşlemeleri, birleştirilmiş/küçültülmüş bir dosyayı henüz oluşturulmamış duruma eşlemenin bir yoludur. Üretim için derleme yaptığınızda, JavaScript dosyalarınızı küçültüp birleştirerek orijinal dosyalarınızla ilgili bilgileri içeren bir kaynak haritası oluşturursunuz. Oluşturulan JavaScript'inizde belirli bir satır ve sütun numarasını sorguladığınızda, kaynak haritada orijinal konumu döndüren bir arama yapabilirsiniz. Geliştirici araçları (şu anda WebKit'in gecelik derlemeleri, Google Chrome veya Firefox 23 ve sonraki sürümler), kaynak haritayı otomatik olarak ayrıştırıp sadeleştirilmemiş ve birleştirilmemiş dosyalar çalışıyormuş gibi görünmesini sağlayabilir.
Demo, oluşturulan kaynağı içeren metin alanında herhangi bir yeri sağ tıklamanıza olanak tanır. "Orijinal konumu al"ı seçin kaynak eşlemeyi, oluşturulan satır ve sütun numarasını girerek sorgular ve konumu orijinal kodda döndürür. Sonucu görebilmek için konsolunuzun açık olduğundan emin olun.
Gerçek dünya
Kaynak Haritalar'ın gerçek dünyadaki aşağıdaki uygulamasını görüntülemeden önce, her gece Chrome Canary'de veya WebKit'te kaynak haritaları özelliğini etkinleştirdiğinizden emin olun. Bunun için, geliştirici araçları panelindeki ayarlar simgesini tıklayıp "Kaynak haritalarını etkinleştir"i işaretleyin. seçeneğini belirleyin.
Firefox 23 ve sonraki sürümlerde, yerleşik geliştirme araçlarında varsayılan olarak etkinleştirilmiş kaynak haritaları bulunur.
Kaynak eşlemelerini neden önemsemeliyim?
Kaynak eşleme, şu anda yalnızca sıkıştırılmamış/birleştirilmiş JavaScript'ten sıkıştırılmış/birleştirilmemiş JavaScript'e kadar çalışıyor. Ancak CoffeeScript gibi derlenmiş JavaScript dilleri ve hatta SASS veya LESS gibi CSS ön işlemcileri için destek ekleme olanağı sayesinde gelecek daha parlak bir gelecek.
İleride, kaynak eşlemeleriyle tarayıcıda yerel olarak destekleniyormuş gibi hemen hemen her dili kolayca kullanabilecektik:
- CoffeeScript
- ECMAScript 6 ve sonrası
- SASS/LESS ve diğerleri
- JavaScript'e derleme yapan tüm diller
Firefox konsolunun deneysel bir derlemesinde hata ayıklama işlemi yapılan CoffeeScript'in şu ekran video kaydını inceleyin:
Google Web Araç Seti (GWT) kısa bir süre önce Kaynak Haritalar için destek ekledi. GWT ekibinden Ray Cromwell, kaynak harita desteğini çalışırken gösteren harika bir ekran video kaydı yaptı.
Oluşturduğum bir başka örnekte de ES6 (ECMAScript 6 veya Next) yazmanıza ve ES3 ile uyumlu kod olarak derlemenize olanak tanıyan Google Traceur kitaplığı kullanılmıştır. Traceur derleyicisi, bir kaynak haritası da oluşturur. Kaynak eşleme sayesinde tarayıcıda yerel olarak desteklendikleri gibi kullanılan ES6 özelliklerinin ve sınıflarının demosunu inceleyin.
Demodaki metin alanı, anında derlenecek ve bir kaynak harita ile eşdeğer ES3 kodu oluşturacak ES6 yazmanıza olanak tanır.
Demo: ES6 yazma, hata ayıklama, kaynak eşlemeyi uygulamalı olarak görüntüleme
Kaynak eşlemesi nasıl çalışır?
Şu anda kaynak harita oluşturma desteği olan tek JavaScript derleyici/küçültücü Closure derleyici'dir. (Bunu nasıl kullanacağınızı daha sonra açıklayacağım.) JavaScript'iniz birleştirilip küçültüldükten sonra, yanında bir kaynak eşleme dosyası bulunur.
Şu anda Closure derleyici, tarayıcı geliştirici araçlarına bir kaynak eşlemenin mevcut olduğunu belirtmek için gerekli özel yorumu sona eklememektedir:
//# sourceMappingURL=/path/to/file.js.map
Bu, geliştirici araçlarının çağrıları orijinal kaynak dosyalardaki konumlarına geri eşleştirmesini sağlar. Daha önce yorum pragması //@
şeklindeydi, ancak bununla ilgili bazı sorunlar ve IE koşullu derleme yorumları nedeniyle yorumun //#
olarak değiştirilmesine karar verildi. Şu anda Chrome Canary, WebKit Nightly ve Firefox 24 ve sonraki sürümler yeni yorum pragmasını desteklemektedir. Bu söz dizimi değişikliği, sourceURL'yi de etkiler.
Tuhaf yorum fikrini beğenmediyseniz, derlenmiş JavaScript dosyanızda özel bir başlık da ayarlayabilirsiniz:
X-SourceMap: /path/to/file.js.map
Yorumda olduğu gibi bu, kaynak harita tüketicinize bir JavaScript dosyasıyla ilişkilendirilmiş kaynak haritayı nerede arayacağını bildirir. Bu başlık, tek satırlı yorumları desteklemeyen dillerde kaynak eşlemelerine referans verme sorununu da ele alır.
Kaynak harita dosyası, yalnızca kaynak eşlemeleri etkinse ve geliştirici araçlarınız açıksa indirilir. Ayrıca, geliştirici araçlarının gerektiğinde bu dosyalara başvurabilmesi ve görüntüleyebilmesi için orijinal dosyalarınızı da yüklemeniz gerekir.
Kaynak eşlemesi nasıl oluşturulur?
JavaScript dosyalarınızı küçültmek, birleştirmek ve kaynak haritası oluşturmak için Closure derleyici'yi kullanmanız gerekir. Komut aşağıdaki gibidir:
java -jar compiler.jar \
--js script.js \
--create_source_map ./script-min.js.map \
--source_map_format=V3 \
--js_output_file script-min.js
--create_source_map
ve --source_map_format
, iki önemli komut işaretidir. Varsayılan sürüm V2 olduğundan ve yalnızca V3 ile çalışmak istediğimizden bu gereklidir.
Bir kaynak haritasının anatomisi
Bir kaynak haritasını daha iyi anlamak için Closure derleyicisi tarafından oluşturulacak bir kaynak harita dosyasının küçük bir örneğini kullanacağız ve "eşlemelerin" nasıl nasıl çalıştığını anlatacağım. Aşağıdaki örnekte, V3 spesifikasyonu örneğindeki küçük bir varyasyon gösterilmektedir.
{
version : 3,
file: "out.js",
sourceRoot : "",
sources: ["foo.js", "bar.js"],
names: ["src", "maps", "are", "fun"],
mappings: "AAgBC,SAAQ,CAAEA"
}
Yukarıda, kaynak haritasının çok sayıda ilginç bilgi içeren bir nesne değişmez olduğunu görebilirsiniz:
- Kaynak eşlemenin temel aldığı sürüm numarası
- Oluşturulan kodun dosya adı (Küçültülmüş/kombine üretim dosyanız)
- sourceRoot, kaynakları bir klasör yapısıyla eklemenizi sağlar. Bu aynı zamanda yer tasarrufu tekniğidir
- kaynaklar, birleştirilen tüm dosya adlarını içerir
- adları, kodunuzun tamamında görünen tüm değişken/yöntem adlarını içerir.
- Son olarak, eşlemeler özelliğinde asıl işlem Base64 VLQ değerleri kullanılarak gerçekleşir. Gerçek alan tasarrufu burada gerçekleştirilir.
Base64 VLQ ve kaynak haritasını küçük tutma
İlk başta, kaynak harita spesifikasyonu tüm eşlemelerin çok ayrıntılı çıktılarını içeriyordu ve kaynak eşlemenin, oluşturulan kod boyutunun yaklaşık 10 katı boyutunu içermesiyle sonuçlanıyordu. İkinci sürüm ise bu oranı yaklaşık% 50, üçüncü sürüm ise bir kez daha %50 azalttı. Dolayısıyla 133 kB'lık bir dosya için 300 kB'lık bir kaynak eşleme elde ettiniz.
Peki, karmaşık eşlemeleri korurken boyutu nasıl küçülttüler?
VLQ (Değişken Uzunluk Miktarı) değeri, değerin bir Base64 değerine kodlanmasıyla birlikte kullanılır. Eşlemeler özelliği çok büyük bir dizedir. Bu dizenin içinde, oluşturulan dosya içindeki bir satır numarasını temsil eden noktalı virgüller (;) bulunur. Her satırda, bu satırdaki her segmenti temsil eden virgüller (,) bulunur. Bu segmentlerin her biri, değişken uzunluktaki alanlarda 1, 4 veya 5'tir. Bazıları daha uzun görünebilir ancak bunlar devamlılık bitleri içerir. Her segment bir öncekinin üzerine inşa edilir. Bu, her bir bit önceki segmentlerine göre olduğundan dosya boyutunun azaltılmasına yardımcı olur.
Yukarıda belirtildiği gibi, her segment değişken uzunlukta 1, 4 veya 5 olabilir. Bu diyagramda, bir devam biti (g) bulunan ve dört uzunluğunda değişken olarak kabul edilir. Bu segmenti ayrıntılarıyla inceleyeceğiz ve kaynak haritasının orijinal konum üzerinde nasıl çalıştığını göstereceğiz.
Yukarıda gösterilen değerler tamamen Base64 kodu çözülmüş değerlerdir. Doğru değerlerini elde etmek için birkaç işlem daha yapılması gerekir. Her segment genellikle beş şey yapar:
- Oluşturulan sütun
- Bunun göründüğü orijinal dosya
- Orijinal satır numarası
- Orijinal sütun
- Varsa asıl adı
Her segmentin adı, yöntem adı veya bağımsız değişkeni yoktur. Bu nedenle, tüm segmentler dört ila beş değişken uzunluğu arasında geçiş yapar. Yukarıdaki segment şemasında yer alan g değerine devamlılık biti denir ve Base64 VLQ kod çözme aşamasında daha fazla optimizasyon yapılmasını sağlar. Bir devamlı işlem biti, bir segment değeri üzerinde derlemenizi sağlar. Böylece, büyük bir sayıyı depolamak zorunda kalmadan büyük sayıları depolayabilirsiniz. Bu, kökleri midi biçiminde olan çok akıllı bir alan tasarrufu tekniğidir.
Yukarıdaki AAgBC
şeması daha fazla işlendiğinde 0, 0, 32, 16, 1 sonucunu döndürür. 32, aşağıdaki 16 değerini oluşturmaya yardımcı olan devam bitidir. Base64'te tamamen çözülen B, 1'dir. Bu nedenle, kullanılan önemli değerler 0, 0, 16, 1'dir. Bu, oluşturulan dosyanın 1. satırının (satırların sayısı noktalı iki nokta üst üste ile verilir) sütun 0'ın dosya 0 (0 dosya dizisi foo.js'dir), 1. sütundaki 16. satır ile eşlendiğini belirtir.
Segmentlerin kodunun nasıl çözüldüğünü göstermek için Mozilla'nın Kaynak Harita JavaScript kitaplığına başvuracağım. Ayrıca, JavaScript'te de yazılan WebKit geliştirici araçları kaynak eşleme koduna bakabilirsiniz.
B'den 16 değerini nasıl elde ettiğimizi doğru bir şekilde anlamak için bit tabanlı operatörlerle ve bu spesifikasyonun kaynak eşlemede nasıl çalıştığına dair temel bilgilere sahip olmamız gerekir. Bir önceki g rakamı, bit tabanlı AND (&) operatörü kullanılarak (32) rakamı ile VLQ_CONTINUATION_BIT (100000 veya 32) değeri karşılaştırılarak devam biti olarak işaretlenir.
32 & 32 = 32
// or
100000
|
|
V
100000
Bu, her ikisinde de göründüğü her bit konumunda 1 döndürür. Dolayısıyla, 33 & 32
öğesinin kodu çözülmüş bir Base64 değeri, yukarıdaki şemada görebileceğiniz gibi yalnızca 32 bit konumunu paylaştığından 32 döndürür. Bu işlem daha sonra, önceki her devamlılık biti için bit kaydırma değerini 5 artırır. Yukarıdaki örnekte yalnızca 5 bir kez kaydırılmıştır. Dolayısıyla sola kaydırarak 1 (B) x 5 kaydırabilirsiniz.
1 <<../ 5 // 32
// Shift the bit by 5 spots
______
| |
V V
100001 = 100000 = 32
Daha sonra bu değer, sayının (32) bir noktasında sağa kaydırılarak VLQ imzalı bir değerden dönüştürülür.
32 >> 1 // 16
//or
100000
|
|
V
010000 = 16
İşte oldu. 1'i böyle 16'ya çeviriyorsunuz. Bu, aşırı karmaşık bir süreç gibi görünebilir, ancak sayılar büyüdükçe daha da anlamlı hale gelir.
Olası XSSI sorunları
Bu spesifikasyonda, bir kaynak eşlemenin kullanılmasından kaynaklanabilecek siteler arası komut dosyası ekleme sorunlarından bahsedilmektedir. Bu sorunu azaltmak için kaynak haritanızın ilk satırının başına ")]}
" eklemeniz önerilir söz dizimi hatasının ortaya çıkacağı şekilde kasıtlı olarak JavaScript'i geçersiz kılabilir. WebKit geliştirici araçları bu sorunların üstesinden gelebilir.
if (response.slice(0, 3) === ")]}") {
response = response.substring(response.indexOf('\n'));
}
Yukarıda gösterildiği gibi ilk üç karakter, spesifikasyondaki söz dizimi hatasıyla eşleşip eşleşmediklerini kontrol etmek için dilimlenir. Bu durumda ilk yeni satır öğesine (\n) giden tüm karakterler kaldırılır.
sourceURL
ve displayName
iş başında: Eval ve anonim işlevler
Kaynak eşlemenin bir parçası olmasa da aşağıdaki iki kural, değerlendirmeler ve anonim işlevlerle çalışırken geliştirmeyi çok daha kolay hale getirmenize olanak tanır.
İlk yardımcı, //# sourceMappingURL
mülküne çok benziyor ve aslında kaynak harita V3 spesifikasyonunda belirtiliyor. Geçersiz kılınacak aşağıdaki özel yorumu kodunuza ekleyerek geliştirme araçlarınızda daha mantıklı adlar olarak görünmelerini sağlamak için değerlendirmeleri adlandırabilirsiniz. CoffeeScript derleyicisini kullanan basit bir demoya göz atın:
Demo: eval()
'deki kodu sourceURL üzerinden komut dosyası olarak gösterin
//# sourceURL=sqrt.coffee
Diğer yardımcı, anonim işlevin geçerli bağlamında bulunan displayName
özelliğini kullanarak anonim işlevleri adlandırmanıza olanak tanır. displayName
mülkünün nasıl çalıştığını görmek için aşağıdaki demonun profilini inceleyin.
btns[0].addEventListener("click", function(e) {
var fn = function() {
console.log("You clicked button number: 1");
};
fn.displayName = "Anonymous function of button 1";
return fn();
}, false);
Geliştirici araçlarında kodunuzun profilini çıkarırken (anonymous)
gibi bir değer yerine displayName
özelliği gösterilir. Ancak displayName suda neredeyse ölmüştür ve Chrome'a girmeyecektir. Ancak tüm umutlar kaybolmamış ve debugName adı verilen çok daha iyi bir teklif önerildi.
Eval adlandırma şu an için yalnızca Firefox ve WebKit tarayıcılarda kullanılabilmektedir. displayName
özelliği yalnızca WebKit gecelerinde kullanılabilir.
Birlikte toplanalım
Şu anda CoffeeScript'e eklenen kaynak harita desteği ile ilgili çok uzun bir tartışma mevcuttur. Sorunu inceleyin ve CoffeeScript derleyicisine kaynak harita oluşturma işleminin eklenmesi için desteğinizi ekleyin. Bu, CoffeeScript ve sadık takipçileri için büyük bir kazanç olacak.
UglifyJS'nin ilgilenmeniz gereken bir kaynak harita sorunu da var.
Coffeescript derleyicisi de dahil olmak üzere birçok araç, kaynak eşlemeleri oluşturur. Bu konuyu şu an için bir tartışma noktası olarak görüyorum.
Kaynak haritaları oluşturabilecek ne kadar çok araç elimizde varsa o kadar iyi olacaktır. O yüzden sorun ve favori açık kaynak projenize kaynak harita desteği ekleyin.
Mükemmel değil
Kaynak haritalarında şu anda izleme ifadelerine yer verilmemektedir. Sorun, bir bağımsız değişkeni veya değişken adını geçerli yürütme bağlamı içinde incelemeye çalışmanın, gerçekte var olmadığı için hiçbir şey döndürmemesidir. Bu, derlenen JavaScript'inizdeki gerçek bağımsız değişken/değişken adıyla karşılaştırıldığında incelemek istediğiniz bağımsız değişkenin/değişkenin gerçek adını aramak için bir tür ters eşleme gerektirir.
Bu tabii ki çözülebilir bir sorun ve kaynak haritalarına daha fazla dikkat ettiğimizde muhteşem özellikler ve daha istikrarlı hale gelmeye başlayabiliriz.
Sorunlar
Kısa bir süre önce jQuery 1.9, resmi CDN'lerin dışında sunulduğunda kaynak eşlemeleri için destek eklemiştir. Ayrıca, jQuery yüklenmeden önce IE koşullu derleme yorumları (//@cc_on) kullanıldığında özel bir hataya da dikkat çekmişti. O zamandan beri, source Eşleme URL'sini çok satırlı bir yoruma sarmalayarak bu sorunun etkilerini hafifletmek için taahhüt yapılmıştır. Alınacak ders, koşullu yorum kullanmayın.
O zamandan beri bu sorun düzeltildi ve söz dizimi //#
olarak değiştirildi.
Araçlar ve kaynak
İşte göz atmanız gereken diğer kaynak ve araçlardan bazıları:
- Nick Fitzgerald'ın kaynak harita desteğiyle bir UglifyJS çatalı var.
- Paul Ireland, kaynak haritalarını gösteren pratik bir demo deneyimi sunuyor
- Bunun ne zaman çıktığıyla ilgili WebKit değişiklik kümesine göz atın
- Değişiklik kümesi, tüm makaleyi başlatmasını sağlayan bir düzen testi de içeriyordu.
- Mozilla'da, yerleşik konsoldaki kaynak eşlemelerinin durumuyla ilgili takip etmeniz gereken bir hata bulunuyor
- Conrad Irwin, tüm Ruby kullanıcılarınız için çok kullanışlı bir kaynak harita mücevheri yazdı.
- Eval adlandırma ve displayName özelliği ile ilgili daha fazla bilgi edinin.
- Kaynak haritaları oluşturmak için Closure Compilers (Kapatma Derleyicileri) kaynağına göz atabilirsiniz.
- Videoda bazı ekran görüntüleri ve GWT kaynak haritaları desteğinden bahsediliyor.
Kaynak haritaları geliştirici araç setinde kullanabileceğiniz çok güçlü bir yardımcı programdır. Web uygulamanızı sade ama kolay hata ayıklamaya uygun hale getirmek son derece yararlıdır. Ayrıca yeni geliştiricilerin, deneyimli geliştiricilerin okunamayan küçültülmüş kodlarla uğraşmak zorunda kalmadan uygulamalarını nasıl yapılandırıp yazdıklarını görmelerini sağlayan çok güçlü bir öğrenme aracıdır.
Neyi bekliyorsunuz? Hemen tüm projeler için kaynak eşlemeleri oluşturmaya başlayın.