Slide 1

Slide 1 text

Modern JavaScript Mimarisi Rameş Aliyev

Slide 2

Slide 2 text

Modern JavaScript Mimarisi • Katmanları Ayırmak • Bileşenlere Bölmek • Otomasyon • Paket Yönetimi • Modülerlik • Geleceğe Hazır Olmak Modern bir JavaScript mimarisi özet olarak bu sayılan parçalar ve yaklaşımların bir araya getirilmesiyle oluşuyor.

Slide 3

Slide 3 text

Katmanları Ayırmak

Slide 4

Slide 4 text

• Veri • Görünüm • İşleyiş Katmanları Ayırmak Yazılım mimarisindeki en bilinen yaklaşım, yazılımın katmanlarını birbirinden ayırmaktır. Buna göre veri katmanı, görünüm ve işleyiş katmanları birbirinden ayrılmalıdır. Görünüm katmanı kullanıcı girdilerini işleyiş katmanına iletmek, ve o anki verinin ekran üzerinde kullanıcıya sunulması ile görevlidir. Veri katmanı herhangi bir alanın o anki verisini tutmaktadır. İşleyiş katmanı ise kullanıcıdan gelen aksiyonlara göre veri katmanı üzerinde manipulasyonlar yapar.

Slide 5

Slide 5 text

• Model • View • Controller Bu katmanları ayırma yaklaşımının en bilinen deseni MVC’dir. Veri=Model, Görünüm=View, İşleyiş=Controller Katmanları Ayırmak

Slide 6

Slide 6 text

Katmanları Ayırmak MV* Desenleri • MVC by Trygve Reenskaug - 1979 • MVP by Taligent - 1990 • MVVM by John Grossman - 2005 • MV-Whatever… Angular MV* desenleri 79’dan beri kullanılmaktadır.

Slide 7

Slide 7 text

CONTROLLER MVC VIEW MODEL Veri Okur Değişiklikleri Bildirir Değiştirir Çağrıları İletir MVP VIEW PRESENTER MODEL MVVM Değiştirir Günceller Çağrıları İletir Değişiklikleri Bildirir VIEW VIEWMODEL MODEL Değiştirir Komutlar Değişiklikleri Bildirir Data Bindings Katmanları Ayırmak MV* Desenleri MV* desenleri aralarında küçük ancak önemli farklar bulundururlar. Bu şemada dikkat edilmesi gereken ilk şey MV* desenlerinde katmanlar arasında çift yönlü iletişim bulunur. Bilinmesi gereken bir başka şey de, bu MV* desenleri çoğu büyük şirket dolasıyla Frameworkler tarafından da farklı şekilde yorumlanır. Bir MV* desenini öğrenip onu uyguladığını söyleyen Framework kullanmaya başladığınızda öğrendiğiniz desen ile Framework’ün işleyişinin benzeşmediğini görebilirsiniz…

Slide 8

Slide 8 text

Slide 9

Slide 9 text

CONTROLLER MVC VIEW MODEL MODEL MODEL MODEL MODEL VIEW VIEW VIEW VIEW Katmanları Ayırmak Sorun Facebook’un ağzından: MVC deseni ile ilgili sorun birbirini kullanan Model ve View’lerin zaman içerisinde çok karışık hale gelmesi ve yukarıdaki gibi bir şemaya neden olması. Bu şemada bir sonsuz döngü olup olmadığı, ya da bir modele gelecek bir tetiklemenin sonunun nerede biteceğini anlamak zordur. Katmanlar birbirleriyle çift yönlü iletişim kurmaktadırlar.

Slide 10

Slide 10 text

FLUX Katmanları Ayırmak Çözüm

Slide 11

Slide 11 text

ACTION COMPONENT DISPATCHER STORE Katmanları Ayırmak Flux Buna çözüm olarak, Facebook “Flux” mimarisini sunuyor. Flux mimarisindeki en önemli şey; akışın tek yönlü olması. Sisteme gelen bir aksiyon (kullanıcı girdisi ya da sunucudan gelen yeni veri) Dispatcher üzerinden geçerek Store’lara dağılıyor. Store’lar bu aksiyona göre varsa kendi içlerinde değişiklik yapıp Componentlerin dinlediği event’leri tetikliyorlar. Componentler yeni veri ile kendilerini yeniden render ediyorlar.

Slide 12

Slide 12 text

ACTION COMPONENT DISPATCHER STORE Daha sonra Component’ler yeni aksiyon yayabilirler. Component’lar aynı zamanda kullanıcı girdilerini dinlerler ve gelen girdilere göre aksiyon yayarlar. Katmanları Ayırmak Flux

Slide 13

Slide 13 text

Flux Katmanları Ayırmak Nereden Çıktı? + Jon Snow Where are you Jon? Brb. Peki ya Flux neden çıktı, nerden çıktı? Neden Facebook ekibi böyle bir şey geliştirmeye ihtiyaç duydu?

Slide 14

Slide 14 text

-­‐ Yeni  mesaj  alındığında:   -­‐ Yeni  Mesajı  ChatTab’e  ekle. Flux Katmanları Ayırmak Nereden Çıktı? Başlangıçta, sadece bir ChatTab vardı, ve yeni mesaj alındığında yapılması gereken işlem basitti. Yeni Mesajı al ve ChatTab’e ekle. + Jon Snow Where are you Jon? Brb.

Slide 15

Slide 15 text

