2014/05/21

Polymer.jsを使ってWeb Componentsを試す

Webフロントまわりの開発をやっているとサーバサイドに比べてあまりにも面倒。調べているとWeb Componentsがかなり便利そうだったので調べたものをメモ。

■環境
Google Chrome 35.0.1916.99 beta

■参考ページ
Web Components普及の夜明け!?Polymer.jsを試してみた。
なぜWeb Componentsはウェブ開発に革命を起こすのか

■ライブラリを整える
ライブラリをGitHubから取得する。
まずブラウザの機能補完(Polyfill)ライブラリを取得する
%git clone https://github.com/Polymer/platform.git
次にWeb Componentsの実装Polymer.jsを取得する
%git clone git://github.com/Polymer/polymer.git
独自にコンポーネントを作ることもできるけど、今回は簡単に試すために既にあるパッケージ群(Toolkit-UI)をゲットしておく。
%git clone https://github.com/Polymer/toolkit-ui.git

■ページを作る
Web Componentsを使った簡単なHTML(index.html)をつくる(参考)。
<!DOCTYPE html>
<html>
  <head>
    <script src="polymer/platform.js"></script>
    <script src="polymer/polymer.js"></script>
    <link rel="import" href="toolkit-ui/elements/g-icon.html">
  </head>
  <body>
    <g-icon src="http://www.adamrocker.com/blog/images/category_7.jpg"></g-icon>
    <img src="http://www.adamrocker.com/blog/images/category_7.jpg" id="icon">
  </body>
</html>

<link>タグでg-icon.htmlコンポーネントを読み込む。
<g-icon>はToolkit-UIの中で独自に作られたタグ。このタグを使うとHTML/CSS/JSのパッケージが展開されたかのうように表示される。
Custom Elements/Shadow DOM/Templateあたりの要素技術を使っている。

■ブラウザで表示する
index.htmlをそのままブラウザで開いても何も起きない。
<link> タグのimportがローカルファイルに対応していないのでg-icon.htmlファイルを読み込めないため。
なので以下のコマンドでローカルに簡単なWebサーバを立てる。
コマンドはindex.htmlファイルと同階層で実行する。
%python -m SimpleHTTPServer

ブラウザでhttp://0.0.0.0:8000/index.htmlにアクセスすればアイコンが2つ表示されるはず。1つは24px角の小さなアイコンで、これはg-iconが以下のように展開されている。
<style>
      @host {
        * {
          display: inline-block;
          vertical-align: middle;
        }
      }

      #icon {
        width: 24px;
        height: 24px;
        cursor: pointer;
        background-repeat: no-repeat;
        background-position: center;
        background-size: 100% 100%;
      }
</style>
<div id="icon" style="background-image:url(http://www.adamrocker.com/blog/images/category_7.jpg); width:24px; height:24px">
</div>

<g-icon>が展開されると<div>要素のidがiconだが、index.htmlの<img>要素のidもicon。バッティングしてアウトな感じだが、Shadow DOM内はカプセル化されているので実際は<g-icon>が展開されたidはindex.html内のidに影響しない。当然classとかも。素晴らしい!
Web Componentsが広まれば<link> タグでコンポーネントをimportするだけでWebページの部品が使える世界になる。

  ■Web Componentsとは
HTML/CSS/JSのかたまり。ボタンやアラートやカレンダー、カラーピッカーなど、HTML/CSS/JSのセットで使いまわされるであろう機能部品を1つのかたまりとしてパッケージ化するブラウザ技術。
標準化に向けたW3Cのワーキングドラフト→Introduction to Web Components

Web Componentsはいくつかの要素技術が統合されている。
Template
Mutation Observer
HTML Imports
Custom Elements
Shadow DOM
Object.observe()
Pointer Events
Pointer Gestures
Web Animations

ブラウザネイティブでサポートしているのはごく一部の要素技術だけ。
Chromeでも全ての要素技術をサポートしているわけではない。

■Polymer.jsとは
Web Componentsを使えるようにするJavascriptライブラリ。
ブラウザの差分を埋める(Polyfill)ためにplatform.jsと併用して使う。
それによりWeb Componentsの要素技術が使える数とブラウザが飛躍的に増える。
ブラウザの互換性一覧はコレ→Browser Compatibility

■jQueryと違うのか?
考え方のオリジナルはjQueryっぽい。jQueryが成功しているので足りない部分を補完して、完成度の高いブラウザ標準機能にしようとしているみたい。
足りない部分とは、例えば、jQueryプラグインはHTMLをセットで動く事が多いけどjQueryプラグインの内部にHTMLを加えるには、DOMを作る要領で作ることはできるが…面倒。CSSも加えるとなると更に面倒。そしてクラス名などが他のライブラリとバッティングする事も考える必要が出てくる。そこらへんをまとめてWeb Componentsが面倒を見てくれる。

例えばHTML Importsを使えばHTML/CSS/JSのまとまりを読み込めるので、HTMLの生成をJSで行う必要がなく簡単。

Templateを使えば、HTMLの生成が飛躍的に楽になる。Template技術はサーバサイドでのHTML生成では当たり前に使われている。これは、そもそもWebフロント領域の話なので、これがHTMLだけで何とかなるようになると仕事がめっちゃ楽になる。いちいちサーバサイドのプログラム(JSPとかPHP、Python、Ruby)を弄る必要がなくなる。

Shadow DOMを使えば、HTML/CSS/JSのまとまりをカプセル化できるので、名称の汚染がない。CSSのクラス名などがHTML/CSS/JSのまとまりの中でしか適用されないので他のライブラリやコンポーネントのことを意識する必要がない。