Seray Uzgur
09.05.2018

Marko: Vahşi doğada zarif bir kütüphane

İlk olarak dünya tatlısı, zarif konuşma tarzı, yelpaze fırça ve spatula sahibi rahmetli Bob Ross’a saygılar sevgiler diyerek başlamak istiyorum. Yazı içerisinde birçok ingilizce terim çevrilmeden kullanılacaktır, şimdiden bilgilendirmiş olayım.

Bu makalede bir süredir dikkatimi çeken bir front-end kütüphanesi olan Marko hakkında yazacağım. Sadece giriş bilgisi, tanıtım ve basit bir uygulama içerecek.

Önce bilmenizi isterim ki, Marko ile sadece 2 adet proje geliştirdim. Biri makale içerisinde bahsedeceğim örnek uygulama diğeri ise firmamızın web sayfası.

İlk Bakış

Marko e-Bay’in kendi ihtiyaçları için geliştirdiği bir kütüphane. Temel olarak yaptığı iş ve yapış tarzı bildiğiniz diğer kütüphanelere (React,Vue v.b.) benzerlik gösteriyor. Yine component bazlı, state tutabilen input (props) alabilen, ve Virtual DOM kullanan bir kütüphane. Karşılaştırmalı bir kaynak isterseniz hem kendi sitesinde bol bol var, hem de ekibin başındaki arkadaşın bir sunumu var.

Sitesinde belirttiği üzere 4 ana konuda öne çıkmaya çalışıyorlar.

Bu maddelere getirdikleri açıklamalar ve yaklaşımları genelde işe yarayan zarif çözümler. Bunlar hakkında biraz bahsetmek istiyorum.

Basitlik

If you know HTML, CSS, and Javascript, you know Marko

Konu basitlikse, bence ilk olarak bilmemizi istediği teknolojileri konuşmalıyız. Marko bu konuda oldukça alçak gönüllü. Standart HTML, CSS ve JS bilgisi ile hemen browser’a hello world çıkarabilecek bir sayfa hazırlayabiliyorsunuz. Ayrıca size sağladığı yazım kolaylıkları ile gerçekten karmaşık yapıları bile sade gözüken bir şekilde yazmanıza olanak tanıyor.

Bunun yanında diğer kütüphanelerle birlikte görmeye alışık olduğumuz create xx app yaklaşımının burada da olduğunu görüyoruz.

marko-cli uygulamasını kullanarak console üzerinden proje yaratabiliyorsunuz. Dokümanlarını takip ederek detaylarına bakabilirsiniz. Size güzel bir iskelet içerisinde Marko standartlarına göre bir proje oluşturuyor. Bu proje ön tanımlı ayarlara sahip, istemediğiniz sürece ek ayar yapmanıza gerek yok.

Ben marko-cli kullanarak oluşturulan uygulama iskeletini kullanarak örnek projemi oluşturdum. Kaynak kodlarına buradan ulaşabilirsiniz.

Verimlilik

Faster loads via streaming and a tiny (~10kb gzip) runtime

Performans çok önem verdikleri bir konu olmuş. Sunucu tarafında da istemci tarafında da rendering performansı çok yüksek bir kütüphane. Ayrıca kütüphane boyutu gzip sıkıştırması ilk 10kb civarında. Kütüphane kendi başına çok küçük boyutlu ve yaptığınız geliştirmelerde dikkatli olduğunuz sürece gerçekten bu performansı koruyarak yolunuza devam edebiliyorsunuz. Başka ek bir kütüphaneye ihtiyaç duymuyorsunuz.

Sitesinde belirttiği gibi CSS animation kullanmadan sadece JS kullanarak ortalama 60 fps almak çok kolay.

Kademeli Yapı

From simple HTML templates to powerful UI components

Progressive kelimesini Türkçe’ye çevirirken anlatılmak istenilenin farklı ihtiyaçlara uygun, farklı karmaşıklıklarda çözümler sunabildiği olduğunu düşünerek kademeli kelimesini seçtim.

Oluşturduğunuz dosya sadece bir HTML şablonu olabilir ya da state tutan zengin bir UI bileşeni yazabilirsiniz. Bu yalınlığa yakışacak şekilde isterseniz bileşenleri farklı dosyalarda .html, .js, .css veya bir arada .marko uzantılı olarak oluşturabilirsiniz. Özellikle .marko yazmak çok daha kolay ve zevkli diyebilirim. Oluşturduğunuz dosyada js, style ve html(template) bir arada bulunuyor. Yazdığınız js es6 destekli ve style yazarken çok kolay bir şekilde less ve sass desteği kazanıyor.

Güvenilirlik

Marko is powering high-traffic websites like ebay.com

Güvenilir olması önemli ve birçok kütüphane güvenilir 😆. Diğer yeni çıkan kütüphaneler ile karıştırılmamak için belirtmek zorunda hissettiklerini düşünüyorum. Bu konuda yapabileceğim bir yorumum yok. Firmamızın sitesini marko ile kodladık ve static olarak sunuyoruz. Henüz Marko kaynaklı bir sorun ile karşılaşmadık.