1 Daha sonradan üst bar’a bir “GörülmemişSohbetSayacı” eklendi. Artık yeni bir mesaj alındığında aynı zamanda bir sayacı arttırmak, ve ChatTab’e focus olunca geri azaltmak gerekiyordu. Flux Katmanları Ayırmak Nereden Çıktı? + Jon Snow Where are you Jon? Brb. -­‐ Yeni  mesaj  alındığında:   -­‐ GörülmemişSohbetSayısı++   -­‐ Yeni  Mesajı  ChatTab’e  ekle.   -­‐ ChatTab  focus  olunca;  GörülmemişSohbetSayısı-­‐-­‐

Slide 16

Slide 16 text

Flux Katmanları Ayırmak Nereden Çıktı? 1 + Jon Snow Where are you Jon? Brb. Jon Snow Brb. Tyrion Lannister I should quit drinking. Arya Stark I can’t see you anymore. Khaleesi I hate teens. Cersei Lannister I’ll show them. Stannis Barathe… Lets burn the city. Jon Snow Brb. Samwell Tarly Where are you Jon? En son eklenen “Ana Mesajlar Görünümü” ile ise handler methodu iyice karışık bir hale geldi.

Slide 17

Slide 17 text

Jon Snow Brb. Tyrion Lannister I should quit drinking. Arya Stark I can’t see you anymore. Khaleesi I hate teens. Cersei Lannister I’ll show them. Stannis Barathe… Lets burn the city. Jon Snow Brb. Samwell Tarly Where are you Jon? -­‐ Yeni  mesaj  alındığında:   -­‐ GörülmemişSohbetSayısı++   -­‐ Yeni  Mesajı  ChatTab’e  ekle.   -­‐ Açıksa  Mesajı  Ana-­‐Mesajlar-­‐Görünümü’ne  ekle.   -­‐ ChatTab  veya  ana  mesajlar  penceresi  focus  olunca;
 GörülmemişSohbetSayısı-­‐-­‐ Flux Katmanları Ayırmak Nereden Çıktı? 1 + Jon Snow Where are you Jon? Brb. Artık eğer açıksa alınan mesajı “Ana Mesajlar Görünümü”ne de eklemek gerekiyordu. Ve Okunmamış mesajlar sayısını bir azaltmak için. ChatTab’in ya da “Ana Mesajlar Görünümü”nün focus olması dinleniyordu.

Slide 18

Slide 18 text

ACTION HANDLER ANA MESAJ GÖRÜNÜMÜ CHAT TAB GÖRÜLMEMİŞ SOHBETLER SAYACI DIŞ KONTROL Flux Katmanları Ayırmak Nereden Çıktı? Bu kodu bir şema üzerinden inceleyecek olursak, bir dış kontrolcü tarafından içerikleri değiştirilen üç veri alanından bahsedebiliriz. Kendi iç tutarlılıklarını sağlayamayan üç model.

Slide 19

Slide 19 text

İÇ KONTROL ACTION ANA MESAJ GÖRÜNÜMÜ CHAT TAB GÖRÜLMEMİŞ SOHBETLER SAYACI Yeni Mesajı Ekle Yeni Mesajı Ekle ? Flux Katmanları Ayırmak Nereden Çıktı? Bu sorunu düzeltmek için, aradan handler’ı kaldırıp, aksiyonun doğrudan veri tutuculara gelmesini, ve her veri tutucunun gelen aksiyona göre kendini düzenlemesini sağlıyoruz. Yalnız hala bir sorun var, Görülmemiş Sohbetler Sayacı gelen yeni mesajlarda kendini bir arttırabilir ancak ne zaman azaltacak?

Slide 20

Slide 20 text

İÇ KONTROL ACTION ANA MESAJ GÖRÜNÜMÜ CHAT TAB GÖRÜLMEMİŞ SOHBETLER SAYACI Yeni Mesajı Ekle Yeni Mesajı Ekle Mesajın Geldiği Sohbeti Görülmemişler Listesine Ekle Flux Katmanları Ayırmak Nereden Çıktı? Bunun için ilk yapılması gereken, “Görülmemiş Sohbetler Sayacı”nda sayı değil, sohbetleri tutmak. Bu sayede bir sohbet görüldü olarak işaretlenebilir. Sayı tutmanın kırılgan tarafı şu; artık sohbet iki farklı alan üzerinden görülebilir. Hem ChatTab, hem de Ana Mesajlar Görünümü. Diyelim ki bir mesaj geldi. Sayacı bir arttırdık. Sonra bir mesaj daha geldi. Şimdi sayacımız 2 değerini gösteriyor. Aynı mesajı hem ChatTab hem Ana Mesajlar Görünümünden açtığımızda ne olur? İki mi azalır? Yoksa bunu kontrol etmek için biraz daha mı kod yazmamız gerekir? Tabiki önlenebilir, ancak sayı tutmak yerine sohbetlerin kendisini sayaçta tutup, okundu okunmadı olarak işaretlersek, hem daha yalın bir kodumuz olur, hem de olası bir çok bugdan kurtulmuş oluruz.

Slide 21

Slide 21 text

