Web Components における依存ライブラリの断片化とエコシステムのコロニー化

あくまで可能性のはなし

あまりポジティブな意味で捉えられないのでタイトルですが、あくまで可能性の話であり、直面するかもしれない問題についての一次考察って感じです。

  1. コンポーネントが依存するライブラリの断片化
  2. ラッパーライブラリによるロックインまたは断絶
  3. その他の妄想

ここでは上記の3点について、つらつら書いてます。

1. コンポーネントが依存するライブラリの断片化

これまで開発者は自身がすべてのコンポーネントを管理するつもりで、ときにミニマルに、ときに富豪的に、依存するライブラリを選定していました。

いつの日か Web Components を前提にしてコンポーネントを選定するときも、個々が依存しているライブラリまでコントロールしきれるかは定かではありません。

依存関係の肥大化は避けたい

例えば npm であればさほど気にならない依存関係の肥大化も、ブラウザで実行されるコンポーネントの場合は、依存リソースの数と大きさはネットワークコストに直結するので何も考えないわけにはいきません。

最悪のケースで想定すると、各々が自由に複数の依存ライブラリを使い、あまつさえ内部から <script> で同じライブラリの違うバージョン、違うCDNからの呼び出しを含んだりすると収集がつかなくなります。

パッケージマネージャへの依存は必要そう

というような依存ライブラリの断片化は、プロジェクト全体の依存関係を管理できる bower のようなパッケージマネージャに適切な情報を提供して、管理を委譲することで十分に解決できるはずなので大きな危機感はありません。

何にせよ留意すべきポイントではあります。(Polymer が <link> の CSS を自動ロードするのは悪手ってことですね)

Web Components を避ける選択肢も残り続ける

Custom Elements に絞って述べると、あれらを使うにはブラウザ上の JavaScript で document.registerElement して登録する必要があります。この仕様は、サーバーサイドレンダリングを求める層には喜ばしくない事実です。

今で言うところの React + node にサーバーサイドレンダリングだとか isomorphic だとかいうメリットを見ているような層は、もしかしたら現状の Web Components に寄りつかないかもしれません。そして、これも断片化のひとつと言えます。

サーバーサイドレンダリングとかisomorphicは、過渡期特有の複雑性だと考えてしまいたい節もある

2. ラッパーライブラリによるロックインまたは断絶

Web Components にまつわるライブラリ話で言うと、ラッパーライブラリの存在が避けて通れません。

Web Components 的にラッパーライブラリは必要

避けて通れない理由としては、Web Components の関連仕様がわりと世間が避けたがる DOM に近いところにあり、抽象化の余地が多分に残されている点があります。

ラッパーライブラリ単位でエコシステムが構築される?

このようなラッパーライブラリが群雄割拠になった場合、ひとつのラッパーライブラリを選んで強固にロックインされるか、複数のラッパーライブラリの併用を強いられるかの選択になります。今の時点でもっとも有力なのは Polymer ですが、これが jQuery のようにキチンと覇権を取るかは定かではありませんし、客観的にはそれを望んでいるとも見えません。

いま考えられるケースは jQuery プラグインのような寡占的エコシステムに乗っかる形態か、grunt/gulp のように各ラッパーライブラリ向けの port を提供する形態でしょうか。

過渡期であるがゆえの断絶

Web Components の知見が未成熟なのか、ラッパーライブラリの方向性が未成熟なのか分かりませんが、なにかと過渡期です。例えばコンポーネント間のメッセージング手段や、React でいう Prop のような attribute 越しの値の受け渡しフォーマットに標準はありません。

Polymer 関連のコンポーネント として <core-signals> はメッセージングの手段としてはロックイン度が高いので使いづらそうですし、<core-style> もスタイルを共有したいのは分かりますが用途に対してロックイン度が高い印象があります。

コロニー的な収束が必要なのか、I/F的な収束が必要なのかはまだ分かりませんが、結局 JavaScript 的に生やした API で何とかする可能性が濃厚なように思います。

3. その他の妄想

これらの諸事情に対して、ライブラリユーザー的なスタンスで取れる付き合い方がいくつか考えられます。

たとえばラッパーライブラリをコンパクトにする

ラッパーライブラリの併用は容易にリソースを圧迫しますが、個々の Web Components ラッパーライブラリがファイルサイズと機能をコンパクトにまとめていれば、それほどの懸念ではなくなるかもしれません。いや、一般的なラッパーとしてはサイズを絞った時点で機能面の差別化が難しくなるでしょうし、あまり意味ないですね・・・。

たとえばグローバルなコンポーネントにライブラリを使わない

アプリケーション固有のコンポーネント(ローカルなコンポーネント)および、それにまつわるエトセトラにのみ強固なライブラリを適用して、広く共有したいコンポーネントにはライブラリを使わないという選択肢もありえます。

たとえば Web Components なコンポーネントの I/F を統一する

前述したようなメッセージングの手段や、値の受け渡し手段にまつわる仕組みを統一する(or 自然と傾向が偏る)というのも必要かもしれません。

コンポーネントであることと、再利用性の範囲

「すべてコンポーネントであれ」という方針をどれくらい実現するのか、コンポーネントがどの範囲で再利用可能にするのかは開発者の手に委ねられています。

ラッパーライブラリが間に入ることによって、コンポーネントの相互運用性が遮られるようであれば、メインライブラリの選定によって断絶してしまう現状とさして変わりはありません。

経験値の不足

開発者としても「コンポーネント」に対する経験値は、絶対的に不足しています。今後、コミュニティが真剣に議論することで現実解に至れると信じつつ、時間をかけて見ていきたいところです。

Polymer さん元気〜?

最後に本題とは関係ありませんでしたが、Polymer 0.8 αlphaリリースと紹介動画っぽいの出てますね。( ˘ω˘)