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 टिप्पणियां
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 से हल किया जा सकता है
बल्कि यह सोचने पर मजबूर करता है कि “बड़े UI को जितना चाहें re-render कर दें, virtual DOM संभाल लेगा”, जिससे उल्टा असर होता है; वास्तविक performance खराब होती है, लेकिन app structure इतना जम चुका होता है कि rewrite के बिना ठीक करना मुश्किल हो जाता है
मैंने चार teams में यही pattern देखा, और architect के तौर पर React में आने वाली समस्याओं के आधार पर performance-aware vanilla structure की सलाह दी, लेकिन “इससे बचने के कई तरीके हैं” जैसी बातों के कारण इसे स्वीकार नहीं किया गया
आखिरकार कई मामलों में लगता है कि लोगों को खुद मेहनत करके सीखना पड़ता है
createElementfunction 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 नहीं किया जा सकता
निजी तौर पर मुझे DOM को imperatively update करना ज्यादा पसंद है। क्या हो रहा है, इस पर बहुत बारीक control मिल सकता है, और इसे बहुत efficient structure के रूप में design किया जा सकता है
किसी की मजबूत methodology के हिसाब से सोचे बिना app features को add, change, delete और modify करना आसान बनाया जा सकता है
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 में ठीक से हल हुई नहीं लगी
docs में “SSG” के बजाय “static site generator” पूरा लिखना बेहतर होगा। मैंने static site generators इस्तेमाल किए हैं, फिर भी SSG क्या है यह नहीं पता था और AI से पूछना पड़ा
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-htmltemplate 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
JSX के E4X से आगे निकलने की वजह भी यही थी, और उसके बाद JS के अंदर HTML templates को लेकर कोई गंभीर proposal नहीं आया
फिर भी लगता है कि इसे आधुनिक रूप देकर इस सामान्य idea को फिर से जिंदा किया जा सकता है: https://github.com/WICG/webcomponents/issues/1069
for eachकी जगहfor(of)आने की वजह E4X थाfor (:)न मिलने की वजह और भी अजीब है: कुछ TC39 members को डर था कि यह उन:typeannotations से टकरा सकता है, जिनके बारे में वे मानते थे कि वे किसी दिन जादू की तरह 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 पर काम नहीं किया है
examples अच्छे हैं, लेकिन मुझे अहम बात यह लगती है कि वे ऐसे component props नहीं दिखाते जो समय के साथ बदल सकते हैं
लगता है ऐसी capability को model ही नहीं किया गया है। अगर इसकी जरूरत नहीं है तो यह clever तरीका है, लेकिन यह ज्यादा complex apps तक कैसे 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अगर आपको JSX के concrete DOM elements लौटाने का यह तरीका पसंद है, तो Solid ठीक इसी तरह काम करता है, और इसमें proper reactivity layer भी जोड़ी गई है
setTimeoutयाsetIntervalके इस्तेमाल को कैसे रोकता हैहालांकि मैं इस बात से सहमत हूं कि ऐसे projects छोटे use cases में तो अच्छा काम करते हैं, लेकिन “real world” scenarios में अक्सर जल्दी टूट जाते हैं
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 साल से ज्यादा लग गए
React की पहली release से 6 महीने पहले, Firefox 17 में इसे web pages के लिए disable कर दिया गया था
मुझे जानना है कि क्या किसी और के लिए भी आखिरी 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 में भी सामान्य loops और interpolation वैसे ही इस्तेमाल होते हैं।
{}vanilla JS expressions लेते हैंबस element tags को
createElementcalls में expand करने के लिए एक compile step चाहिए होता हैहर व्यक्ति information को अलग तरीके से process करता है, लेकिन उस example में punctuation बहुत ज़्यादा है, इसलिए जल्दी समझना बहुत मुश्किल है
जब तक आप दिमाग में syntax को खुद decompose नहीं करते, generated DOM structure दिखता नहीं; और compiler चाहिए या नहीं, इससे कहीं ज़्यादा महत्वपूर्ण है DOM structure को एक नज़र में समझना
संदर्भ के लिए, मैं neurodivergent हूँ, और उम्मीद है यह explanation मदद करेगा
browser developer tools में दिखने वाली चीज़ जैसा है, इसलिए compare और debug करना आसान है
लेकिन complex app में जब components सैकड़ों हो जाते हैं और एक-दूसरे को import करके इस्तेमाल करने लगते हैं, तो JSX tags में लिखने का तरीका simple और समझने में आसान syntax जैसा महसूस होता है
React के खिलाफ प्रतिक्रिया भी आखिरकार इस बात से काफी आती है कि simple कामों के लिए यह overkill है, और सच में overkill है
लेकिन लोग जो apps बनाते हैं, उनकी complexity और requirements अलग-अलग होती हैं, इसलिए यह कहना आसान नहीं कि कोई एक पक्ष ज़्यादा आकर्षक है। ये अलग-अलग समस्याओं के लिए अलग tools हैं