ACTION ANA MESAJ GÖRÜNÜMÜ CHAT TAB GÖRÜLMEMİŞ SOHBETLER SAYACI İÇ KONTROL Yeni Mesajı Ekle Yeni Mesajı Ekle Mesajın Geldiği Sohbeti Görülmemişler Listesine Ekle Görüldü Olarak İşaretle Flux Katmanları Ayırmak Nereden Çıktı? Yeni yapımızla birlikte, artık “Görüldü Olarak İşaretle” aksiyonu birden fazla çalışsa bile; hep aynı sohbeti görüldü olarak işaretleyeceği için, bir buga neden olmayacak. Olası bugları oluşmadan engelledik.

Slide 22

Slide 22 text

ACTION SOHBETLER MESAJLAR GÖRÜLMEMİŞ SOHBETLER TÜM YAPI CHAT TAB VIEW MESSAGE VIEW UNSEEN COUNTER GÖRÜLDÜ OLARAK İŞARETLE GÖRÜLDÜ OLARAK İŞARETLE Flux Katmanları Ayırmak Nereden Çıktı? Biraz uzaklaşıp büyük fotoğrafa bakacak olursak, gelen aksiyon üç adet veri tutucumuzun kendilerini düzenlemesini sağlıyor. Sonra verinin değiştiğini öğrenen View’lar, kendilerini re-render ediyorlar. Ve kullanıcıdan gelecek aksiyonu bekliyorlar. Kullanıcı bu alanlara focus yaparsa; “Görüldü olarak İşaretle” aksiyonunu yayıyorlar. Bu aksiyon “Görülmemiş Sohbetler” veri tutucusunu ilgilendirecek, ve o da “Unseen Counter”’ın re-render olmasını sağlayacak yeni bir event (olay) yayarak, Unseen Counter View’i tetikleyecek.

Slide 23

Slide 23 text

ACTION STORE COMPONENT GENEL YAPI Flux Katmanları Ayırmak Nereden Çıktı? Özetle; Veri tutucularımız: Store. View’larımız Component’lerimiz oluyor. Ve uygulamamızdaki akış tek bir yöne doğru akıyor.

Slide 24

Slide 24 text

ACTION COMPONENT DISPATCHER STORE Katmanları Ayırmak Flux Maddelerimizi sayalım: - Veriler Store’da tutuluyor ve veri mutasyonu sadece bir aksiyon tarafından yapılabiliyor. - Akışımız tek yönlü, başlangıcı ve ilerileyişi daha kolay takip edebiliyoruz. - Component’ler aksiyonları değil Store’lar üzerindeki değişimleri dinliyorlar.

Slide 25

Slide 25 text

ACTION COMPONENT DISPATCHER STORE Katmanları Ayırmak Flux Peki ya Dispatcher’lar? Dispatcher’ların tek bir işi var; Bir aksiyon tüm Store’lar tarafından işlenmeden önce yeni bir aksiyonun işlenmesini engellemek. Yani Dispatcher’ın tek yaptığı kendisine gelen aksiyonları Store’lara iletmek ve işlenmesinin bitmesini beklemek. Bu sırada gelen aksiyonları bekletmek.

Slide 26

Slide 26 text

ACTION COMPONENT DISPATCHER STORE {   type:  “UPDATE_TEXT”   data:  {…}   } Katmanları Ayırmak Flux Üstünden geçecek olursak: Action: İçinde bir adet tip ve bir adet veri barındıran bir nesneden öte bir şey olmayan, sistem üzerinde meydana gelen herhangi bir olayı gösteren bir sinyaldir.

Slide 27

Slide 27 text

ACTION COMPONENT DISPATCHER STORE -­‐ Store’lara  ilet.   -­‐ Yolu  tıka. Katmanları Ayırmak Flux Dispatcher: Aldığı Action’ları Store’lara iletir, Store’lar bu aksiyonu tamamlayana kadar başka aksiyonların beklemede kalmasını sağlar.

Slide 28

Slide 28 text

ACTION COMPONENT DISPATCHER STORE -­‐ Aksiyonları  dinle.   -­‐ İşini  gör.   -­‐ Olay  yay. Katmanları Ayırmak Flux Store: Verileri tutmakla ve düzenlemekle sorumludur. MV*’deki Model’den farklı olarak; Model domain- specific (yani bir alana özgü, örneğin bir resim galeriniz varsa, o galerideki her bir resme ait veri) veri tutarken, Store’lar bu konuda daha esnek kullanılabilirler.

Slide 29

Slide 29 text

ACTION COMPONENT DISPATCHER STORE -­‐ Kendini  düzelt.   -­‐ Hareket  bekle.   -­‐ Aksiyon  yarat. Katmanları Ayırmak Flux Component: Store’da tutulan o anki verinin ekran üzerindeki görünümünü sağlamakla görevlidir. Aynı zamanda kullanıcının etkileşimini Aksiyon olarak Dispatcher’a gönderir.

Slide 30

Slide 30 text

STORE? ACTION? DISPATCHER? COMPONENT? Ama sanki bütün bunlar bir yerden tanıdık gibi?

Slide 31

Slide 31 text

EVENT VIEW CONTROLLER MODEL ? ACTION COMPONENT DISPATCHER STORE + Katmanları Ayırmak Flux Pete Schirmer’in Facebook’un Youtube’da yayınladığı sunuma yaptığı yorumda şöyle diyor: “Bir şey mi kaçırdım? MVC’yi başından beri yanlış anlayıp daha iyi bir sinyal yönetimiyle baştan icat etmişler gibi. Özetle Event=Action, Dispatcher=Controller, Store=Model, Component=View gibi?”
 Dispatcher=Controller benzetmesi hariç diğerlerinin (nerdeyse) birbirinin karşılığı olarak sayılabilir.