Kullanmadan önce bilsem hoş olurdu diyebileceğim bilgileri paylaşmaya çalıştım, bundan sonrası biraz daha teknik ve detaylı olacak.

Şurada mutlu bir kod parçacığı var

Talk is cheap. Show me the code. — Linus Torvalds

Burada sıfırdan bir proje oluşturup adım adım anlatmayacağım, bunu yapmak isterseniz dokümanları gerçekten başarılı. Yapacağım şey, yazdığım proje hakkında bilgilendirme yaparak kütüphane hakkında önemli bulduğum özellikleri anlatmak olacak.

Marko’nun bazı temel noktaları hakkında bilgi sahibi olursak, ilerideki konuları daha kolay anlatabileceğimi düşünüyorum.

Marko hem kolaylık hem de standart sağlamak için bazı ön tanımlı klasör ve dosya adları ile birlikte geliyor. Siz yine istediğiniz isimlendirmeyi verebilirsiniz ama çeşitli kolaylıklardan mahrum kalabilirsiniz.

Başlıca önemli klasör isimleri components ve routes.

Klasörler

Components

Yazacağınız bileşenleri koyduğunuz klasör burası. Size sağladığı tek ve kocaman bir artı var o da içindeki bileşenlerin otomatik olarak her yerde import etmeden kullanılabilir hale gelmesi. Yani aşağıdaki ağaçta gördüğünüz x bileşeni başka bir dosyanın içerisinde hiçbir ön tanımlama yapmadan kullanılabilir. Bu tarz bir kullanımın hem güzel noktaları var hem de eksikleri var.

Not: components klasörü içerisinde yazmadığınız bileşenleri kullanabilmek adına çok dertli olmayan basit bir yan yolu var ama insan bir kere iyiyi görünce bu kullanım göze batmaya başlıyor. Kullandığınız dosyadan kullanmak istediğiniz bileşene relative path vererek ulaşabiliyorsunuz.

Hemen bir örnek verelim, varsayalım yapı aşağıdaki ağaç şeklinde. Olabilecek ihtimallere göre bir tablo ile durumu anlatmaya çalışacağım.

Yapı

src/
├── components
│ ├── x.marko
│ ├── y.marko
│ └── z
│ ├── index.marko
│ ├── logo.svg
│ └── style.css
├── layouts
│ ├── a.marko
│ └── b
│ ├── index.marko
│ └── style.css
└── index.marko

Kullanım Şekli:

Routes

Routes klasörü size kolay bir şekilde sayfalarınızı yönetmeniz konusunda yardımcı oluyor. Ayrıca kendi alt klasörlerinin içindeki components klasörleri projenin geri kalanından bağımsız olarak o route içerisinde kullanılabilir oluyor.

src/
├── components
│ ├── x.marko
│ ├── y.marko
│ └── z
│ ├── index.marko
│ ├── logo.svg
│ └── style.css
├── routes
│ ├── a.marko
│ └── b
│ ├── index.html
│ ├── index.js
│ ├── components
│ │ ├── only4b.marko
│ └── style.css
└── index.marko

components altındaki bileşenler her yerde çağrılabilirken routes/b/components altındaki bileşenler sadece b içerisinde çağrılabilecektir. Tabi atlamamak gerekir <include(...)> tagini kullanarak yine her yerden erişilebilir. Bahsettiğimiz konu sadece otomatik keşif için geçerli.

Yukarıdaki ağaç yapısındaki bir projede, otomatik olarak bazı URL’lere cevap verecek bir uygulamamız oluşuyor.

Son olarak dikkatinizi çektiyse, bileşen ve rutlar hem klasör olabiliyor hem de dosya olabiliyor.

Syntax

Peki bu küçük mutlu kodları hangi fırçalar ile yaratıyoruz? Marko projenizde bir çok yapısal farklılığa izin veriyor fakat her zaman daha kolay ve daha basit bir yöntemi özendirerek bizi yönlendirmeye çalışıyor.

Template

Sitesine ilk girdiğinizde sizi kocaman bir şekilde Choose a syntax diye karşılıyor ve Marko’s concise syntax’ını kullanabilirsiniz diyor. Bahsettiği şey; düz <…> tagleri yerine, girinti (indentation) bazlı farklı bir yazım şekli kullanabilecek olmanız. Bu yeni yazım şekli;

Örnekler aşağıda, siz karar verin.

Ben yine sadeliği sevdiğimden ve sanırım değişiklik istediğimden ilk yazım şeklini kullanıyorum.

Component Yapısı

Bir diğer konu; bileşen yazımı. Bileşen yazarken 3 farklı kurgu yapabiliriyoruz.

├── components  
│ ├── x.marko # 1
│ ├── y # 2
│ │ ├── index.marko
│ │ ├── logo.svg
│ └── z # 3
│ ├── index.html
│ ├── index.js
│ └── style.css

