幸か不幸か、この2つについていろいろ調べた機会があったのでメモ。
結果、個人的には、hyperHTML推しです。
はじめに
どっちも聞いたことないな?って人のために、何を目的とした技術なのかを。
これらはReactがやってるみたく、ウェブアプリケーションのViewを構成するコンポーネントを、宣言的に記述するためのライブラリ。
ただReactやらVueはVirtualDOMという抽象化を経る一方、こちらはRealDOMであるのと、JSXとかそういう記法はなく、Tagged Templatesを使ってコンポーネントを書いてく。
まあ実装はさておき書き味としては、めちゃくちゃ薄いReactって感じの立ち位置。
Template Literalで書いたHTMLを関数にわたすと、DOM要素として返してくれたり、実際のDOMツリーに反映してくれたりする。
で、そういう目的をもつライブラリとして白羽の矢が立ったのがこの2つだったわけです。
lit-html
まず最初に使ってたのが`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だけでも頑張れるのでは?という気持ちになってくる。
しかし
やっぱり使うのやめました。
なんかよくわからんけど、lit-htmlのrenderに自作のcustom elementsを渡した場合、その要素のconnectedCallbackが謎いタイミングで呼ばれて、自身のルート要素が空っぽ(attrもtextContentも)になる・・気が・・する・・
— りぃ (@leader22) June 11, 2018
なんてことないユースケースやと思うものの、地雷を踏んだのかうまくいかない。
秘技rAFで挟むするとうまく描画されることが判明してしまった
— りぃ (@leader22) June 11, 2018
そんなことしてまで使いたくはない!
まぁそこまで使い込んでないのでいまいち確信は持ててないけど、なんか運が悪かったんやろうね・・。
ちなみに当時のバージョンは`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`ってのまで用意してあって、本気度が伺えますね。
というわけで、もうしばらく使いこんでみるので、`hyperHTML`についてはまた記事を書くかも。