Slide 32

Slide 32 text

github.com/facebook/flux github.com/spoike/refluxjs github.com/deloreanjs/delorean github.com/TuxedoJS/TuxedoJS github.com/addthis/fluxthis Katmanları Ayırmak Flux

Slide 33

Slide 33 text

Bileşenlere Bölmek

Slide 34

Slide 34 text

ACTION COMPONENT DISPATCHER STORE Bileşenlere Bölmek Bileşen, bir önceki Flux şemamızdaki Component’ten başkası değil. Şimdi onun iç yüzünü inceleyeceğiz.

Slide 35

Slide 35 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search…
   
     
  • Jon  Snow
  •  
  • Tyrion  Lannister
  •  
  • Arya  Stark
  •  
  • Khaalesi
  •  
  • Cersei  Lannister
  •  
 
[   {   name:  “Jon  Snow”,   status:  “Online”,   client:  “web”   },   {   name:  “Tyrion  Lannister”,   status:  “idle”,   client:  “web”   },   {   name:  “Arya  Stark”,   status:  “Online”,   client:  “Mobile”   },     ...     ] Bileşenlere Bölmek Sorun Ekranımızı bir çok büyük parçalara böldük. Bu parçaları bileşenlerimiz olarak kabul ediyoruz. Bunlardan biri ChatTab. ChatTab bileşenimizi oluşturacak veriyi biliyoruz. Hatta bu bileşenimizi oluşturacak HTML kodlarımız ve bileşenimizin görünümü de mevcut. Peki bu bileşenimizin kendisi nasıl oluşturmalı?

Slide 36

Slide 36 text

REACT Bileşenlere Bölmek Çözüm

Slide 37

Slide 37 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… React Bileşenlere Bölmek Çözüm Çözüm şu: bileşenimizi bölebildiğimiz yere kadar başka bileşenlere böleceğiz. Kural şu: Her bileşen sadece bir işten sorumlu olmalı. Bu mantıkla, bileşenimizi daha ufak parçalara bölelim. (Bir not: Elinizde bir PSD varsa, Layer’larına bakın, belki de tasarımcımız iyi bir layer düzeni kurguladıysa, bileşenlerimiz hazır olabilir. Bu belki de bileşenlere isim verme sürenizi kısaltır.)

Slide 38

Slide 38 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… React Bileşenlere Bölmek Çözüm Arama inputumuz kesinlikle bir bileşen.

Slide 39

Slide 39 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… React Bileşenlere Bölmek Çözüm Kullanıcı listemizin de ondan aşağı kalır bir hali yok bileşen olma konusunda.

Slide 40

Slide 40 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… React Bileşenlere Bölmek Çözüm Ancak liste’nin her bir elemanı da bir bileşen. Her eleman üzerindeki veriyi göstermekle yükümlü. Liste ise onları listelemekle. Bu iki iş yapar.

Slide 41

Slide 41 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… ChatTab SearchBar UserList UserListItem React Bileşenlere Bölmek Çözüm Bileşenlerimizi bölmeyi bitirince, geriye kalan onları isimlendirmek oluyor.

Slide 42

Slide 42 text

                React Bileşenlere Bölmek Çözüm Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… ChatTab SearchBar UserList UserListItem Sıra bileşenlerimizi ayrı ayrı geliştirmeye geldi. İster dışardan içeri, ister içerden dışarı sırayla geliştirebilirsiniz. Büyük projelerde içeriden dışarıya yani küçükten büyüğe başlamak tavsiye edilir. Bu bileşenlerin dizilimi solda gözüktüğü gibi olacaktır. Burada dikkat edilmesi gereken React’ta veri dıştan içe doğru gelir. React’ta bu bileşenlerin iki tür veri kaynakları olur. Props ve State.

Slide 43

Slide 43 text

PROPS STATE React Bileşenlere Bölmek State - Props Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… Peki ne ola ki bu State ve Props? Çok basit. Props bildiğimiz property. Bir bileşenin property’ler üzerinden aldığı verilere denir. Props’lar değişmez. En azından bileşenin kendisi tarafından. Bileşene o props’ları kim veriyorsa, onun kontrolündedir. State’ler ise değişir. Bir bileşenin kendisine aittir.

Slide 44

Slide 44 text

• Orijinal Kullanıcı Listesi Bileşen Verileri • Arama Kelimesi • Filtrelenmiş Kullanıcı Listesi React Bileşenlere Bölmek State - Props Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… O zaman bileşenlerimizin üzerindeki props ve state’leri bulalım. İlk iş olarak bileşenlerimizde kullanılacak verilerin listesini çıkarmakla başlayalım. Çıkardık bile! Kullanıcı listemiz, arama inputuna yazdığımız arama kelimesi ve kullanıcı listemizin bu arama kelimesi ile filtrelenmiş hali, bize gereken veriler bunlar.

Slide 45

Slide 45 text

• Parent’tan property ile mi alındı? State mi Props mu? • Değişecek bir şey mi? • Başka bir Props ya da State vasıtasıyla
 tekrar oluşturulabilir mi? React Bileşenlere Bölmek State - Props Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… Peki bu verilerin hangisi State hangisi Props? Bunun belirlemek için yukarıdaki soruları tek tek her biri için soracağız. Property ile alınıyorsa props’tur. Alınmıyorsa ve değişmesi gereken bir veriyse state’tir. Başka bir props ya da state vasıtasıyla tekrar oluşturulabiliyorsa ikisi de değildir.

