🍃このブログは移転しました。
3秒後、自動的に移動します・・・。

lit-htmlとhyperHTML

幸か不幸か、この2つについていろいろ調べた機会があったのでメモ。

結果、個人的には、hyperHTML推しです。

はじめに

どっちも聞いたことないな?って人のために、何を目的とした技術なのかを。

これらはReactがやってるみたく、ウェブアプリケーションのViewを構成するコンポーネントを、宣言的に記述するためのライブラリ。

ただReactやらVueはVirtualDOMという抽象化を経る一方、こちらはRealDOMであるのと、JSXとかそういう記法はなく、Tagged Templatesを使ってコンポーネントを書いてく。

まあ実装はさておき書き味としては、めちゃくちゃ薄いReactって感じの立ち位置。
Template Literalで書いたHTMLを関数にわたすと、DOM要素として返してくれたり、実際のDOMツリーに反映してくれたりする。

で、そういう目的をもつライブラリとして白羽の矢が立ったのがこの2つだったわけです。

lit-html

GitHub - Polymer/lit-html: An efficient, expressive, extensible HTML templating library for JavaScript.

まず最初に使ってたのが`lit-html`。
Polymer、もといLitElementのコアということで、名前で決めたところは正直ある。

import { html, render } from 'lit-html';

const helloTemplate = (name) => html`<div>Hello ${name}!</div>`;

render(helloTemplate('Steve'), document.body);

という具合に、SFCライクに文字列から要素を作り出せて、それをDOMに描画するAPIもある。

この描画も賢くて、ちゃんとやれば差分描画してくれる。

ちなみにこの`lit-html`、実は`lit-extended`っていう拡張版がある。

https://polymer.github.io/lit-html/guide/writing-templates.html#lit-html-or-lit-extended

`lit-html`にいくつかの記法が追加されてて、

import { html } from 'lit-html/lib/lit-extended.js';

const Btn = () => html`
  <button
    class$=${}
    disabled?=${}
    on-click=${ev => {}}
  >OK</button>
`;

みたく書ける。

そうそうコレコレ〜欲しかったあの機能たち!
なのでこの関数に引数を渡せば、いわゆる`props`的な使い方もできて、SFCが捗ります。

`lit-extended`があれば、WebComponentsだけでも頑張れるのでは?という気持ちになってくる。

しかし

やっぱり使うのやめました。

なんてことないユースケースやと思うものの、地雷を踏んだのかうまくいかない。

そんなことしてまで使いたくはない!

まぁそこまで使い込んでないのでいまいち確信は持ててないけど、なんか運が悪かったんやろうね・・。

ちなみに当時のバージョンは`0.10.0`でした。

hyperHTML

GitHub - WebReflection/hyperHTML: A Fast & Light Virtual DOM Alternative

そういうわけで、日本ではまったく話題になってないけど、今の個人的なイチオシとなったのがコレ。

立ち位置としては、`lit-html`よりも先発のライブラリで、ProductionReadyとのこと。作者による比較Gistもある。

https://gist.github.com/WebReflection/fadcc419f5ccaae92bc167d8ff5c611b

試しにさっきの`lit-html`のコード例を全部置き換えてみるとこうなる。

import { wire, bind } from 'hyperhtml';

const helloTemplate = name => wire()`<div>Hello ${name}!</div>`;

bind(document.body)`${helloTemplate('Steve')}`;

const Btn = () => wire()`
  <button
    class=${}
    disabled=${}
    onclick=${ev => {}}
  >OK</button>
`;

てな具合でほぼ遜色ない感じ。

  • `render`が`bind`になって
  • `html`が`wire`になっただけ
  • 属性の末尾に`$`つけなくてもよくなったり

と、いい事づくしなのに、`lit-html`で起こってた描画のバグも発生しなかったので、これがProductionReadyってやつか!ってなった。

SSRするためのモジュールとして、`viperHTML`ってのまで用意してあって、本気度が伺えますね。

GitHub - WebReflection/viperHTML: Isomorphic hyperHTML

というわけで、もうしばらく使いこんでみるので、`hyperHTML`についてはまた記事を書くかも。