3 पॉइंट द्वारा GN⁺ 2024-08-17 | 1 टिप्पणियां | WhatsApp पर शेयर करें

Vanilla JSX के उदाहरण

अगर JSX DOM elements लौटाए तो?

  • ClickMe फ़ंक्शन एक बटन बनाता है और क्लिक की संख्या दिखाने की सुविधा देता है
  • हर बार बटन पर क्लिक करने पर टेक्स्ट अपडेट होता है
export default function ClickMe() {
  let i = 0;
  const el = Click me as HTMLButtonElement;
  el.onclick = (e) => {
    el.textContent = `Clicked ${++i} times`;
  };
  return el;
}

पुन: उपयोग की क्षमता

  • ClickMe कॉम्पोनेंट को कई बार इस्तेमाल करके हर instance का अलग state रखा जा सकता है
import ClickMe from "./sample1.js";
export default () =>

;

इंटरैक्टिव DOM tree बनाना

  • TodoInput और TodoList क्लास का उपयोग करके todo list को मैनेज किया जा सकता है
  • items जोड़े जा सकते हैं और क्लिक करके हटाए जा सकते हैं
function TodoInput(attrs: { add: (v: string) => void }) {
  const input =  as HTMLInputElement;
  input.placeholder = 'Add todo item...';
  input.onkeydown = (e) => {
    if (e.key === 'Enter') {
      attrs.add(input.value);
      input.value = '';
    }
  };
  return input;
}

class TodoList {
  ul =  as HTMLUListElement;
  add(v: string) {
    const item =
- {v}
 as HTMLLIElement;
    item.onclick = () => item.remove();
    this.ul.append(item);
  }
}

export default () => {
  const list = new TodoList();
  list.add('foo');
  list.add('bar');
  return
     list.add(v)} />
    {list.ul}
  ;
};

बड़े पैमाने के डेटा को प्रोसेस करना

  • FindNames फ़ंक्शन बड़े पैमाने के डेटा को प्रोसेस और फ़िल्टर करके नतीजे दिखाता है
  • input value के अनुसार real-time में matching items अपडेट होते हैं
import { data } from "../fetch-dataset.js";
export default function FindNames() {
  const status =  as HTMLParagraphElement;
  const results =  as HTMLUListElement;
  const input =  as HTMLInputElement;
  updateMatches();

  function updateMatches() {
    const matched = (data.entries().filter(([k]) => k.match(input.value)).toArray());
    const matches = (Iterator.from(matched).map(match => ).take(30));
    results.replaceChildren(...matches);
    status.textContent = `${matched.length} / ${data.size}`;
  }

  return
    {input}
    {status}
    {results}

;
}

function Item(attrs: { match: [string, number], regex: string }) {
  const [name, count] = attrs.match;
  const total = ({count});
  return
-
     {total}

;
}

function highlight(str: string, regex: string) {
  if (!regex) return str;
  const r = new RegExp(`(${regex})`, 'gi');
  return str.replace(r, '$1');
}

imlib का परिचय

  • imlib एक लाइब्रेरी है जिसे immaculatalibrary.com के लिए विकसित किया गया है
  • इसका उपयोग minigamemaker.com और उस वेबसाइट को बनाने में किया गया है जिसे आप अभी पढ़ रहे हैं
  • इसे इसलिए विकसित किया गया क्योंकि मौजूदा state पर्याप्त नहीं थी, और apps बनाने का यह सबसे पसंदीदा तरीका है

GN⁺ का सारांश

  • यह लेख बताता है कि JSX का उपयोग करके DOM elements को सीधे कैसे बनाया और इंटरैक्ट किया जा सकता है
  • यह दिखाता है कि virtual DOM का उपयोग किए बिना भी बड़े पैमाने के डेटा को कुशलता से कैसे प्रोसेस किया जा सकता है
  • imlib लाइब्रेरी apps को सरल और सहज तरीके से विकसित करने में मदद करती है
  • मिलते-जुलते फीचर्स वाले अन्य प्रोजेक्ट्स में React, Vue.js आदि शामिल हैं