Slide 46

Slide 46 text

• Orijinal Kullanıcı Listesi Bileşen Verileri • Arama Kelimesi • Filtrelenmiş Kullanıcı Listesi PROP STATE … React Bileşenlere Bölmek State - Props Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… Soruları tek tek sorduk. Orijinal kullanıcı listemizi ChatTab bileşenimize property olarak alacağız, o bir props. Arama kelimesi arama inputuna kullanıcının girdiği yazı olacak. Değişecek, o bir state. Peki ya filtrelenmiş kullanıcı listesi? Cevap: Ne state ne de props. Çünkü iki farklı verinin birleşimi ile oluşuyor. Kendi başına bir varlığı yok.

Slide 47

Slide 47 text

State Kime Ait? 1. Bu state’i kullanan componentleri bul. 2. Bu componentlerin ortak parent’ına ait. 3. Ortak parent yoksa, state için ortak
 parent yarat. React Bileşenlere Bölmek State - Props Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… State’lerimizi bulduk. Fakat bulmamız gereken bir şey daha var. Bu state’ler hangi bileşen üzerinde barınacaklar? Bunun için yapmamız gerekenler yukarıdaki gibi. “Arama Kelimesi” state’i kime ait?

Slide 48

Slide 48 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… ChatTab SearchBar UserList UserListItem Arama Kelimesi React Bileşenlere Bölmek State - Props Arama Kelimesi’ni yaratacak olan bileşen SearchBar. Arama Kelimesini kullanarak Orijinal Kullanıcı Listesini filtreleyecek ve onu kullanacak bileşen ise UserList. Bu durumda bu state ikisinin ortak parent’ına ait. Yani ChatTab’e.

Slide 49

Slide 49 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… ChatTab SearchBar UserList UserListItem React Bileşenlere Bölmek Data Flow Söylememiz gereken iki şey daha var. Birincisi veri akışı. Veri akışı React’ta dışarıdan içeriye oluyor. Dışardaki bileşen kendi içinde başka bir bileşen yaratırken ona propslar vasıtasıyla veri gönderebiliyor; ancak içerdeki bileşen bir dışındaki bileşenin state’lerini düzenleyemiyor.

Slide 50

Slide 50 text

ChatTab SearchBar UserList UserListItem handleUserInput() onUserInput(props.handleUserInput()) React Bileşenlere Bölmek Inverse Data Flow E ama burada bir sorun var? “Arama Kelimesi” ChatTab’e ait bir state dedik. Ve SearchBar’ın bunu değiştirmesi gerekiyor. Ancak doğrudan erişip değiştiremiyor. E nasıl olacak? Bunun için ChatTab SearchBar’a props’lar üzerinden bir method yolluyor. SearchBar kendi üzerindeki inputa yeni veri girişi olduğunda; ChatTab’ten aldığı bu fonksiyonu tetikliyor. Böylece ChatTab kendi state’ini kendi düzenliyor. Olması gerektiği gibi.

Slide 51

Slide 51 text

ChatTab SearchBar UserList UserListItem handleUserInput() onUserInput(props.handleUserInput()) Re-­‐Render  etmesi  gerektiğini  nerden  bilecek? React Bileşenlere Bölmek Inverse Data Flow Tamam, ChatTab state’ini değiştirdi. Peki UserList kendini yeniden render etmesi gerektiğini nerden bilecek? React’ın çalışma mantığı da bu, bir state değiştiğinde, o state’in ait olduğu bileşenin içinde kalan tüm bileşenlerin render methodlarını tetikliyor. Ve geriye döndürdükleri HTML çıktısında değişim olup olmadığına bakıyor. Eğer değişim varsa, bu bileşenleri yeniden DOM’a render ediyor.

Slide 52

Slide 52 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… React Bileşenlere Bölmek Data Binding Söylememiz gereken ikinci şey ise one-way databinding. Öncelikle two-way databinding’i açıklayalım. Verinizi tutan Store’unuz ve onu gösteren hatta belki de yaratan bir bileşeniniz var diyelim. Eğer aralarında two-way databinding olsaydı, bu şu demek olurdu: State’de veri değişince anında ekranda gözüken veri de değişecek. Aynı şekilde eğer kullanıcı bu veriyi ekran üzerinde örneğin bir input üzerinde değiştirirse, bu sefer de anında State üzerinde tutulan veri güncellenecek. Peki ya bunun tek yönlüsü yani one-way databinding? Ekran üzerindeki değişimin anında otomatik olarak State’i düzenlemesini unutun. Sadece State’teki düzenleme ekrana yansır, tersini ise sizin kontrol etmeniz gerekir. İşte buna one-way databinding denir. React da bu şekilde çalışır. Biz de bu nedenle az önceki gibi inputta bir şey değişince method tetikleriz.

Slide 53

Slide 53 text

              React.createElement(ChatTab,  {users:  userList},     React.createElement(SearchBar,  null),     React.createElement(UserList,  null,     React.createElement(UserListItem,  {name:  "John  Snow"}),     React.createElement(UserListItem,  {name:  "Tyrion  Lannister"}),     React.createElement(UserListItem,  {name:  "Khaleesi"})   )   ) React Bileşenlere Bölmek JSX JSX. React’ın dili. Gözünüzde büyütmeye gerek yok. Çünkü biz onu React için kullanırken sadece yukarıdaki gibi işleri kolaylaştırmaya yarıyor. Dilerseniz JSX kullanmayabilirsiniz. Ama bu kodlarınızı sağdaki gibi yazmanız gerektiği anlamına gelecek. Bu nedenle tavsiye edilir.

