6 ms·
Proposal for Standardized JSX
- palmfacehn 1y agoI'm happy with <template> elements. No shade on JSX, but I prefer the abstraction of HTML, CSS and vanilla JS.
- cluckindan 1y agoI consider the slots-based approach clunky and prefer implementing my own templating system with simple functions returning HTML in template strings.
- palmfacehn 1y agoI did this in the past, but I found that templates simplified the process. The same functions I use to populate/update elements can be reused on existing elements and newly cloned template elements. It can be done in JS by returning strings of unpopulated elements, but then my display is further mixed with logic. I like to create the HTML and CSS as I'd like it with test data, then just wrap that with <template> tags. Easy to preview without triggering function calls or pasting it into code. Probably not important, but as I recall I think there was some minor overhead in translating from a JS String to an Element.
- pwdisswordfishz 1y agoEven better – return a DocumentFragment: https://stackoverflow.com/a/79233706 https://stackoverflow.com/a/79233706 I wish this were available natively.
- HelloNurse 1y agoCan you recommend examples and tutorials of happy <template> usage, showing advantages over building values for innerHTML etc. as text from strings and template string literals?
- palmfacehn 1y agoCanonical reference for me: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/template https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/...
- HelloNurse 1y agoThis MDN page is where I first discovered the <template> element, and I wasn't very impressed: verbosely operating on one textContent at a time, using ordinal indices into very untyped querySelectorAll results, apparently gratuitous complications with document fragments and shadow DOM.
- palmfacehn 1y agoVerbosity never concerned me. Readability, maintenance, page weight and separation of concerns does. Typically I do not find myself using querySelectorAll within the context of a template element. When I do I am usually applying changes universally to all of the matched children within the element. The CSS class of the element reflects these things semantically. I find this highly readable. It also resolves most concerns around the type of the element. Of course in Vanilla JS, types are a mess. Even Microsoft's finest duct tape script doesn't fully resolve these issues. Overall I find Vanilla JS and browser APIs to be a lesser evil than the build systems, package managers and indirection of the React/Next.js approaches. After all, these compiled environments and their libraries will boil down to Vanilla JS when deployed in the browser.
- 90s_dev 1y agoI made this proposal because JSX is more generally useful than generating HTML. You can use it for configuration, or views for other GUIs like I do in https://90s.dev/os/ https://90s.dev/os/ or to describe basically any kind of tree.
- WorldMaker 1y agoTemplate elements don't have great Typescript type checking today. I've been very happy with both, writing things in TSX with deep type checking and then statically rendering them to Template tags. [0] https://worldmaker.net/butterfloat/#/stamps https://worldmaker.net/butterfloat/#/stamps
- aatd86 1y agobecause react decided to return JSX like element syntax instead of being simply a function returning a dom element doesn't mean that this should be standardized.
- 90s_dev 1y agoGiven <foo bar={qux}>bla</foo> React used to transform it into React.createElement("foo", { bar: qux }, "bla") Now it transforms it into import _jsx from "react/jsx-runtime"; _jsx("foo", { bar: qux }, "bla") My proposal transforms it into { [Symbol.for('jsx')]: 'foo', bar: qux, children: "bla" } It's self-contained and generic, doesn't rely on auto-imports or globals, and doesn't have key collisions. It's the only way I can imagine it ever being standardized.
- pwdisswordfishz 1y agoWhat does <foo children={qux}>bla</foo> do?
- 90s_dev 1y agoThis is a known ambiguity in JSX, to the point where TypeScript gives this error: > 'children' are specified twice. The attribute named 'children' will be overwritten. ts(2710)
- pwdisswordfishz 1y agoNo, that's an ambiguity in React. JSX defines only syntax.
- 90s_dev 1y agoTrue. Then can you suggest a standardized ECMAScript JSX proposal that doesn't turn this into a "children" key on an object? Would you just transform it into an array? ["foo", { bar: qux }, "baz"] ?
- 90s_dev 1y agoHi, I'm the guy who wrote this proposal. tl;dr: My proposal transforms <foo bar={qux}>bla</foo> into { [Symbol.for('jsx')]: 'foo', bar: qux, children: "bla" } It's self-contained, generic, doesn't rely on imports or globals, and avoids tag key collisions. It's the only way I can imagine it ever being standardized. I currently use JSX for: * Creating custom GUI view objects in https://90s.dev/os/ https://90s.dev/os/ * Using JSX as a convenient & composable string-builder in Node.js via https://immaculata.dev/ https://immaculata.dev/ when generating all my sites at build-time e.g. https://github.com/sdegutis/immaculata.dev/blob/main/site/template/core.tsx https://github.com/sdegutis/immaculata.dev/blob/main/site/te... * Using JSX to generate plain DOM objects in the browser in some of my sites like https://github.com/sdegutis/minigamemaker.com/blob/main/site/app.tsx#L29-L36 https://github.com/sdegutis/minigamemaker.com/blob/main/site...
- WorldMaker 1y agoI think it is still useful as a function call syntax. There's a variety of data structures that people convert JSX to already, including direct-to-DOM. Choosing a blessed one seems harder than a function calling convention, and a function calling convention resembles other language things like tagged templates. I agree that the current "auto-imports" to find that function are nonsense and far too React specific. But the current "global" approach isn't actually "require a global" it is "requires a variable in scope" so it works with "Bring-Your-Own-Import" just fine. We just need a better standard for what that BYOI function is called by default. `React.createElement` is obviously silly. I've been happy in my own projects standardizing on `jsx` as the function name. (It resembles the auto-imports, too, even if I still don't understand why React thought it needed an extra underscore.) I think the biggest tweak that would be nice if we are also wishing for ponies would be a way to set that function per block of JSX like the way that you can tag a template. That would make it far easier than the current per-file or per-project configurations. jsx<foo bar={qux}><zoot>bla</zoot></foo> That doesn't look terrible. Not great either. But I'm sure the big problem with it is that it makes the `jsx < foo` less than versus `jsx<foo />` tag parsing a lot harder. ETA: New idea, what if it was a fake dot tag .< operator? jsx.<foo bar={qux}><zoot>bla</zoot></foo> react.<foo bar={qux}><zoot>bla</zoot></foo> snabbdom.<foo bar={qux}><zoot>bla</zoot></foo> Maybe?
- pwdisswordfishz 1y ago> There has been no push for JSX standardization. https://facebook.github.io/jsx/ https://facebook.github.io/jsx/ is a mirage, apparently.
- 90s_dev 1y ago> *It's NOT a proposal to incorporate JSX into the ECMAScript spec itself.* It's intended to be used by various preprocessors (transpilers) to transform these tokens into standard ECMAScript. (Emphasis theirs.)
- silverwind 1y agoI hope a future standard will allow multiple elements in expression contexts without the need for fragments, or arrays, e.g. const els = <div/><div/>; Compare to current ugly solutions: const els = <><div/><div/></>; const els = [<div/>, <div/>];
- eyelidlessness 1y agoMaybe it’s ugly, that seems like a matter of personal taste. But it’s syntactically unambiguous which is valuable especially for a language which mixes expressions and statements in often very subtle ways. There are also other ambiguities to consider: const trailingIntetpolation = <><div/>{foo}</>; const leading = <>{foo}<div/></>; const bare = <>{foo}</>;
- 90s_dev 1y agoSure and while we're at it why not support `const x = 3 5` also.
- gherkinnn 1y agoNow that I am paid to occasionally write templates in languages other than JSX, I do miss it so much. All the ERBs and ng-for s and handlebars of this world don't remotely come close.
- orta 1y agoThere was some interesting work on standardising on "ESX" in the TC39 discourse that folks in the thread may want to follow: https://es.discourse.group/t/proposal-esx-as-core-js-feature/1511 https://es.discourse.group/t/proposal-esx-as-core-js-feature... Core docs: https://gist.github.com/WebReflection/2d64f34cf58daa812ec876242c91a97c https://gist.github.com/WebReflection/2d64f34cf58daa812ec876...
- elehack 1y agoI like this — JSX is a little annoying to work with outside the major implementations. If this existed, I might not have found the need to make my little Hyperstatic library (https://jsr.io/@mdekstrand/hyperstatic https://jsr.io/@mdekstrand/hyperstatic).
- 90s_dev 1y ago> JSX is a little annoying to work with outside the major implementations There are dozens of us, dozens!