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

Hyperscript! #62

Open
brainkim opened this issue Apr 25, 2020 · 6 comments
Open

Hyperscript! #62

brainkim opened this issue Apr 25, 2020 · 6 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@brainkim
Copy link
Member

brainkim commented Apr 25, 2020

Someone asked on reddit if we’re going to support hyperscript. I think we could definitely do this and promote it as an alternative to JSX/whatever. The only concern I have is that hyperscript typically has special stuff where they use the CSS syntax to specify id/classes in the tag (h("a#my-link", props, children))? Do we need to implement this to be hyperscript compatible?

@brainkim brainkim added help wanted Extra attention is needed good first issue Good for newcomers labels Apr 25, 2020
@moos
Copy link

moos commented Apr 25, 2020

IMHO this should only be an extension or plugin (same with htm). Hopefully the core can be kept minimal and pristine.

@mcjazzyfunky
Copy link
Contributor

mcjazzyfunky commented Apr 25, 2020

Just my 2 cents:

  • If you need a pure ECMAScript solution then maybe first decide whether you really prefer hyperscipt over a template literal based solution:

      return h('div.box', `Hello, my name is ${firstName} ${lastName}`)

    vs.

      return html`
         <div class="box">
           Hello, my name ist ${firstName} ${lastName}
         </div> 
      `
  • Consider to make the second (=> props) argument of your hyperscript function optional even in the case that there are additional (=> children) arguments.

      return h('p.some-class', 'Whatever')
  • Consider to allow some more advanced hyperscript syntax

    h('.box > ul.link-list[data-flag][data-key=value]',
        h('li.primary > a.link', { href: 'https://www.facebook.com' }, 'Facebook'),
        h('li.secondary > a.link', { href: 'https://www.google.com' }, 'Google'))
  • Consider using an in-memory cache (=> JavaScript object) for the results of the RegExp parsing of the expressions provided by the first argument of your hyperscript function.
    Will be much faster then ... though some guys may just call it "premature optimization" ;-)

  • Heed @moos's wise counsel and don't add that hyperscript function to the core. Use an extra package for that.

@nykula
Copy link

nykula commented Apr 25, 2020

Just having createElement aliased to h, like Preact has, would be a big convenience improvement already.

@brainkim
Copy link
Member Author

@mcjazzyfunky These seem like interesting design ideas but I think it’s more important to follow a spec if there is one.

@nykula If that’s all hyperscript is then you can do this today 😇:

import { createElement as h } from "@bikeshaving/crank";

@nykula
Copy link

nykula commented Apr 25, 2020

For anyone wanting to take h() up, here are some test cases and the simplest initial code to get you started, public domain 😉 Handles only the class names and optional second argument, letting you skip the boring stuff and jump right away to the cool cases @mcjazzyfunky mentioned.
https://gist.github.com/nykula/0575494162a547100b5432938330ebe8

@brainkim Sure, aliasing the import on my side is what I do now, but having to type less in every project is quite a win (: There's just no benefit in a long name for the one function which is called hundreds times more often than any other export, unless cloning React API is on the roadmap. Same goes for renderer.render vs a render shortcut, though much less important.

@mcjazzyfunky
Copy link
Contributor

mcjazzyfunky commented Apr 25, 2020

Some addtional 2 cents of mine if you do not mind:
A couple of years ago I've really been a big fan of hyperscript as I was of the puristic opinion that JavaScript code should be written in pure JavaScript and JSX is obviously not JavaScript.
My opinion has changed completely since then: I do not believe any longer that using hyperscript in JavaScript is a good idea, as JSX is so much easier to use and tooling for JSX is quite sophisticated nowadays.

  • If you use TypeScript => JSX is clearly the best choice then. Hyperscript has really no advantages here but only a lot of disadvantages
  • If you use JavaScript in a project where you are using build tools => JSX is soooo much more fun to work with, for example syntax errors will be shown immediately, while invalid hyperscript expressions will only be detected at runtime. And everything is so much easier to read with JSX.
  • If you use JavaScript in an environment where you DO NOT use build tools => Maybe here hyperscript will be a choice to consider, but when will it nowadays ever happen that your project has no build process?!?

Anyway, for all of you who still think that hyperscript is a great thing to use:
Find here a demo of a hyperscript function for Crank.js that has all the advanced features I was talking about in my comment above (it's a modified version of something I've implemented a couple of years ago). Be aware that this is highly experimental and really ugly and verbose code. For my defense, one reason for the code being so ugly is that the highest priority was performance and unfortunately syntactically nice features like destructing arrays with rest parameter do not perform very well (at least in 2017). So please do not blame me for that code 😉
You will really have to implement your hyperscript function from scratch (or use some other code base - the implementation will be a lot easier if you only implement the standard hyperscript features), but maybe at least this hyperscript implementation could help you someday on comparing performance (btw: This implementation is optimized for Firefox and Chrome and Chromium based Edge ... will not perform that well on IE or older Edge versions).

https://codesandbox.io/s/blissful-heyrovsky-h51y2?file=/src/index.js

[EDIT]: Here's a little parser for standard hyperscript expressions (supporting tagName, id and classes): https://jsbin.com/qerovuvelu/1/edit?js,output
[EDIT]: Maybe I prefer this implementation to the previous one: https://jsbin.com/fivulazuvo/1/edit?js,console

@brainkim brainkim added the enhancement New feature or request label Apr 28, 2020
@brainkim brainkim removed the help wanted Extra attention is needed label Jan 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

4 participants