Slide 54

Slide 54 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Cersei Lannister Web React Bileşenlere Bölmek Render Sorunu React’ın render mantığından bahsettik. ChatTab üzerindeki bir state değiştiğinde, tüm child componentlerinin render edecek, ve render methodlarından dönen HTML’lerde bir değişiklik olup olmadığına bakacak. Değişiklik varsa değişikliği DOM’a uygulayacak. Peki React bunu nasıl yapıyor? Daha da önemlisi neden yapıyor? Bunun için önce başımızın belası DOM Render Sorununu ele alalım.

Slide 55

Slide 55 text

[   {   name:  “Jon  Snow”,   status:  “Online”,   client:  “web”   },   {   name:  “Tyrion  Lannister”,   status:  “idle”,   client:  “web”   },   {   name:  “Arya  Stark”,   status:  “Online”,   client:  “Mobile”   }   ] Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Cersei Lannister Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Cersei Lannister React Bileşenlere Bölmek Render Sorunu Diyelim ki bir verimiz var ve bu verimizden bir bileşen oluşuyor.

Slide 56

Slide 56 text

- Tyrion offline oldu. - Khaalesi online oldu. - Cersei online oldu. - Arya offline oldu. - Jon idle oldu. - Jon Mobile oldu. React Bileşenlere Bölmek Render Sorunu Zaman içinde kişi listemizde bu değişiklikler meydana geliyor.

Slide 57

Slide 57 text

[   {   name:  “Jon  Snow”,   status:  “Online”,   client:  “web”   },   {   name:  “Tyrion  Lannister”,   status:  “idle”,   client:  “web”   },   {   name:  “Arya  Stark”,   status:  “Online”,   client:  “Mobile”   }   ] [   {   name:  “John  Snow”,   status:  “Idle”,   client:  “mobile”   },   {   name:  “Khaalesi”,   status:  “Online”,   client:  “web”   },   {   name:  “Cersei  Lannister”,   status:  “Online”,   client:  “Web”   }   ] React Bileşenlere Bölmek Render Sorunu Bu değişiklikler sonucunda veri yapımız yukarıdaki hale geliyor.

Slide 58

Slide 58 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Cersei Lannister Jon Snow Mobile Khaalesi Web Cersei Lannister Web Arya Stark Tyrion Lannister Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Cersei Lannister Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Cersei Lannister React Bileşenlere Bölmek Render Sorunu Bu değişiklikler sonucunda yeni görünümümüz yukarıdaki gibi olmalı. Çok eskiden olsa bu değişiklikleri DOM üzerinde tek tek uygulardık. Daha sonra hayatımıza Template’ler girdi. Artık değişikliklerde tüm görünümü render ediyorduk. Tüm görünümü baştan render etmenin dezavantajı; birincisi değişecek şey çok küçük bile olsa her şeyi baştan yapmak, ikincisi DOM üzerinde işlem yapmak her zaman pahalıdır, son olarak da baştan render edilecek alanla kullanıcı o an etkileşim içindeyse, örneğin scroll ediyorsa, re-render edildiğinde konumunu kaybedecektir.

Slide 59

Slide 59 text

VIRTUAL DOM React Bileşenlere Bölmek Render Sorunu Çözümü Bunun için React Virtual Dom dediği bir yapı kullanır. Yani sanal, gerçek olmayan DOM.

Slide 60

Slide 60 text

FARKINI ALIR Jon Snow Mobile Khaalesi Web Cersei Lannister Web Arya Stark Tyrion Lannister Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Cersei Lannister Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Cersei Lannister React Bileşenlere Bölmek Virtual DOM React; bileşenin değişiklik yapılmadan önceki görünümünü Virtual DOM üzerinde tutar. Daha sonra değişikliklerin uygulanmış halini de Virtual DOM’da başka bir yerde yaratır. Daha sonra bu iki görünümün birbirinden farklı olan taraflarını bulur. Ve sadece bu farklılıkları gerçek DOM’a uygular.

Slide 61

Slide 61 text

     
  •   Jon  Snow  
  •  
  •   Tyrion  Lannister  
  •  
  •   Arya  Stark  
  •  
  •   Khaalesi  
  •  
  •   Cersei  Lannister  
  •  
     
  •   Jon  Snow  
  •  
  •   Khaalesi  
  •  
  •   Cersei  Lannister  
  •  
  •   Arya  Stark  
  •  
  •   Tyrion  Lannister  
  •  
React Bileşenlere Bölmek Virtual DOM Soldaki değişiklik yapılmadan önceki HTML çıktı, sağdaki ise State’ler değiştirildikten sonra ChatTab bileşeninin child bileşenlerinin render ederek oluşturduğu yeni çıktı. React sadece ikisi arasındaki farkları (yeşil renktekiler) alacak ve bu farkları DOM’a uygulayacak.

Slide 62

Slide 62 text

Otomasyon

Slide 63

Slide 63 text

