JavaScript
WebComponents
VirtualDom
WebAssembly
asm-dom

WebAssemblyで実装された仮想DOM asm-dom でWeb Componentsを使ってみた

More than 1 year has passed since last update.


asm-domとは

https://github.com/mbasso/asm-dom

asm-domはWebAssemblyで実装された仮想DOMライブラリです。

asm-domのさわりの記事はこちら

https://qiita.com/kwst/items/e8a2505ec20c5021087b


Web Componentsとは

Web技術で再利用可能でカプセル化されたパーツを作るためのAPI群です。

ライブラリではなくAPIなのでpure JSで書くことができます。各ブラウザでやっと実装が進んできた段階なので、ブラウザに寄ってはまだ実装されていないAPIがあったりします。

MDNによる解説

https://developer.mozilla.org/ja/docs/Web/Web_Components


Web Components は、いくつかの独立したテクノロジーで構成されています。 Web Components は、オープンなウェブテクノロジーを使用して作成された再利用可能なユーザーインターフェイスウィジェットと考えることができます。これらはブラウザーの一部であるため、jQuery や Dojo などの外部ライブラリーは必要ありません。 HTML ページにインポートステートメントを追加するだけで、既存の Web Components をコードを記述することなく使用できます。 Web Components は、新規または今も開発中の標準ブラウザー機能を使用します。



サンプル

サンプルとしてshadow domとcustom elementsを使ったクラスをasm-domでレンダリングします。

コンポーネントクラスはattachShadowでshadow domを使えるようにして、shadowRootの子要素をpatchにかけます。


web-component.js

export default class WebComponent extends HTMLElement {

constructor() {
super();
this.attachShadow({ mode: 'open' });
const n = document.createElement('div');
this.shadowRoot.appendChild(n);
const { h, patch } = window.asmDom;
const vnode = h('div', {}, [ 'This is Web Components' ]);
patch(n, vnode);
}
}

コンポーネントを使う側では、customElements.defineでcustom elementを定義してbodyに追加します。


index.js

import init from 'asm-dom';

import WebComponent from './components/web-component';
customElements.define('web-component', WebComponent);

init({
unsafePatch: true
}).then(asmDom => {
const { h, patch } = asmDom;
const root = document.getElementById('root');
const vnode = h('web-component', {}, []);
patch(root, vnode);
});


サンプルレポジトリ

https://github.com/SatoshiKawabata/asm-dom-example

デモページ


unsafePatchプロパティ

はじめ、asm-domのinit()の引数に何も入れずに立ち上げたらpatch()が上手く動かず、何も表示されませんでした。

unsafePatchをtrueにすることで、oldVnodeではないvnodeをpatch()に渡すことができます。

ここのコードで空のdiv要素と新しいvnodeをpatch()に渡しているので、unsafePatchが必要でした。

const n = document.createElement('div');

const vnode = h('div', {}, [ 'This is Web Components' ]);
patch(n, vnode);

これはWeb Componentsのissueでが動かないよって言ったら教えてくれました。