2018/01/18
GoogleAppsScriptでReact+TypeScriptのウェブアプリケーションを作ろう ― 第2回 実装編 ―
目次
お久しぶりです、ものねこです。前回に引き続き、GoogleAppsScript(以下GAS)でウェブアプリケーションを構築していきます。
前回はGASでウェブアプリケーションを公開する方法を確認しました。今回は、ローカルでGASのプロジェクトを管理する環境を構築して、Googleのリモート環境(以下リモートと表記します)にアップロードするまでの手順を紹介します。
GASはJavaScriptをベースとした言語なので、ローカルではJavaScriptのプロジェクトとして管理できます。そこで、JavaScriptのパッケージ管理ツールであるnpmを使って環境を構築します。TypeScriptのコンパイル環境まで構築して、改修が見込まれるクライアントサイドのソースコードはTypeScriptで管理できるようにしましょう。
npmについて知りたい方にはこちらの記事がおすすめです。
また、npm(node.js)の導入についてはこちらの記事を参考にしてください。
今回の作業手順は次のとおりです。
- node-google-apps-scriptのインストール
- Google Drive APIの有効化と認証
- React+TypeScriptの導入
- React+TypeScriptのソースコード作成
- リモートへのアップロード
早速進めていきましょう。
1. node-google-apps-scriptのインストール
今回の環境構築のキモは、Googleから提供されているnode-google-apps-scriptというnpmのパッケージです。このパッケージを使うと、ローカルのJavaScriptをリモートにアップロードできるようになります。まずはnode-google-apps-scriptを導入しましょう。
1 |
$ npm install -g node-google-apps-script |
オプションの -g
はグローバルインストールを意味していて、ユーザディレクトリ直下の.node_moduleディレクトリにnode-google-apps-scriptがインストールされてパスが通るため、コマンドgappsが使用できるようになります。
2. Google Drive APIの有効化と認証
次に、プロジェクトをアップロードできるようにGoogleのDrive APIを有効化します。
前回作成したGASプロジェクトを開き、タブメニューから[リソース]→[Cloud Platform プロジェクト]→上部のプロジェクトのリンクをクリックします。
Google Cloud Platformページが開かれるので、左部の[APIs&Services]→[ライブラリ]をクリックします。
すると、Google Cloud Platformで使用できるAPI群が表示されるのでDrive APIのアイコンをクリックし、遷移先のページで[有効にする]ボタンをクリックします。
続けて左部の[認証情報]→[認証情報を作成]→[OAuth クライアントID]をクリックします。ラジオボタンでアプリケーションの種類を「その他」に設定し、適当な名前をつけてキーを作成します。これでGoogle側のプロジェクトのアップロード設定は完了です。
OAuth2.0クライアントIDの一覧右部から認証用のjsonファイルをダウンロードします。
ダウンロードした認証ファイルを利用して、ローカルで認証します。
1 |
$ gapps auth [ダウンロードした認証ファイルのパス] |
とします。ワンタイムURLが表示されるので、任意のブラウザでアクセスすれば、認証されます。
1 |
Please visit the following url in your browser (you'll only have to do this once): https://accounts.google.com/hogehuga Successfully Authenticated with Google Drive! |
いよいよプロジェクトを作成します。任意の場所にプロジェクト用のディレクトリを作成し、そのディレクトリ直下に移動して
1 |
$ gapps init [スクリプトID] |
としてください。スクリプトIDはGASプロジェクトの上部メニューから[ファイル]→[プロジェクトのプロパティ]で参照できます。./src下に現在のGASプロジェクトがダウンロードされます。そして、./src下のファイルを編集して
1 |
$ gapps upload |
とすれば./src下のソースコードがアップロードされる状態になっています。
ちなみにリモートのgsファイルはローカルではjsファイルに、ローカルのjsファイルはリモートではgsファイルに自動変換されます。
3. React+TypeScriptの導入
ソースコードがアップロードできるようになったので、React+TypeScriptのアプリケーション開発環境を整えましょう。
WebpackというJavaScriptのモジュールバンドラを使用して、TypeScriptで記述したReactを一つのjsファイルにまとめるように設計します。全く同じ環境構築についてTypeScriptの公式サイトがドキュメントを提供しているので、参考にして進めていきます。
最初に、GASのアップロードが設定されたディレクトリをnpmプロジェクトにします。
1 |
$ npm init -y |
ディレクトリ直下にnpmの設定ファイルである./package.jsonが作成され、./node_module以下にnpmのパッケージがインストールされるようになりました。node-google-apps-scriptはデフォルトで./src下をアップロード対象として認識するため、./srcはこのままにして、./app下にTypeScriptのソースを記述していくことにします。
1 |
$ mkdir app |
次に、必要なパッケージをインストールしていきます。
Webpackをインストールします。
1 |
$ npm install -g webpack |
これにより、コマンドwebpackが使用できるようになります。
続いてReact・TypeScriptとTypeScriptのReact用型定義ファイル・Webpackに必要な追加パッケージをインストールします。
1 |
$ npm install -S react react-dom typescript @types/react @types/react-dom awesome-typescript-loader |
オプションの-Sはプロジェクトへのインストールを意味します。上記のパッケージはプロジェクトごとに必要なものなので、プロジェクトディレクトリ直下の.node_moduleディレクトリにインストールします。
TypeScriptをインストールして、プロジェクトディレクトリ直下にTypeScript用の設定ファイル(tsconfig.json)を作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "compilerOptions": { "outDir": "./src/", "sourceMap": false, "noImplicitAny": true, "module": "commonjs", "target": "es5", "jsx": "react" }, "include": [ "./app/**/*" ] } |
さらにWebpack用の設定ファイル(webpack.config.js)を作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
module.exports = { entry: "./app/index.tsx", output: { filename: "bundle.html", path: __dirname + "/src" }, resolve: { extensions: [".ts", ".tsx", ".js", ".json"] }, module: { rules: [ { test: /\.tsx?$/, loader: "awesome-typescript-loader" } ] } }; |
これらの設定により、プロジェクトディレクトリ直下でコマンドwebpackを打つと、./app下のindex.tsxを探して読み込んで、依存するファイルがまとめられ、./src下にbundle.htmlが生成されるようになりました。
Webpackではjsファイルが生成されるところ、なぜ拡張子をhtmlとしているのかというと、GAS上のhtmlファイルで参照できるプロジェクト上のファイルがhtmlファイルに限られているからです。今回は出力されたbundle.htmlのソースコードの先頭と末尾に
<script></script>タグを追記して、htmlファイルとして認識されるようにします。
bundle.htmlを読み込むスクリプトをindex.htmlに追記します。
1 2 3 4 5 6 7 8 9 10 |
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <div id="app"></div> <?!= HtmlService.createHtmlOutputFromFile('bundle').getContent(); ?> </body> </html> |
またindex.htmlにスクリプトを記述するため、doGet関数でHTMLファイルをテンプレートとして読み込むよう書き換えます。
1 2 3 |
function doGet() { return HtmlService.createTemplateFromFile('index').evaluate(); } |
4. React+TypeScriptのソースコード作成
あとは、./app下にindex.tsxをエントリーとしてReactファイルを作成すれば動作します。
1 2 3 4 5 6 7 8 9 |
import * as React from "react"; import * as ReactDOM from "react-dom"; import { Hello } from "./Hello"; ReactDOM.render( , document.getElementById("app") ); |
1 2 3 4 5 6 7 8 9 |
import * as React from "react"; interface HelloProps { company: string; user: string; } export class Hello extends React.Component<HelloProps, {}> { render() { return <h1>こんにちは、{this.props.company}の{this.props.user}です!</h1> ; } } |
5. リモートへのアップロード
以上のファイルを作成したら
1 |
$ webpack |
生成されたsrc/bundle.htmlのソースコードの先頭と末尾に<script></script>を追記します。
1 |
$ gapps upload |
とすれば、リモートに必要なファイルがアップロードされます。
前回同様[ウェブアプリケーションとして導入]から版を新しくして公開しなおせば、Reactが動作していることが確認できるはずです。
早足でしたが、以上が最小限の構成でReact+TypeScriptでGASのウェブアプリケーションを動かすための手順です。GAS上で動かすウェブアプリケーションではGoogleのAPIを利用できるので、様々なアプリケーションを開発できます。もし興味がありましたら、いろいろと試してみてください。