1 टिप्पणियां

 
GN⁺ 2024-08-17
Hacker News की राय
  • असली DOM nodes लौटाने से immediate-mode style API और UI=f(state) मॉडल लगभग निष्प्रभावी हो जाते हैं, जो JSX और Lit जैसी non-JSX libraries का बड़ा फायदा है
    असली DOM नहीं, बल्कि DOM का वर्णन लौटाना चाहिए, ताकि नए state के साथ template को बार-बार evaluate किया जा सके और जिस DOM में वह template render होता है उसे efficiently update किया जा सके
    उदाहरणों में input.onkeydown = ... या this.ul.append(item) जैसे imperative DOM API से updates किए जा रहे हैं, लेकिन संभव है कि ऐसे code से बचना और template में items पर iterate करना ही virtual DOM का मुख्य लाभ हो
    हालांकि virtual DOM की समस्या यह है कि diff calculation धीमी होती है, और इसे Lit की तरह static parts और dynamic parts को अलग करने वाले templates से हल किया जा सकता है

    • जटिल web UI बनाने के अनुभव से, sufficiently complex app में virtual DOM performance advantage मुझे लगभग भ्रम जैसा लगता है
      बल्कि यह सोचने पर मजबूर करता है कि “बड़े UI को जितना चाहें re-render कर दें, virtual DOM संभाल लेगा”, जिससे उल्टा असर होता है; वास्तविक performance खराब होती है, लेकिन app structure इतना जम चुका होता है कि rewrite के बिना ठीक करना मुश्किल हो जाता है
      मैंने चार teams में यही pattern देखा, और architect के तौर पर React में आने वाली समस्याओं के आधार पर performance-aware vanilla structure की सलाह दी, लेकिन “इससे बचने के कई तरीके हैं” जैसी बातों के कारण इसे स्वीकार नहीं किया गया
      आखिरकार कई मामलों में लगता है कि लोगों को खुद मेहनत करके सीखना पड़ता है
    • यह user पर निर्भर करता है। दूसरे नजरिए से देखें तो JSX बस createElement function call pattern के लिए एक अलग DSL है, और बताए गए फायदे framework और runtime से आते हैं
      और संक्षेप में कहें तो JSX एक alternative function call syntax है जिसके उपयोगी use cases हैं
      मेरी पिछली company में हमने JSX को test data factories के लिए इस्तेमाल किया था; यह XML जैसा दिखता था, लेकिन element creation step में builder pattern के जरिए final data के हिसाब से contextual decisions लिए जा सकते थे
      इसका React या DOM से कोई संबंध नहीं था, और इसका मतलब यह भी नहीं था कि JSX के बिना declaratively express नहीं किया जा सकता
    • “आप क्या चाहते हैं” यह किसके बारे में है, इस पर निर्भर करता है। निजी तौर पर मैं किसी भी reconciliation mechanism के बिना DOM nodes को in-place update करना पसंद करता हूं
    • “अब imperative updates नहीं करने पड़ेंगे” वाला सपना समझ में आता है। मैं करीब 10 साल से ऐसे frameworks इस्तेमाल कर रहा हूं और उनसे काफी परिचित हूं
      निजी तौर पर मुझे DOM को imperatively update करना ज्यादा पसंद है। क्या हो रहा है, इस पर बहुत बारीक control मिल सकता है, और इसे बहुत efficient structure के रूप में design किया जा सकता है
      किसी की मजबूत methodology के हिसाब से सोचे बिना app features को add, change, delete और modify करना आसान बनाया जा सकता है
    • मैं इस बात से सहमत हूं कि असली DOM nodes लौटाने से JSX और Lit जैसी non-JSX libraries के फायदे—immediate-mode style API और UI=f(state) model—कमजोर हो जाते हैं, लेकिन यह पूरी computing में भी गिनी-चुनी सबसे leaky abstractions में से एक जैसा लगता है
      React के आसपास renders को बार-बार न होने देने, unnecessary refreshes रोकने जैसी चीजों का ecosystem बना है, तो उसकी वजह है
  • पिछले 10 सालों से static site generators की हालत से निराश होकर मैंने यह project बनाया
    मैं मुख्य रूप से static websites बनाता हूं, इसलिए मुझे simple और intuitive tools चाहिए थे और JSX अच्छा fit लगता था, लेकिन React जैसे JSX frameworks की excessive complexity से थक चुका था
    इसलिए मैंने JSX को strings में render करने वाला static site generator बनाया, और इसे browser side तक expand करके JSX को DOM elements में render करवाना स्वाभाविक था
    कुछ cases में, खासकर layouts में, यह shared components के लिए भी अच्छा fit है। कुल मिलाकर result से संतुष्ट हूं, लेकिन कुछ हिस्से काफी hacky हैं और IDE support भी बेहतर हो सकता है
    इसके अलावा यह तरीका SEO के लिए भी अच्छा fit है। यह ऐसी समस्या थी जो मुझे दूसरे JSX frameworks में ठीक से हल हुई नहीं लगी

    • क्या आपने Astro देखा है, यह जानना चाहूंगा। वह लगभग perfect static site generator जैसा लगता है, लेकिन हो सकता है VanillaJSX कोई और कमी हल करता हो
    • idea अच्छा है। demo page पर todo app में 404 आ रहा है
      docs में “SSG” के बजाय “static site generator” पूरा लिखना बेहतर होगा। मैंने static site generators इस्तेमाल किए हैं, फिर भी SSG क्या है यह नहीं पता था और AI से पूछना पड़ा
    • Django server-side के लिए JSX हो तो बढ़िया होगा
    • क्या आपने lit-html देखा है, यह जानना चाहूंगा
      Vue से आकर मुझे आश्चर्य हुआ कि lit-html सिर्फ simple vanilla JS templates के जरिए event binding सहित Vue templates के बहुत से काम कर देता है
      VSCode lit extension इस्तेमाल करने पर templates के अंदर भी syntax highlighting और full type checking मिल सकती है
      Marc Grabanski ने ट्वीट किया था कि वे Lit नहीं, बल्कि vanillajs के साथ lit-html इस्तेमाल करते हैं; उसके बाद मुझे इसके बारे में पता चला, और खुद experiment करने पर यह बहुत अच्छी तरह काम करता मिला। आप अभी जो हल करने की कोशिश कर रहे हैं, उससे यह काफी मिलता-जुलता लगता है
      lit-html template package का इस्तेमाल करने पर templates chapter में बताई गई अधिकांश चीजें की जा सकती हैं: https://lit.dev/docs/templates/overview/
      lit-element की component abstraction के बिना भी यह संभव है: https://lit.dev/docs/libraries/standalone-templates/#renderi...
  • ऐसे “क्या हो अगर” दिलचस्प इसलिए लगते हैं क्योंकि JSX की जड़ें Facebook के XHP तक जाती हैं, और XHP ने साफ तौर पर शुरुआती JS standard E4X से प्रेरणा ली थी, जो यहां बताए गए library जैसा ही दिखता और काम करता था
    [1] https://engineering.fb.com/2010/02/09/developer-tools/xhp-a-...
    [2] https://en.m.wikipedia.org/wiki/ECMAScript_for_XML

    • E4X में एक दुर्भाग्यपूर्ण कमी थी कि वह असली DOM instances लौटाता था, इसलिए उन्हें imperative तरीके से update करना पड़ता था
      JSX के E4X से आगे निकलने की वजह भी यही थी, और उसके बाद JS के अंदर HTML templates को लेकर कोई गंभीर proposal नहीं आया
      फिर भी लगता है कि इसे आधुनिक रूप देकर इस सामान्य idea को फिर से जिंदा किया जा सकता है: https://github.com/WICG/webcomponents/issues/1069
    • एक मजेदार बात यह है कि JavaScript में for each की जगह for(of) आने की वजह E4X था
      for (:) न मिलने की वजह और भी अजीब है: कुछ TC39 members को डर था कि यह उन :type annotations से टकरा सकता है, जिनके बारे में वे मानते थे कि वे किसी दिन जादू की तरह language में आ जाएंगे
  • मैंने कभी JSX template expressions से असली DOM nodes बनाने के idea पर एक UI library बनाई थी
    यह model objects को properties से bind करके imperative event handler boilerplate भी कुछ हद तक हटा देती थी। जैसा आप सोचेंगे, मुझे यह अच्छा idea लगता है
    https://github.com/tomtheisen/mutraction
    आप track({ clicks: 0 }) से model बनाकर click पर model.clicks बढ़ाने और उस value को सीधे DOM में reflect करने जैसा code लिख सकते हैं

  • यहां VanJS का जिक्र भी किया जा सकता है: https://vanjs.org/
    Solid.JS जैसी दूसरी JSX libraries भी DOM nodes लौटाती हैं, और अच्छा है कि यह idea traction पकड़ रहा है
    मुझे लगता है, हम जिस platform का इस्तेमाल करते हैं उसके जितने करीब रहें, उतना बेहतर है। abstraction layers कभी-कभी useful हो सकती हैं, लेकिन मुझे अब तक platform को छिपाने की सच में जरूरत नहीं मिली
    Facebook जैसे बहुत बड़े projects को फायदा हो सकता है, पर मैंने उस scale पर काम नहीं किया है

    • bundle size comparison में SolidJS का कोई खास मतलब नहीं है, है न?
  • examples अच्छे हैं, लेकिन मुझे अहम बात यह लगती है कि वे ऐसे component props नहीं दिखाते जो समय के साथ बदल सकते हैं
    लगता है ऐसी capability को model ही नहीं किया गया है। अगर इसकी जरूरत नहीं है तो यह clever तरीका है, लेकिन यह ज्यादा complex apps तक कैसे scale होगा, यह साफ नहीं दिखता

    • यहां और सभी browser-side code में इस्तेमाल की गई technique VS Code के अंदर इस्तेमाल होने वाले तरीके जैसी ही है, और यह काफी अच्छी तरह scale होती है
      फर्क बस इतना है कि DOM elements बनाने और setup करने वाले आम 10-line code को ज्यादा concise तरीके से लिखा गया है
      सच कहें तो इस framework में असली दिलचस्प चीजें इसके अलावा लगभग सब कुछ हैं। static site generator side पर JSX को string के रूप में लौटाना, raw source directory लेकर SSG time पर string|Buffer को manipulate करना, chokidar और swc के ऊपर बनाया गया बहुत efficient और fast module system वगैरह
      JSX को DOM की तरह इस्तेमाल करने वाला हिस्सा visually सबसे ज्यादा standout करता है, लेकिन असल में यह party trick के करीब है
      उदाहरण के लिए vanillajsx.com का source बहुत concise, clear और छोटा है। imlib के अलावा किसी dependency के बिना आज ही पूरा लिखा, और JSX-as-DOM demo इसका सबसे कम innovative हिस्सा है: https://github.com/sdegutis/vanillajsx.com/tree/main/site
    • इस approach को असली scale तक ले जाने और यह भरोसा करने के लिए कि सब कुछ उम्मीद के मुताबिक साथ काम करेगा, एक proper reactivity layer चाहिए
      अगर आपको JSX के concrete DOM elements लौटाने का यह तरीका पसंद है, तो Solid ठीक इसी तरह काम करता है, और इसमें proper reactivity layer भी जोड़ी गई है
    • शायद मैं कुछ miss कर रहा हूं, लेकिन समझ नहीं आता कि यह तरीका setTimeout या setInterval के इस्तेमाल को कैसे रोकता है
      हालांकि मैं इस बात से सहमत हूं कि ऐसे projects छोटे use cases में तो अच्छा काम करते हैं, लेकिन “real world” scenarios में अक्सर जल्दी टूट जाते हैं
    • मैं इस library का बचाव नहीं कर रहा, न ही इसे इस्तेमाल करने की योजना है, लेकिन React/Vue की तरह props changes से re-render trigger करवाना हो तो यहां JS Proxy इस्तेमाल किया जा सकता है
      implementation इतनी मुश्किल नहीं लगती
  • यह Vanilla TSX से काफी मिलता-जुलता है: https://github.com/wisercoder/uibuilder
    Vanilla TSX में लिखे app का example यहां है: https://github.com/wisercoder/eureka/tree/master/webapp/Clie...

  • मुझे ActionScript 3 याद आ गया, जिसमें language core में XML था
    लिखने में मजेदार language थी, लेकिन ES4 बनने में famously fail हो गई। आखिरकार TypeScript और JSX के जरिए लगभग उसी जगह पहुंचने में 10 साल से ज्यादा लग गए

    • https://en.wikipedia.org/wiki/ECMAScript_for_XML — यह Firefox में भी था, लेकिन लोगों को नहीं चाहिए था और आखिरकार हटा दिया गया
      React की पहली release से 6 महीने पहले, Firefox 17 में इसे web pages के लिए disable कर दिया गया था
    • मुझे याद नहीं कि इस तरह XML inline generate किया जा सकता था। शायद अगर यह Flex server-side feature रहा हो तो संभव रहा होगा
  • मुझे जानना है कि क्या किसी और के लिए भी आखिरी example Firefox में काम नहीं कर रहा है। Edge में चल गया, लेकिन Firefox में fail हुआ
    Uncaught (in promise) TypeError: Map.groupBy(...).entries().map is not a function

  • मुझे ठीक से समझ नहीं आ रहा कि JSX नीचे जैसे लिखने से ज़्यादा आकर्षक क्यों है
    h("div", {}, [ h("p", {}, "this is easy"), ...list.map((l) => h("li", {}, l)) ])
    ऐसा करने पर compiler और नई syntax बनाए बिना ही loops और variable interpolation वगैरह अपने-आप मिल जाते हैं। अच्छा होगा अगर कोई समझा दे

    • मुझे लगता है बहुत-से लोगों को JSX version कहीं ज़्यादा readable और familiar लगेगा। बेशक यह taste की बात है
      निष्पक्ष होकर कहें तो JSX में भी सामान्य loops और interpolation वैसे ही इस्तेमाल होते हैं। {} vanilla JS expressions लेते हैं
      बस element tags को createElement calls में expand करने के लिए एक compile step चाहिए होता है
    • निजी तौर पर, आपने जो code दिया है उसे देखकर जो लोग उसे JSX जितना अच्छा मानते हैं, उन्हें मैं ठीक से समझ नहीं पाता
      हर व्यक्ति information को अलग तरीके से process करता है, लेकिन उस example में punctuation बहुत ज़्यादा है, इसलिए जल्दी समझना बहुत मुश्किल है
      जब तक आप दिमाग में syntax को खुद decompose नहीं करते, generated DOM structure दिखता नहीं; और compiler चाहिए या नहीं, इससे कहीं ज़्यादा महत्वपूर्ण है DOM structure को एक नज़र में समझना
      संदर्भ के लिए, मैं neurodivergent हूँ, और उम्मीद है यह explanation मदद करेगा
    • उस logic के rabbit hole में नीचे उतरते जाएँ तो अंत में Common Lisp पर पहुँचते हैं
    • मैंने भी कभी यही सोचा था। एक फायदा यह लगता है कि यह HTML जैसा दिखता है
      browser developer tools में दिखने वाली चीज़ जैसा है, इसलिए compare और debug करना आसान है
    • single file या simple app हो तो वह style भी ठीक है
      लेकिन complex app में जब components सैकड़ों हो जाते हैं और एक-दूसरे को import करके इस्तेमाल करने लगते हैं, तो JSX tags में लिखने का तरीका simple और समझने में आसान syntax जैसा महसूस होता है
      React के खिलाफ प्रतिक्रिया भी आखिरकार इस बात से काफी आती है कि simple कामों के लिए यह overkill है, और सच में overkill है
      लेकिन लोग जो apps बनाते हैं, उनकी complexity और requirements अलग-अलग होती हैं, इसलिए यह कहना आसान नहीं कि कोई एक पक्ष ज़्यादा आकर्षक है। ये अलग-अलग समस्याओं के लिए अलग tools हैं