2 puan yazan GN⁺ 2023-11-14 | 1 yorum | WhatsApp'ta paylaş
  • Web components, React component’larının tarayıcıdaki karşılığı gibi görünse de, gerçekte mevcut HTML’i merkeze alıp üzerine işlev ekleyen bir modele daha yakındır
  • Temel fark JavaScript çalışmadan önce render edilebilmesinde yatar: boş bir custom element’e veri geçirmektense, anlamlı HTML’i bir custom element ile sarmalamak daha doğal bir yaklaşımdır
  • HTML web component, mevcut markup’ı genişletir; içeriği ve işlevi tamamen JavaScript’e bırakan boş öğeler ise JavaScript web component’e daha yakındır
  • React tarzı bileşenleştirme yerine koymaya (replacement) alışkınsa, web components içeriği koruyup üzerine işlev ekleyen güçlendirme (augmentation) düşüncesini gerektirir
  • Web platformunda HTML5, fetch, TypeScript ile ilgili akışlarda olduğu gibi iyi fikirler mevcut teknolojileri yerinden etmekten çok desteklenerek güçlendirme yoluyla uzun süre varlığını sürdürme eğilimindedir

Web components ile React component’ların karakteri farklıdır

  • “Web components” adı, web platformunun React component karşılığı gibi gelebilir
    • React’in JSX’i <MyComponent> biçimini kullanır; web components ise <my-component> biçimini kullanabilir
    • Ancak React component yapar gibi web component yapmaya çalışırsanız kolayca hayal kırıklığı yaşayabilirsiniz
  • Bu iki teknolojinin tasarımda öncelik verdiği özellikler ve kullanım biçimleri farklıdır
    • Birini diğeri gibi kullanmaya çalışmak, her teknolojinin doğal yönüyle çatışır

HTML web components, yerine koymaktan çok güçlendirmeye uygundur

  • Tipik bir React component, boş bir component’a prop’larla veri geçirip JavaScript’in tüm içeriği render ettiği bir biçimde olabilir
<UserAvatar
  src="https://example.com/path/to/img.jpg";
  alt="..."
/>
  • Web components de dışarıdan bakıldığında aynı şekilde yazılabilir
<user-avatar
  src="https://example.com/path/to/img.jpg";
  alt="..."
></user-avatar>
  • Ancak web components’ın kendine özgü gücü, JavaScript’ten önce render edilebilmesidir
    • React component’ları bu şekilde çalışamaz
  • Bu yüzden boş bir “shell component” yerine, temel içeriği HTML ile oluşturup ardından custom element ile sararak işlev ekleyen yapı daha iyi uyar
<user-avatar>
  <img src="https://example.com/path/to/img.jpg"; alt="..." />
</user-avatar>
  • Jeremy’nin “HTML web components” ayrımı, custom element’in mevcut markup’ı genişletip genişletmediğine odaklanır
    • Custom element boşsa, HTML web component değildir
    • Mevcut markup’ı sarıp genişletiyorsa HTML web component’e daha yakındır
  • “JavaScript web component”, boş bir öğenin içeriğinin ve işlevinin tamamen JavaScript’e bağlı olduğu biçimdir
<user-avatar
  src="https://example.com/path/to/img.jpg";
  alt="..."
></user-avatar>
  • Bu biçim, JavaScript yoksa son kullanıcı için anlam taşımaz
  • Buna karşılık HTML web component’ta JavaScript olmasa bile anlam ve içerik kalır; JavaScript varsa bunun üzerine işlev eklenerek güçlendirilir
<user-avatar>
  <img src="https://example.com/path/to/img.jpg"; alt="..." />
</user-avatar>