Benim en sevdiğim 1 numaralı yöntem. Bileşen ile alakalı yan dosyalar var ise zorunlu olarak 2 numaraya başvuruyorum ama 3 numara gerçekten bazı sıkıntılar olduğuna işaret ediyor diyerek kullanmamaya çalıştığım bir yöntem. Korktuğum aslında fazla büyük bir bileşen yazmış olup o nedenle 3 farklı dosyaya bölme ihtiyacı hissetmiş olmak. Halbuki mutlu bir geliştirici; iyi senaryoda tek bileşeni 3 dosyaya değil, tek dosyalık 3 bileşene bölmeli diyerek spatulamız ile biraz ışık efekti yapıyoruz.

Bütün tavsiyelere uyduğunuzda elinizde dantel gibi bir kod oluyor. 😃

Detaylı bilgi için yine buraya bakabilirsiniz.

Component Lifecycle

Bildiğiniz üzere bileşenlerin kendi hayat döngüsüne ait çeşitli event’leri oluyor. Dokümanları gayet güzel açıklamış ama yine de biraz bahsetmek istiyorum. Marko 6 adet event tanımlıyor. Bunlar ve tetiklendiği zamanlar ;

Temel olarak bu eventleri dinleyebilmek için ön tanımlı isimlerde metodlarınız olmalı. on<İlk harfi büyük event ismi> . Bu eventleri yakalamanız zorunlu değildir, sadece gerektiğinde ekleyebilirisiniz.

class {
onCreate(input, out) { }
onInput(input, out) { }
onRender(out) { }
onMount() { }
onUpdate() { }
onDestroy() { }
}

Event’ler

Yalın bir şekilde işledikleri event mekanizmalarını çok beğendim. Son derece okunur ve kullanımı kolay olmuş. Üstelik öğrenmek toplam 10sn sürüyor 👶.

Çok basit bir sınıf üzerinden anlatayım isterseniz.

class {
setKeyword(e){
this.state.keyword = e.target.value;
this.state.timer = setTimeout(()=>this.emit("search", e.target.value ),400);
}
}
<input type="text" value=state.keyword on-input("setKeyword")/>

Yukarıdaki örnekte input içine verilmiş attributelarda on-input("setKeyword") kısmını göreceksiniz. Bu kod her input eventi tetiklendiğinde setKeyword metodunu çalıştır demek.

Dinlemek istediğiniz bütün event’lere çok kolay bir şekilde bağlanabiliyorsunuz. on-<event adı>("<method adı>") Aynı durum custom event'ler için de geçerli.

Diyelim 2 adet bileşenimiz var.

// child.marko
class {
setKeyword(e){
// do something
this.emit("search", e.target.value );
}
}
input type="text" value=state.keyword on-input("setKeyword")
//------------------------------------------------

// parent.marko
class {
searched(keyword){
this.state.keyword = keyword;
}
}
div
child on-search("searched")

Örnek kodda görebileceğiniz gibi ilk tanımladığım child.marko içerisinde bir input içerisinde bir listener var ve her girdidesetKeyword tetikleniyor. setKeyword içerisinde bir dizi işlem yapıldıktan sonra this.emit("search", e.target.value ); satırı ile bileşen search event'i fırlatıyor. parent.marko ise child bileşenini child on-search("searched")ile kullanmış. Yani child her search eventi fırlattığında, parent içerisindeki searched metodunu çalıştır.

Aynı şekilde child once-search("searched" yazmış olsaydık sadece ilk tetiklendiğinde çağrılacak, sonrakilerde çağrılmayacaktı.

Böylelikle 👇 👆 eventler hakkında herşeyi anlattık. Şaka şaka 😄! Detaylara kendi kaynaklarından ulaşabilirsiniz.

Style

Bileşen ile stili isterseniz tek dosyada, isterseniz farklı dosyalarda yazarak ilerleyebiliyorsunuz. Farklı dosya olarak yazarsanız uzantıları yöneterek, tek dosyada yazarsanız ise style.less ya da style.sass diye belirterek istediğiniz preprocessor desteğini alabilirsiniz. Dokümanlarda çok işlenmiş bir konu olmamakla beraber, anlatabileceği fazla bir detayı yok. Sadece şunu bilmenizde fayda var, scoped olarak yazamıyorsunuz. Bu nedenle isimlendirmelere ya da sınıf yapılarına dikkat etmenizi öneririm.

class {}
style.less {
#search-box {
width:100%;
height:30px;
border:1px @borderColor solid;
font-size: 30px;
padding: @padding;
color:#333;
}
}
div#search-box type="text"

Genel olarak dikkatimi çeken noktalarda bilgi aktarmaya çalıştım. Bu kadar mı, tabi ki değil ama genel hatları ile bilgi sahibi olabilmek ve yumuşak bir giriş yapmak için yeterli olduğunu düşünüyorum. Devamını isterseniz haber vermekten çekinmeyin 🎉.

Esen kalın.

info@fill-labs.com clutch Clutch.co Twitter Twitter Instagram Instagram Linkedin Linkedin
©Fill-labs 2024 Legal Notice - Data protection - Use of cookies