dackdive's blog

新米webエンジニアによる技術ブログ。JavaScript(React), Salesforce, Python など

[GAS] Google Apps Script の HtmlService で Polymer を使う

先日の HTML5 Conference に参加して Polymer を触ってみたくなった。

せっかくなので先日勉強した Google Apps Script の HtmlService で Polymer を使えないかなーと色々模索してみたので、メモ。

はじめに

Google Apps Script + Polymer については公式 Developer Blog でサンプルアプリケーションを紹介している。

G Suite Developers Blog: Speeding up HtmlService in Apps Script

このアプリは参考にはなるんだけど、
独立した web アプリではなく docs のアドオンとして作っているため
独立した web アプリにするために色々やってみた。
(HtmlService で作るアプリケーションの種類については このあたり に書かれている)

まずはコードから

最終的にできたものはこちら。
なお、Polymer アプリケーションはこちらのチュートリアルのものを利用してます。

http://itshackademic.com/static/codelabs/ja/1-polymer-first-app/#1

ポイント

ファイル構成は ベストプラクティス に従う

必須ではないが、メインの html と css, javascript をそれぞれ別ファイルにしてる。

├── index.css.html
├── index.html
├── index.js.html
└── Code.gs

(各ファイルのファイル名は任意)

で、index.htmlcss, js をインクルードします。

<!DOCTYPE html>
<html>
    <head>
       <?!= include('index.css'); ?>
   </head>
    <body>
        <?!= include('index.js'); ?>
    </body>
</html>

この include() はサーバーサイドのスクリプト (Code.gs) で定義してるやつですね。

function include(filename) {
    return HtmlService.createHtmlOutputFromFile(filename)
        .setSandboxMode(HtmlService.SandboxMode.IFRAME)
        .getContent();
}

Polymer ライブラリは CDN がないので外部から無理矢理ロードする

これがなかなかつらいところなんだけど、Polymer はまだ CDN でロードすることができないため
サンプルアプリケーションにあった URL から読み込んでいます。

なお、この URL は GAE 上に Polymer を静的リソースとして丸ごとアップロードしておいて、そこから読み込むようにしているよう。

<html>, <head>, <body> などのタグは "使用する"

これ、ベストプラクティスとは真逆のことをやっているんだけど。
Don't use ... のところの冒頭をよく読むと

If your page is sanitized by Caja instead of the newer IFRAME sandbox mode, ...

とあり、IFRAME モード ではない 場合のことらしい(と解釈)。
特に理由がなければ SandboxMode は IFRAME を使うべきっぽいし、<head> タグとかないと Polymer ライブラリの読み込みがうまくいかなかったので通常の html っぽく書いてます。

(おまけ)開発はローカルで、gas-managerでデプロイ

Google Apps Script の開発手法については色々議論されてますが
私は gas-manager というツールを使って vim で書いたコードをアップロードしています。

ツールについてはこちらの記事を参考にしていただければ。

(おまけ)作成したGASを独立したwebアプリとして公開するまで

先日の記事に記載。

TODO

なんか開いた時にエラー出てる。。。

f:id:dackdive:20150206011437p:plain

Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "https://script.google.com" from accessing a frame with origin "https://n-4p3ayflbzam3uw5cvxhskx3oudoovn3pullzafi-script.googleusercontent.com". Protocols, domains, and ports must match.

調べてもわかんなかったのと、とりあえず動いてるので保留。

リファレンス

Check! Google Apps Script - UIの実装は HtmlService + Polymer の利用が主流に? - Qiita