CSS CSSLINT AUTOPREFIXER MINIFY main.scss main.min.css CONCAT JSCS MINIFY stores/*.js components/*.js app.js main.min.js JSHINT Otomasyon Sorun Geliştirme yaparken sürekli yapmak zorunda olduğunuz angarya işler mutlaka vardır. Dosyaları compile etmek, kontrol etmek, sıkıştırmak, üzerinde belli başlı düzenlemeler yapmak, taşımak, silmek ve dahası. Tüm bu işleri elle yapmak, işler kısa bile sürse yorucu ve gereksiz. Adı üzerinde: angarya iş.

Slide 64

Slide 64 text

SASS CSS CSS CSS LINT CSS AUTOPREFIXER CSS MINIFY *JS CONCAT JS JSCS JS JSHINT JS MINIFY Otomasyon Çözüm Yaptığınız bu angarya işlere bakarsanız, aslında bu ardı sıra yaptığınız işler parçalara bölünebilirler. Bu her parça “iş”’i yaptırabileceğiniz otomasyon yapıları mevcut.

Slide 65

Slide 65 text

Otomasyon Çözüm Bu yapılardan iki tanesi Grunt ve Gulp. İkisi de temelde “görev yönetici” olarak çalışır. Onlara verdiğiniz görevleri sırasıyla yerine getirirler. Bu görevler programlanabilen her şey olabilir. Grunt ve Gulp görevleri yaptırmak için alt yapı sunarlar. Esas görevleri yapan üzerlerine yazılmış pluginlerdir. Otomasyon için Grunt/Gulp kullanmanın diğer bir yararı da taşınabilir olmalarıdır. Her ikisi de (Grunt için grunfile.js Gulp için gulpfile.js) birer config dosyası ile çalışırlar. Bu dosya proje klasörünüzde yer aldıkça; aynı otomasyon her yerde çalıştırılabilir. GRUNT GULP

Slide 66

Slide 66 text

• Dosya tabanlı. • Ram Tabanlı. grunt.initConfig({          jshint:  {              files:  ['src/**/*.js']          },          watch:  {              files:  [‘src/**/*.js’],              tasks:  ['jshint']          }   }); gulp.task('scripts',  ['clean'],  function()  {      return  gulp.src(paths.scripts)          .pipe(sourcemaps.init())          .pipe(coffee())          .pipe(uglify())          .pipe(concat('all.min.js'))          .pipe(sourcemaps.write())          .pipe(gulp.dest('build/js'));   }); Otomasyon Grunt / Gulp Aynı işi de yapıyor olsalar, yapış biçimlerinde küçük farklılıklar bulunur. Öncelikle Grunt dosya tabanlı çalışır, her yürüttüğü görevden sonra dosyayı kaydeder. Bir sonraki görevde geri açar ve yeni görevi uygular. Gulp ise görevleri yerine getirirken dosya içeriklerini RAM üzerinde saklar. Bu performans üstünlüğü sağlar. Bir diğer fark da Grunt’ın config dosyası daha çok “config” dosyasına benzerken, Gulp’ınki daha çok bir script gibidir. Bu da bir tercih nedeni olabilir.

Slide 67

Slide 67 text

Paket Yönetimi

Slide 68

Slide 68 text

Kütüphaneler Framework’ler APP Bileşenler Araçlar Paket Yönetimi Sorun Projelerimiz, genelde bir çok parçadan oluşurlar. En önemli parça projenin kendisi yani çekirdeğidir. Bunun yanında ek parçaları vardır. Bunlar projelerimizde kullandığımız kütüphaneler, çatılar, araçlar ve dışardan aldığımız bileşenler olabilir. Çekirdek hariç diğer parçalara “paket” adı veririz, ve onları yükleme, güncelleme, silme, taşıma işlemlerini kolay yönetilir hale getirmemiz gerekir. Projeleri bilgisayarımızdan sunucuya taşırken yanında bu paketleri de elle taşımamalı, ya da paketlerin kurma/ silme işlerini elle yapmamalıyız.

Slide 69

Slide 69 text

NPM BOWER npmjs.com bower.io package.json bower.json node_modules bower_components Paket Yönetimi Çözüm Yine iki çözümümüz var. Front-End için BOWER, Sunucu veya tarayıcı taraflı JavaScript için çoğunlukla NPM. (Bazı paketler her ikisinde de bulunabilir.) Her ikisi de bir config dosyası (NPM package.json ve BOWER bower.json) yaratır ve yüklediğiniz paketlerin bilgisi bu dosyalarda saklanır. Projenizi taşırken tek yapmanız gereken config dosyalarının root klasöründe olduğundan emin olmak. Daha sonra tek komut ile tüm bağımlılıkları yükleyebilirsiniz. NPM paketlerini root klasöründe node_modules, BOWER ise bower_components altına yükler. Bu klasörler çoğunlukla versiyon kontrol sistemlerine dahil edilmezler. (Git, svn, vs.)

Slide 70

Slide 70 text

Modülerlik

Slide 71

Slide 71 text

Modülerlik Sorun Projemiz büyüdükçe, projemizi bölmemiz gereken daha ufak parçaların sayısı çoğalır. İşte bu parçaları birbirinden ayrı tutmaya ve ihtiyaç duyulan yere yüklemeye modüler yaklaşım diyoruz. Bu modül ekrandaki bir bileşen olabileceği gibi, belirli bir işi yapmak üzere geliştirilmiş bir yazılım parçası da olabilir.

Slide 72

Slide 72 text

