-
Notifications
You must be signed in to change notification settings - Fork 35
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
Create element instances, then resolve to strings #6
base: master
Are you sure you want to change the base?
Create element instances, then resolve to strings #6
Conversation
8b46ec0
to
11451ed
Compare
This is a really slick idea! I'm wondering about performance and compatibility though - thinking this now requires any consumer to cast to a String (at least implicitly) whereas before that was unnecessary. Also for perf there are now intermediary objects being created that could cost (though I've seen this can sometimes have the opposite effect too). I'm curious - do you think this is a large enough change that it would warrant a second project? I'd love to have a direct jsx-to-string renderer and a more react/preact-compatible stateless string renderer. The latter is interesting since it's really an optimization of preact-render-to-string, which takes in Preact VNode objects and builds up an HTML/XML string. Thoughts on the two project idea? |
11451ed
to
26c4842
Compare
Yeah, I agree that keeping vhtml as a direct-to-string renderer is a good thing. I was already thinking about a 3 project approach, where there's room for a slightly more enhanced build of vhtml on the spectrum from vhtml < new project < Preact. New project could include the object elements in this PR, and the In theory, a lot of the codebase between vhtml and new project could be shared, it could be structured as an alternate Rollup build. |
Agreed, I had wondered if it would be worth doing second entrypoint in vhtml for that. I'm fine with either approach really. If we split some of the functions up into files, the two could share quite a bit of them. |
Sounds good to me. Let me take a swing at re-working this PR as a second entrypoint and see how it looks. If it feels too contrived it'll be easy to split apart completely. |
@developit Do you have any feelings about the other PRs to work towards this goal? Deciding whether to focus my efforts on your project or a new one of my own. |
I'm not sure of others, but my use case for vhtml is to be able to have all of React's ease of development without any state whatsoever. (And also an easy upgrade path should the project warrant React in the future.) So whatever project has this feature is the one I want to use. The same goes for the aforementioned style object helper. If y'all think that's a level-up from vhtml, so be it... But is there anyone using vhtml that wouldn't rather have these features? I can't imagine anyone willing to forgo them. |
@nathancahill did you get anywhere with this? Perhaps publishing the 2 projects from the same repo with a shared codebase would be a nice middle-ground? |
Updated with new approach
This PR changes the behavior of
h()
from immediately executed functions, to a function that first creates element instances, and then later resolves them to a string. This means that JSX is now executed in a top-down order, instead of executing the most deeply nested function first. This also makesprops.children
an array of elements (instead of resolved strings), that can be manipulated similar to React.Children.Consider this JSX:
The current execution order is:
Image(), Heading(), Body(), Article()
. This PR switches that to the "expected"Article(), Heading(), Body(), Image()
.An example using new
props.children
:Output:
Semi-breaking Changes
The public JSX/vhtml API must be explicitly cast to a string. The element object uses
toString
to output the HTML.innerHTML = <Article>
still works because innerHTML casts to a string.Size: + 56 bytes, from 580 bytes to 636.
I believe this makes vhtml more consistent with other JSX implementations like React/Preact. It's certainly much more powerful, at the cost of 56 bytes.