Web’de güçlendirme yaklaşımı uzun ömürlüdür

  • Web’de güçlendirmeye dayalı yaklaşımın iyi uymasının nedeni, web’in doğasının dayanıklı kademeli geliştirmeyi teşvik etmesi ve web gibi büyük bir şeyi tekrar tekrar değiştirmeye uygun olmasıdır
  • Web çevresindeki framework ve kütüphanelerin iyi fikirleri platforma alınsa bile, bunlar çoğu zaman mevcut teknolojileri bütünüyle değiştirmek yerine güçlendiren biçimde dahil olur
    • XHTML, HTML4’ün yerini almaya çalıştı; HTML5 ise HTML4’ü güçlendirmeye çalıştı ve kazanan HTML5 oldu
    • Ağ kütüphaneleri XMLHttpRequest’in yerini almaya çalıştı; iyi fikirler sonunda fetch standardına taşındı
    • fetch bugün tarayıcı dışındaki çeşitli ortamlarda da bulunuyor
    • Sass ve jQuery’nin iyi fikirleri de tarayıcıya taşındı
    • TypeScript’in iyi fikirleri de mevcut teknolojilerin yerini almadan, onları güçlendirecek şekilde tarayıcıya giriyor
  • Web components da React’in component modelinin tarayıcıya taşınması gibi görülebilir; ancak web’in zaten çalışma biçimini değiştirmekten çok onu güçlendirmeye daha yakındır
  • Uzun ömürlü bir teknik yaklaşım istiyorsanız, yerine koymak yerine güçlendirme ve iyileştirmeyi seçmek web’in yönüyle daha uyumludur

1 yorum

 
GN⁺ 2023-11-14
Hacker News görüşleri
  • Bu yazının user-avatarın gerçekte ne yaptığını ya da ne sağladığını açıklamasını bekledim ama buna hiç gelinmedi.
    İçinde sadece stil varsa neden doğrudan bir CSS sınıfı kullanılmasın anlamıyorum; ayrıca user-avatarın her seferinde içine bir img etiketi yerleştirmesi yerine src niteliği alması çok daha doğal görünüyor.
    Vue/React/Angular, HTML’yi “değiştirmeye” çalışmaktan ziyade HTML/CSS/JS üzerine inşa ediliyor gibi; her şeyi canvas ile render ediyor olsalardı bu iddia daha ikna edici gelebilirdi.
    Web Components ilk duyurulduğunda umutlanmıştım ama yerleşik özellikleri fazla yetersiz ve framework’ler gibi web uygulamaları yaparken gerçekten yardımcı oldukları hissi zayıf.
    Büyük framework’lere alternatifler, özellikle htmx gibi olanlar, jQuery tarzına biraz sözdizimsel şeker eklenmiş hâli gibi görünüyor; bu da web uygulaması geliştirmede büyük bir geri adım gibi hissettiriyor.

    • “Büyük framework alternatifleri jQuery’nin sözdizimsel şekeri gibi” kısmına katılıyorum ama bunun neden web uygulaması geliştirmede bütünüyle yanlış bir seçim olduğu pek net değil.
      Eğer “web uygulaması” ile Google Sheets benzeri şeyler kastediliyorsa katılırım; ama bu anti-React akımı daha çok, böyle örneklerden ziyade framework kurup en baştan onunla geliştirmeyi varsayılan hâle getiren pratiği eleştiriyor gibi.
      Gerçekte ihtiyaç duyulan şeyin yalnızca “üstüne hafifçe eklenen etkileşim” olduğu pek çok web sitesi de var.
    • Bence Eric Meyer’in yazısı niyeti çok daha iyi gösteriyor: https://meyerweb.com/eric/thoughts/2023/11/01/blinded-by-the...
      Temel avantaj aşamalı iyileştirme; img etiketinin zaten varsayılan bir davranışı var, bu yüzden temel render işleminde buna güvenip yalnızca gereken yerleri web component ile “güçlendirmek” yeterli.
    • Somut örnekler az olduğu için bu yazı biraz duşta akla gelen fikirler gibi hissettiriyor.
    • Yazının derdini daha somut gösteren örnek şu: https://www.zachleat.com/web/details-utils
      details-utils component’i, yerleşik HTML detail component’inin davranışını güçlendiriyor.
      Herhangi bir nedenle JavaScript kapalı olsa bile detail component’i normal şekilde çalışmaya devam ediyor; JavaScript açıksa ya da indirme tamamlandıysa dışarı tıklayınca kapanma gibi gelişmiş davranışlar kazanıyor.
      Bu yaklaşımda yeniden kullanılabilir kısım tam olarak bu tür davranış güçlendirmeleri.
      11ty geliştiricisinin bu web component’ini görünce yazının ana fikrini anladım; Web Components’ı ilk gördüğümde hissettiğim “sonuçta JavaScript gerekiyor ve o olmadan çalışmıyor ki” noktası, Rich Harris’in şu yazısında da geçiyor: https://dev.to/richharris/why-i-don-t-use-web-components-2ci...
    • htmx kullanıp kullanmadığını bilmiyorum ama jQuery’nin çözdüğü istemci tarafı JavaScript kullanıcı deneyimi sorunundan farklı bir problemi ele aldığı için bu eleştiri hedefi ıskalıyor gibi.
      htmx esas olarak JavaScript yazmaktan kaçınırken sunucu tarafında render edilen HTML paradigmasını tam sayfa yenileme yerine kısmi sayfa güncellemelerine genişletme yöntemi.
  • “HTML Web Components” fikrini daha fazla görmek için şu yazılar da okunabilir.
    https://meyerweb.com/eric/thoughts/2023/11/01/blinded-by-the... - “So there you have it: a few thousand words on my journey through coming to understand and work with these fully-Light-DOM web components, otherwise known as custom elements. Now all they need is a catchy name, so we can draw more people to the Light Side of the Web.”
    https://adactio.com/journal/20618 yazısında buna uygun bir isim öneriliyor.

    • Ana fikri pek anlayamadım.
      Yazması zahmetli olduğu için sonunda Lit gibi yerleşik framework üstündeki hafif bir framework’e ihtiyaç duyuluyor; üstelik Lit, Preact’ten bile daha büyük.
      Ayrıca durum yönetimi, routing gibi gerçek sorunları çözmediği için daha fazlasını eklemek gerekmesi muhtemel.
      Yeniden kullanılabilir component’ler elde edilebilir ama React kullanılan bir yerde içeride Vue kullanan bir web component getirip kullanma fikrini düşününce kulağa pek mantıklı gelmiyor.
    • Shadow DOM’suz web component’ler öne çıkarıldığı için buna gerçekten sevindim.
      Web’in güzelliği ve zarafeti, gözlemlenebilirlik ve değiştirilebilirlik sağlayan bildirimsel yapısından geliyor.
      Shadow DOM bana hep daha yüksek kapsülleme bariyerleri ve daha fazla kesinlik kurma yönündeki kurumsal bir istek gibi gelmişti; kişisel olarak paylaştığım bir hedef değildi.
      Bu yazı, Light DOM ile çalışmanın nasıl birleştirilebildiğini gösteriyor.
      Web component’lerin ya da custom element’lerin kendi iç DOM’larını değiştirebilmesi, çocuklarını taşıyabilmesi ve yeni içerik oluşturabilmesi gerektiğini hep düşünmüşümdür.
      Örneğin sayfa ya da framework ikonları yerleştirebilir, kullanıcı avatarı öğesi de ad veya süsleyici öğeler ekleyebilir.
      Yine de Light DOM/HTML Web Components konusunda bir endişem var: Shadow DOM bazı performans avantajları sağlıyor.
      CSS seçicilerinin dolaşması gereken öğe sayısını azaltabilmesi, geliştirici olarak zihnimde canlanıyor; bu avantajdan da bir şekilde yararlanabilmek güzel olurdu.
      Custom element’lere ve Web Components’a daha hafif yaklaşan bu bakış açısı gerçekten sevindirici, bağlantılar için de teşekkürler.
    • İsim biraz daha kısaltılıp HTML components denebilir diye düşünüyorum.
  • “JavaScript'ten önce render edilebilir. React bileşenleri bunu asla yapamaz” ifadesini kesin bir yargı olarak söylemek zor; sunucu tarafı render kullanılırsa istemci tarafı JavaScript'ten önce render edilebilir
    Örneğin yazarın iddiasını göstermek için fazla basit olduğunu düşünüyorum
    Durum değişimlerini ele alan bir web component daha iyi bir karşılaştırma olurdu ve argüman da muhtemelen daha güçlü olurdu

    • Bu iyi bir nokta; tersinden bakarsak web component'lerin de sayfa yüklenmeden önce JavaScript ile kaydedilmesi gerektiği için bunun mümkün olmadığı söylenebilir
      Hydration çözümleri var ama genelde daha kötü oluyor, şaşırtıcı ödünleşimler getiriyor ve çoğu zaman birleştirilebilirliği zedeliyor
    • Web Components tarafındaki en büyük sorun, sunucu tarafı render'a dost olmamaları
    • “HTML Web Component”in durum değişimlerini nasıl ele alacağını bilmiyorum
      Sadece img etiketini saran örneğe bakınca faydası çok net gelmedi; ortak öğeleri gruplayıp yeniden kullanmayı sağlayabilir ama etkileşim için hâlâ JavaScript gerekiyor
      Örnekteki görsel alternatif metni de artık yerelleştirme nedeniyle çoğunlukla dinamik oluyor; JavaScript yoksa içerik eksik kalabilir
  • Sonunda Web Components konusunda kafamda bir şeyler oturmuş gibi hissediyorum: https://github.com/kennyfrc/cami.js
    “No Build Steps, No Client-Side Router, No JSX, No Shadow DOM. We want you to build an MPA, with mainly HTML/CSS, and return HTML responses instead of JSON. Then add interactivity as needed.”
    “Declarative templates with lit-html. Supports event handling, attribute binding, composability, caching, and expressions.”

    • Web Components'in güzelliği, ihtiyacınız olan şekilde çalışan bir taban sınıfı bulabilmeniz ya da oluşturabilmeniz
      Ben şahsen, XState'ten ilham alan yerleşik bir durum makinesi içeren React class component tarzı sınıfları seviyorum
      https://github.com/codewithkyle/supercomponent/blob/master/s...
    • HTMX kullanmayı denedin mi diye merak ediyorum
      Yönelim olarak oldukça benzer görünüyor ve HTMX tarafının topluluğu daha büyük bile olabilir
      Kullandıysan, sence hangi konuda eksik kalıyordu merak ediyorum
    • JSX'i standart dışı kullanıcı tanımlı bir DSL ile değiştirip buna zafer demek gibi
  • “web components” tek bir şey değil ve “bir web component” de üretmiyorsunuz
    “Web Components”, üç şeyi bir araya getiren Web Components API'nin adı
    Aslında oluşturduğunuz şey custom element'tir; yanında Shadow DOM da kullanabilirsiniz, HTML template de
    Bu üçünün içinde en önemlisi custom element
    Temel fikir “daha fazla HTML öğesi oluşturmak” olduğu için, hangi özellikleri ve hangi JavaScript API'lerini destekleyeceğine tamamen siz karar verirsiniz
    Sayfaya ekleme, etkileşim kurma ve olayları dinleme biçimi de diğer HTML öğeleriyle tamamen aynı
    Web sayfalarını “eski usul” yazmayı biliyorsanız custom element kullanmayı zaten biliyorsunuzdur; sadece nasıl tanımlanacağını öğrenmeniz gerekir

  • Son zamanlarda build ortamı olmadan Web Components kurcalamaya başladım
    npm, bun, webpack gibi şeyler de yok, bağımlılık da yok ve TypeScript ile yazıyorum
    IntelliJ bunu otomatik olarak JavaScript'e derliyor; tarayıcı görünümü de geliştirme sırasında canlı güncelleme için küçük bir değişiklik izleme işleyicisi enjekte ediyor
    Şimdiye kadar bir sorun çıkmadı
    Web Components'in ayağına dolanan şey HTML Modules gibi görünüyor
    Web component içe aktarmak için .js dosyasına değil de .html dosyasına bağlanabilmek güzel olurdu ama şu anda template ya da biraz daha karmaşık bir şey kullanmak istiyorsanız .innerHtml = \...`` gibi çirkin enjeksiyonlar yapmak gerekiyor
    Bunun sorun olacağını sanmıştım ama IDE template string'leri gayet iyi parse ediyor

    • HTML Modules rafa kaldırıldı ve kaldırıldıktan sonra yerini yalnızca JavaScript tabanlı import'lar aldı
      Ayrıca Web Components'i engelleyen tek şey de bu değil
  • “React bir güçlendirme değil, bir ikame” iddiası bana pek ikna edici gelmiyor
    Sonuçta React de HTML öğelerini render ediyor ve JavaScript olay işleyicileri ekliyor
    img öğesini bir React bileşeniyle sarmalamak, imgnin işlevini elinden almak değil; onun üzerine bir şeyler eklemek, yani onu güçlendirmektir
    Yazar başka React kod tabanlarında çalışmış olabilir ama benim deneyimime göre biz, bir sebep yoksa tarayıcının yerleşik özelliklerini olduğu gibi kullanıyoruz
    Belki de sadece şanslıydım

    • Her web mimarisinin eninde sonunda HTML öğeleri render etmesi zaten doğal; mesele bu değildi
      Mesele, “HTML Web Component” yaklaşımının React'ten farklı olarak render işlemine başlamak için JavaScript'e bağımlı olmaması
    • Yazının anlattığı temel farkı kabaca şöyle görüyorum
      React, tarayıcı render akışı açısından “sayfa yüklenir → bileşen yüklenir” şeklinde çalışırken, Web Component daha çok “sayfa yüklenir → temel render yapılır → bileşen yüklenir” akışına yakın
      JavaScript'i kapatmış biri web component tarafında yine de bir şeyler görebilirken, React'te hiçbir şey göremeyebilir; JavaScript varsa da daha gelişmiş bir render durumuna geçilebilir
    • React bazı durumlarda yerleşik özelliklere erişimi daha da zorlaştırabiliyor
      Örneğin öğeye onchange atarsanız React size change olayı değil, input olayına daha yakın bir şey verir
      Aslında ikisi de değildir; changeden çok inputa benzeyen sentetik bir olay verir
      Gerçekten change istiyorsanız öğe referansını kullanıp effect içinde işleyiciyi doğrudan bağlamanız gerekir
    • Bu, uygulama mimarisine bağlı
      React ile sunucudan HTML döndürüyorsanız imgyi bir React bileşeniyle sarmalamak gerçekten mevcut öğeyi güçlendirmek olur
      Ama her şeyi istemci tarafında render ediyorsanız, o img sonuçta React bileşeninden ayrılamaz
    • O kısmı okurken ters yönü, yani başka bir HTML içine React gömme durumunu düşündüm
      Deneyimime göre React, sayfa yapısının tamamını yukarıdan aşağıya ona emanet ettiğinizde harika; ama sunucu tarafı render gibi işler yaparken onu mevcut yapının içine sıkıştırmaya çalışırsanız zorlaşabiliyor
  • Uzun ömürlü bir yaklaşım arıyorsanız, ikame yerine güçlendirme ve iyileştirmeyi seçin sonucu benim deneyimimle de örtüşüyor
    Bu felsefe sayesinde web projelerim bakım yükünü ve bağımlılıkları en aza indirerek uzun süre ayakta kaldı

  • Web component'ler tek bir iş yapmalı; JavaScript framework'leri ise daha çok bütün bir ekosisteme benziyor
    Birden fazla girdi alabilen bir video oynatıcı web component'i yaptım ve en karmaşık girdi torrent dosyasıydı
    Bunu StencilJS [0] ile Vue/React'e port edebilirdim ama buna gerek olmadan da gayet kullanılabiliyordu
    İlgili etiketi, awesomePlayer.js'den dışa aktarılan sınıfla birlikte koymanız yeterliydi; böylece torrent oynatabilen, kopyala-yapıştır kullanıma uygun bir HTML5 video oynatıcı elde ediyordunuz
    Mümkünse mevcut HTML öğelerini taklit etmeyi de özellikle tavsiye ederim
    Örneğin src kullanmamın nedeni video öğesinin de bunu kullanması; böylece kullanan taraf dokümantasyona bakmadan da onunla etkileşime girebilir
    [0] https://stenciljs.com/

  • Frontend framework bileşenlerinin tamamen ikame amaçlı olduğu ve birleştirilebilir olmadığı fikrine katılmakta zorlanıyorum
    Dışarıdan öyle görünebilir ama kendi bileşenlerimde slot'ları çok kullanıyorum; uygulaması da kolay ve doğal çalışıyor
    Buna karşılık Web Components genelde bir editör benzeri bir şey yapmak için devasa miktarda kod gömmek üzerinden gösteriliyor
    Web Components'te slot kullanmak acı vericiydi; çok sayıda düğümü elle eklemek, template'leri string olarak yönetmek ve biraz karmaşık bir iş yapacaksanız slotchange olayını bile dinlemek gerekiyordu
    Esasen DOM API'sini kullanıyorsunuz; o API bu kadar korkunç olmasaydı zaten React gibi frontend framework'lerine geçilmezdi
    XHTML'in HTML'i güçlendirmediği için başarısız olduğu yönündeki yan argümana da katılmıyorum
    Bence başarısız olmasının nedeni, uygulamanın tamamen geçerli olmak zorunda olması ve bu doğrulamayı istemciye/tarayıcıya bırakmasıydı
    Gerçek XHTML kullansaydınız işaretlemedeki küçücük bir hatada sayfa bozulurdu; bu yüzden herkes geleceğe hazırlık için XHTML doğrulaması yapmış olsa da, sadece bir p etiketinin düzgün kapanmaması yüzünden işin tamamının çökmesi riskini hiçbir şirket göze almazdı