facebook / jsx

The JSX specification is a XML-like syntax extension to ECMAScript.
http://facebook.github.io/jsx/
1.96k stars 133 forks source link

[IDEA] Multiple library targets. #48

Closed trusktr closed 8 years ago

trusktr commented 8 years ago

JSX was designed for writing things like

<ul>
    <li></li>
    <li></li>
</ul>

and converting them into JavaScript like

React.DOM.ul(null, [
    React.DOM.li(null, []),
    React.DOM.li(null, []),
])

Is there anything in the spec about using JSX with different functions for different parts of the tree, and some way to define how to connect those parts of the tree? Maybe it's be some class like JSXAdapter needing to be provided by someone when they wish to switch control of the tree from React to Mithril for example.

Suppose I have a custom renderer made in WebGL called Foo, and I'd love for React users to write declarative scene graphs with Foo. I know that I can just go ahead and use the React API to create components that construct and manipulate a Foo scene graph (and by extension we can now use JSX to write a Foo scene graph), but that isn't compatible with Mithril, Mercury, etc.

Suppose this Foo library has a JSX-compatible functional design, so that it's possible to do this with Foo:

Foo.scene(null, [
    Foo.someThing(null, []),
    Foo.otherThing(null, []),
])

It's not too hard to make JSX compile to a different underlying set of function calls. On that note, it'd be nice if there were some way to connect different UI structures together, as in the following JSX example:

<div>
  <main>
    <Foo.scene>
      <Foo.someThing>
         ...
      </Foo.someThing>
    </Foo.scene>
  </main>
</div>

The underlying function calls could transition from React functions to Foo functions, based on some runtime configuration, where some sort of adapters are specified that tell the runtime how to connect the parts of the tree together. Underneath the hood in some cases, the div and main might be React components, and the inner parts Foo components. In other cases, the div and main might be Mithril components, or Mercury, or etc, while the inner ones are still Foo components.

Does anything like that exist? If not, I think that would be amazing to have, and could potentially open the doors towards easier integration between UI libraries, as described here.

RReverser commented 8 years ago

Note that this it JSX spec repo, which is not attached to any specific implementation, way of transpilation and doesn't limit design to "functional" in any way - it's just syntax which can be transpiled into very different things depending on implementation (e.g. there are implementations that just use createElement with following attribute sets).

Given that, are you sure your issue belongs to the syntactic spec? If so, can you please explain what changes are you requesting?

Thanks.

trusktr commented 8 years ago

Maybe it doesn't belong here. Do you know what I mean though? I wrote more about the idea over here, since it seems like this is less syntax-related than implementation-related. The only thing this would add onto the syntax is some way to be able to distinguish between contexts.

For example, in this JSX snippet:

<React.div>
  <React.main>
    <Foo.scene>
      <Foo.someThing>
         ...
      </Foo.someThing>
    </Foo.scene>
  </React.main>
</React.div>

which is the same as

<div>
  <main>
    <Foo.scene>
      <Foo.someThing>
         ...
      </Foo.someThing>
    </Foo.scene>
  </main>
</div>

if React is set to the default engine (we can omit the React. prefix for those things in that case), we can easily tell which parts are under React's control, and which parts are under Foo's control.

RReverser commented 8 years ago

Well, this is still not a change in syntax - it's already valid JSX, just a different handler, so it belongs to mentioned Babel issue / blog post / etc. or you could try to implement it yourself.