JSX: XML-like syntax extension to ECMAScript – Draft specification
facebook.github.io
facebook.github.io
Laverdet also implemented something similar for node.js called js-xml-literals[3], which I don't think has gained much traction. As for how it's different from E4X, refer to this page[4], which makes the argument that parsing and producing XML are two different tasks; E4X attempts to do both while all of these other approaches focus on producing XML.
(I don't think that this perspective on the history of react.js/jsx has been well-publicized before, hence the post.)
[1]: https://www.facebook.com/notes/facebook-engineering/xhp-a-ne...
[2]: http://codebeforethehorse.tumblr.com/post/52824249342/buildi...
[3]: https://github.com/laverdet/js-xml-literal
[4]: https://github.com/laverdet/js-xml-literal/wiki/Differences-...
With Facebook's brand and recognition, I am sure this JSX will eclipse the other JSX, which is rather unfortunate.
One of the biggest use cases for Javascript is to manipulate and create DOMs. jQuery solved the manipulation part beautifully, but DOM creation remained a hassle. Lots of templating solutions have been attempted, but none of them seem to hit the sweet spot just right (that's a primary reason why there are so many).
JSX is a novel contender that may be just right - even if it's not, it will hopefully push us as a community towards a better solution by offering a very new approach with its own benefits and problems.
Thanks to the peeps at fb for taking the time and effort to make JSX bigger than just reactjs!
JSX is handy because it allows authors to think about the hierarchical relationship of components in terms of how they would be laid out in something like HTML. Template literals may not be ideally suited to the JSX case, but they represent a promising "native" solution to the problem JSX tries to solve. I'm always happier when I can leverage something that is native to the language I'm using to solve a problem.
https://github.com/jlongster/jsx-reader
(Hey React guys... I know you know of my project, what's up with that?)
Can someone with a better understanding explain what the benefit is here? It doesn't seem easier than JS or HTML so I don't understand the point of the abstraction. But I haven't built much on the browser-side in a few years so I am certain I am missing something.
We're stuck with JS, so it's convenient to have a declarative syntax that compiles to JS, because nested function calls suck. As the doc states:
> The purpose of this specification is to define a concise and familiar syntax for defining tree structures with attributes.
This can be used for anything, it has nothing to do with HTML actually. Just like there are many languages and frameworks where you describe UIs with some flavor of XML that compile behind the scenes to API calls to create windows, append buttons, etc.
Well, it wouldn't be that perfect, because then we'd be forced to live with that Lisp (lack of) syntax.
if test-form then-form [else-form]
Examples: (if foo 1 2)
(if foo 1)
That means: after IF there are exactly two or three expressions.LET looks more complicated:
let ({var | (var [init-form])}*) declaration* form*
Example: (let ((foo 10) bar)
(declare (integer foo))
(setq bar foo)
foo)
Note, the notation with parentheses is not the syntax of the Lisp programming language, but of symbolic expressions. The Lisp syntax is defined on top of s-expressions. Not every s-expression is a valid Lisp program.For example the following are not valid Lisp expressions, but still valid s-expressions:
(if foo 1 2 (3) (4))
(let a (declare (integer 10)) 3 + a)... then someone would invent LispScript; later it turns out LispScript sucks as a declarative syntax, so someone else would invent LSX that compiles to LispScript that compiles to LISP :)
var React = require('react')
var other = require('../other-control')
var { div, h2 } = React.DOM;
module.exports = React.createClass({
render: function(){
return div({className="foo"}, [
h2(null,'My playa'),
other()
]);
}
});
I don't use the JSX syntax, for testability, coffee-script can be a lot cleaner... With multiple components in a larger application and webpack it gets really nice.http://en.wikipedia.org/wiki/ECMAScript_for_XML
Brendan Eich was quoted as saying something along the lines of "E4X is crazyland". Parsing it is hard as hell to do right. Think of all the tooling that's out there for JavaScript right now that will either a.) not support JSX code or b.) bloat up beyond belief as it takes into account the suddenly absurd requirements necessary to deal with a similar-but-not-quite-XML-or-even-HTML-for-that-matter syntax. Oh, you want to lint that JavaScript? Bless your heart! You want to add syntax highlighting? Love will find a way. You want to use other static analysis tools, sweet.js macros, or anything else non-trivial? How cute!
So essentially, it's a great way for Facebook to push React.js without making React.js a standard.
Work with both JSX and regular JS in React and you'll see why they're doing this.
I had the pleasure of being the person who removed support for it from Mozilla's codebase: https://bugzilla.mozilla.org/show_bug.cgi?id=788293. Over 11,000 lines of code removed. Everyone on Mozilla's JS team was happy to see that code gone, because it had caused endless problems over the years.
I gained even more joy when I discovered that this removal had temporarily inconvenienced the NSA: https://bugzilla.mozilla.org/show_bug.cgi?id=788293#c74.
Also, you somehow managed to imply that JSX makes it impossible to use sweet.js macros. There's a sweet.js implementation of JSX, so that's absolutely bollocks. https://github.com/jlongster/jsx-reader
So was Harmony. And then it was ressurected.
>Brendan Eich was quoted as saying something along the lines of "E4X is crazyland"
I don't think Brendan Eich has his finger in the pulse of the modern web, so to speak.
I guess there's an argument for everything. But I thought in general, people usually found XML's verbose endings to be noisy and useless. It could always be opt-in, so you only need to add them where needed.
<start><item>something</>...</start>
Or you could just add a comment.Why are nearly all the examples pushing literal UI concerns into the code, if not tightly weaving it with the controller?
I see what it is, but I see nothing about why it is - I'm open for understanding. Someone please help.
['div', {id: 'main'},
['h1', 'Some title'],
['p', 'Some text']]
I wrote a little function to turn this kind of thing into an html string (https://github.com/twfarland/don), but it could also be used as the view descriptor for some kind of view component ala React. Might work on that...JSX -> JS -> JSX
Just JS gets committed into the repository.
When the developer likes/needs JSX he just uses the JSX like an overlay for a specific code part.
The great thing about JSX is that it doesn't build markup. It doesn't even need to be used for markup, it can be used for anything. It's frequently associated with markup because it has been used alongside React, but JSX standalone is a simple syntactic transform for XML-ish notation to JavaScript.
This is quite convenient in some cases, as you can elegantly write DSL's, where each of the tag names are JavaScript functions - and writing the equivalent JavaScript would look something closer to a lisp (moving the function name to the right of the paren).
This:
<Database name="business">
<Table name="user">
<Column name="id" type='int' length={10} />
<Column name="first_name" type='string' length={255} />
<Column name="last_name" type='string' length={255} />
<Column name="choice" type='enum' values={['a', 'b', 'c']} />
</Table>
<Table name="account">
<Column name="id" type='int' length={10} />
<Column name="first_name" type='string' length={255} />
<Column name="last_name" type='string' length={255} />
<Column name="choice" type='enum' values={['a', 'b', 'c']} />
</Table>
</Database>
run through the compiler[1] becomes this: Database({name: "business"},
Table({name: "user"},
Column({name: "id", type: "int", length: 10}),
Column({name: "first_name", type: "string", length: 255}),
Column({name: "last_name", type: "string", length: 255}),
Column({name: "choice", type: "enum", values: ['a', 'b', 'c']})
),
Table({name: "account"},
Column({name: "id", type: "int", length: 10}),
Column({name: "first_name", type: "string", length: 255}),
Column({name: "last_name", type: "string", length: 255}),
Column({name: "choice", type: "enum", values: ['a', 'b', 'c']})
)
)
I find the first easier to read / reorganize in blocks, which can be useful in lots of situations... definitely not all situations - but having declarative markup while being able to imagine it executing as the latter, constructing actual JS objects with specific logic built in - rather than needing to "parse" the XML tree and deal with an extra step of execution, etc, etc.I'd be much happier with s-exps and JSON is close enough.
But not necessarily the same translation as in your example (that is, tags to function calls and attributes to first arguments). Perhaps all existing implementations work like that, but the spec leaves the JavaScript representation undefined. The spec draws attention to this intentional ambiguity when it lists “a set of transpilers that all conform to the JSX syntax but use different semantics on the output”.
http://facebook.github.io/react/docs/displaying-data.html#js...
We strongly believe that components are the right way to separate concerns rather than "templates" and "display logic."
Maybe I'm missing the point here (I come from a background in AngularJS).
Edit: I'm reading up on React and can see the arguments against strictly templating. Makes sense now!