Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Templating Proposal with JSX #3252

Open
christopherjbaker opened this issue May 12, 2017 · 5 comments
Open

Templating Proposal with JSX #3252

christopherjbaker opened this issue May 12, 2017 · 5 comments

Comments

@christopherjbaker
Copy link
Contributor

TLDR

Use JSX because JSX is awesome. Also, no runtime ast parsing, so possibly more performant and smaller.

Details

JSX code is transpiled to calls to a particular function, (defaults to React.createElement, but can be switched with an @jsx pragma on a per-file or per-function basis). This does mean that any inline jsx would need to require the viewJSX function and include the pragma. Standalone files (like *.stache) would just be the jsx itself, and the require, functions, and pragma could be added by the loader. That function is called with the tagName as the first paramater, the properties as the second (an object, or null if no properties), and any children as the following arguments.

Note: within React, there are differences between JSX and HTML, mainly the use of className over class, but this is standard they adopted rather than an implicit requirement. No such limitation would exist in a jsx-based tempating system.

Events

For representing events, I would propose using onFoo syntax. <div onClick={ vm.onClick } />

Binding

One of the complications here regarding binding is that the runtime use is via function calls, and the values are grabbed, so the connection to the parent object is lost each time. This is fine for unbound values, but would interfere with binding. To solve that, I would propose an extra set of getters on CanDefine objects, which return computes or observables instead of the actual values, something like viewModel.$foo. While there would be a small performance hit here, I don't think it would be very significant.

I would propose the use of $ or _ as a prefix or suffix in order to specify binding, though I'm not crazy about it and would be open to other suggestions. <div $foo={ vm.$foo } /> <div foo$={ vm.$foo } /> <div $foo$={ vm.$foo } /> (to parent, to child, two way) <div foo={ vm.$foo } /> (two way shortcut, for when a compute is provided but no $ are present on the key)

Example

/** @jsx viewJSX */
let renderer = makeRenderer((vm) => (
  <div class="foobar">
    { vm.things.map(thing => (
        <div>{ thing }</div>
    )) }
    <div $_foo="bar" />
  </div>
));

let frag = renderer({ things: [ 1, 2, 3 ] );
@christopherjbaker christopherjbaker changed the title Templating Proposal Templating Proposal with JSX May 12, 2017
@justinbmeyer
Copy link
Contributor

justinbmeyer commented May 13, 2017 via email

@matthewp
Copy link
Contributor

@christopherjbaker Does your proposal differ from #3042? It appears to be the same to me.

@christopherjbaker
Copy link
Contributor Author

@matthewp I confess I had not seen that that proposal. I looked at comments on #2995 but didn't realize it was an epic and that there were other attached proposals. In structure, it is not different.

I had seen hypertext before, though did not consider using it to handle can rendering. Would we be able to get performance comparable to can-stache without direct control? Or were you just proposing to using their structure (ala can-stach vs mustache)?

@phillipskevin
Copy link
Collaborator

@christopherjbaker You can take a look at can-hyperscript if you're interested, but it is using a lot of the same internals as can-stache (can-view-live being the big one).

One of the biggest performance pieces is how it handles rendering lists. I got this to work by overwriting the .map function to use can-view-live.list, which isn't a perfect solution but does provide similar performance to can-stache. It's hard to give a full comparison of performance between can-stache and something like can-hyperscript in the state it is in, but there aren't any glaring reasons why we wouldn't be able to optimize rendering performance of can-hyperscript.

One caveat, though, is that we wouldn't be able to support streaming using something like can-hyperscript.

@justinbmeyer
Copy link
Contributor

I think this is still a good idea.

@justinbmeyer justinbmeyer reopened this Dec 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants