Polymer で作ったアプリケーションが Chrome 以外のブラウザで動かないとき、原因の 1 つとしては Polyfill がうまくロードされていない可能性があります。

polymer-cli の雛形
polymer-cli でアプリケーションの雛形を作ったとき、index.html
は以下のような感じになります。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
<title>hoge app</title>
<meta name="description" content="hoge app description">
<!-- See https://goo.gl/OOhYW5 -->
<link rel="manifest" href="/manifest.json">
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="/src/hoge-app/hoge-app.html">
</head>
<body>
<hoge-app></hoge-app>
</body>
</html>
ここで、/bower_components/webcomponentsjs/webcomponents-lite.js
が Polyfill で、WebComponents API をサポートしてないブラウザでも Polymer で作ったアプリケーションが動くようにするライブラリなのですが、このまま polymer build
しても、この /bower_components/webcomponentsjs/webcomponents-lite.js
はビルドに含まれません!!!!!
どうするか
Polymer のビルドの設定ファイルとして、polymer.json
というものがあります。ここに依存ファイルとして /bower_components/webcomponentsjs/webcomponents-lite.js
を追記すれば OK です。
polymer.json
の書き方については私もよく理解してはいないのですが、 https://www.polymer-project.org/1.0/docs/tools/polymer-cli#build を参考に書いていけばいいでしょう。例えば私が作ったソートアルゴリズムを可視化するアプリケーション 1 の polymer.json
は以下のような感じになりました:
{
"entrypoint": "index.html",
"shell": "src/sort-app/sort-app.html",
"fragments": [
],
"includeDependencies": [
"bower_components/webcomponentsjs/webcomponents-lite.js",
"bower_components/webcomponentsjs/webcomponents-lite.min.js"
]
}
このようにすれば、きちんと Polyfill が読み込まれ、Firefox などの他のブラウザでもうまく動くかと思います
Polyfill の条件別ロード
公式サイト (https://www.polymer-project.org/1.0/docs/browsers) ではクライアントサイドで Polyfill が必要かどうか判別して、必要なときのみロードする方法が推奨されているので、やっていきましょう。
まず、index.html
の <script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
をコメントアウトしておきます:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
<title>hoge app</title>
<meta name="description" content="hoge app description">
<!-- See https://goo.gl/OOhYW5 -->
<link rel="manifest" href="/manifest.json">
<!-- <script src="bower_components/webcomponentsjs/webcomponents-lite.js"></script> -->
<link rel="import" href="/src/hoge-app/hoge-app.html">
</head>
<body>
<hoge-app></hoge-app>
</body>
</html>
次に、公式サイトのソースコードをコピペします2:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
<title>hoge app</title>
<meta name="description" content="hoge app description">
<!-- See https://goo.gl/OOhYW5 -->
<link rel="manifest" href="/manifest.json">
<!-- <script src="bower_components/webcomponentsjs/webcomponents-lite.js"></script> -->
<link rel="import" href="/src/hoge-app/hoge-app.html">
</head>
<body>
<hoge-app></hoge-app>
<script type="text/javascript">
(function() {
if ('registerElement' in document
&& 'import' in document.createElement('link')
&& 'content' in document.createElement('template')) {
// platform is good!
} else {
// polyfill the platform!
var e = document.createElement('script');
e.src = 'bower_components/webcomponentsjs/webcomponents-lite.min.js';
document.body.appendChild(e);
}
})();
</script>
</body>
</html>
これで、Polyfill が不必要なブラウザでは余計なロードが発生しなくなりました
-
デモ: http://kumassy.com/sort/ ソースコード: https://github.com/Kumassy/sort_visualizer ↩
-
よく見るとソースコードが公式サイトのものとちょっと違って、
'/bower_components/webcomponentsjs/webcomponents-lite.min.js'
ではなく'bower_components/webcomponentsjs/webcomponents-lite.min.js'
としています。これはアプリケーションを GitHub Pages にデプロイするためです。 ↩