A D require  A;   require  B;   require  C; C B A E F D D G B E require  D;   require  E;   require  B; require  A;   require  D;   require  F; Modülerlik Çözüm Modüler yaklaşımın en önemli faydası soyutlamadır. Bir modülün içi dış dünyadan ayrıdır ve onu sadece bize verdiği ara birim üzerinden kullanabiliriz. Modül tamamiyle baştan bile yazılsa arabirimdeki methodların ismi değişmedikçe yapımız bozulmaz. Ek olarak NPM paket yöneticisi ile yüklenen “paketler” de birer modüldür ve ihtiyaç duyuldukları yere çağrılarak kullanılırlar.

Slide 73

Slide 73 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… Modülerlik CommonJS NodeJS paket yönetimi için CommonJS yaklaşımını kullanır. React ile oluşturduğumuz bileşenleri hatırlayın. Bu bileşenlerin her birini ayrı dosyalarda tutuyorsak, zaten modüler yaklaşım için ilk adımı atmışız demektir. Geriye kalan bunları birer modül haline getirmek, ve gerektiğinde çağırarak kullanmak.

Slide 74

Slide 74 text

Jon Snow Web Tyrion Lannister Web Arya Stark Mobile Khaleesi Mobile Search… searchBar.js   var  SearchBar  =  ...;
 module.exports  =  SearchBar; userListItem.js   var  UserListItem  =  ...;
 module.exports  =  UserListItem; userList.js   var  UserListItem  =  require(‘./UserListItem’);   var  UserList  =  ...;
 module.exports  =  UserList; chatTab.js   var  searchBar  =  require(‘./searchBar’);   var  UserList  =  require(‘./UserList’);   var  ChatTab  =  ...;
 module.exports  =  ChatTab; Modülerlik CommonJS Eğer bu bileşenlerimizi CommonJS modülleri haline getirecek olsaydık. Dosyaları yukarıdaki gibi olacaktı. Her bir modül ihtiyacı olan diğer modülleri çağırıyor. Ve her modül kendin export ediyor. Böylece modüllerimiz de tıpkı bileşenlerimiz gibi aynı sırada iç içe geçmiş oluyorlar. Ancak bu kodlar NodeJS ortamında çalışacaksa da, tarayıcıda çalışmayacak. Peki bunu nasıl aşacağız?

Slide 75

Slide 75 text

browserify.org Modülerlik Browserify Cevap: browserify. Tek yapmanız gereken ana dosyanızı (bizim örneğimizde bu ChatTab modülünü kullanacak olan dosya) browserify üzerinden geçirip (yazar burada bir grunt/gulp görevi yaratmaktan bahsediyor) bu modül yüklemelerinin tarayıcıya göre düzenlenmesini sağlamak.

Slide 76

Slide 76 text

Framework’ler ve Gelecek?

Slide 77

Slide 77 text

Frameworkler ve Gelecek EcmaScript 6 EcmaScript 6 artık standart! Kullanmadığınız her gün geride kalıyorsunuz demektir. En basit özelliğinden en gelişmiş özelliğine kadar farketmeksizin bir yerinden kullanmaya başlayın. Zaten henüz tüm özellikleri tarayıcılar veya NodeJS tarafından implemente edilmiş değil. Siz yavaştan kullanmaya başladıktan sonra tarayıcılar da zamanla kendilerini tamamlayacaklar. EcmaScript 6 kullanmak için ne engeliniz olabilir ki?

Slide 78

Slide 78 text

SURPRISE M..

Slide 79

Slide 79 text

babeljs.io Frameworkler ve Gelecek BabelJS Internet Explorer’a maruz kalanlarımız, maalesef ki ES6 değil ES5’i bile rahatlıkla kullanamıyor olabilirler. Ancak bu bir sorun değil. BabelJS sayesinde Grunt/Gulp otomasyonunuza ekleyeceğiniz fazladan bir görev ile ES6’da yazdığınız kodlarınızı ES5’e çevirebilirsiniz. Eğer tarayıcı ES5 kodlarını bile desteklemiyorsa onun için de ponyfill veya polyfill’leri kullanın.

Slide 80

Slide 80 text

Konuşmanın sosyal mesajına gelecek olursak, hergün yeni bir framework çıkıyor ve geliştiriciler bu frameworklerin fanboyluğunu yapmak görevini üstlenmiş durumdalar. Framework yarıştırmak yerine asıl yapılması gereken en düşük düzeyden başlayarak, tasarım desenlerini, yaklaşımları ve diğer yazılım konseptlerini öğrenmek. Çatılardan önce temellerde uzman olmak. Daha sonra ise bu çatıları oluşturan parçaların üzerine eğilmek. Bu özellikle şirketler tarafından cesaretlendirmek yerine baltalanan bir durum. Çünkü tecrübesiz geliştiricilerin kendi mimarisini kurmaya çalışmasının felaketle sonuçlanabileceğini biliyorlar. Ama bilin bakalım ne oluyor, bu sayılanlardan bihaber geliştiriciler herhangi bir framework kullansalar da sonuç yine felaket oluyor. O nedenle derinlere, temellere inmekten korkmayın. Çünkü günün birinde elbet ya patronunuz ya sizden sonraki geliştirici ya da bizzat kendiniz tarafından yargılanacaksınız. Yargılanacaksanız, dövüşerek yargılanmayı talep edin.

Slide 81

Slide 81 text

ramesaliyev