GASをモダンな環境で開発したい!!
何がやりたいの?
GASを普通に開発すると、GASが用意したブラウザ上の専用のエディタを使う必要がある。簡単な作業をするにはさほど問題は発生しないが、ある程度規模があるものを作ろうとすると結構辛い。なので、中規模程度の開発を想定したGAS開発環境を作成してみた。
説明しない事
- GASにおけるコードの書き方
- JavascriptやTypescriptの解説
- 各種ツールの使い方
どんな事をしたの?
- 専用エディタじゃなくてVSCodeで開発できるようにした
- JavaScriptだと辛いのでTypeScriptを使用できるようにした
- モジュール化できるようにした。
御託は良いから使わせろ
うぃ・w・/(リポジトリ)
README.mdの通りに操作したらとりあえず使えるはず
どんな工夫をしたの?
ここからは私が開発環境を作るのに工夫した事を記述していく。
ここから記述する内容は、先ほど紹介したリポジトリの使い方ではない事を留意して欲しい。
とりあえずローカルとGASを紐づける
ローカルとGASを紐づけるには、claspなるものが必要。
Claspって?
「Command Line Apps Script Projects」、略してClasp。
GASプロジェクトをローカル環境で開発する為の公式CLIツール。
これによってVSCodeとかでコードの開発ができるようになる。
Claspの使い方
- インストール
Node.js環境下で、下記コマンドを実行してClaspをインストール。(グローバルにインストールしたくない人は各位工夫してね)
npm install -g @google/clasp
- Googleアカウントでログイン
GAS開発したいアカウントでログインする必要がある。下記コマンドでブラウザが立ち上がるか、認証用URLが発行されるので、そこからログイン
clasp login
- プロジェクトの作成
新規作成したい場合
下記コマンドでプロジェクトを作成する。
clasp create --title {プロジェクト名} --type standalone
既存のGASプロジェクトを使いたい場合
下記コマンドで既存プロジェクトのクローンが可能
clasp clone {プロジェクトID}
- プロジェクトIDっていうのは、ブラウザでGASプロジェクトを開いた際のURLにおける、
https://script.google.com/u/0/home/projects/XXXXXXXXXXXXXXXXXXXXX/edit
のXXXXXXXXXXXXXXXXXXXXXの部分がID
- ソースコードを色々編集したら、下記コマンドでアップロードする
clasp push
逆に、ブラウザエディタ側で編集したやつを取り込みたい場合は、
clasp pull
をする。
モジュール化対応
GASにおけるモジュール化
GAS環境では、全てのソースコードがグローバルに配置される。なので、ファイルや関数の衝突、依存関係の管理がめっちゃめんどい。要はコードを複数ファイルに分割してimportみたいな事ができない。なので、まずはこの問題を乗り越えていく。
モジュール化の救世主「webpack」
webpackってなぁに?
webpackは複数のソースファイルをひとまとめにして、「バンドル」として出力するツール。webpackを活用する事で、ファイル単位での運用が難しい環境でも複数ファイルを一つにまとめる事で運用が可能になる。
今回工夫した事
- babelの導入
後述するTypeScript対応説明する - GasPluginの導入
GAS独自の実行環境に最適化した形式にコードを変換してくれる。webpack独自のモジュールラッパーを除去してくれたりする。 - webpack.DefinePluginの導入
GASの実行環境上では環境変数を触れないので、コード内に値を埋め込んでおく必要がある。
DefinePluginを使うと、webpackによるバンドル生成時に値を埋め込んでくれる。コードに埋め込む仕様上セキュアな値を使う事は推奨されない。GASでセキュアな情報を用いたい場合は、GASのプロパティサービスを活用しよう。
GASの実行環境対応
GASにおけるTypeScript
GASはTypeScriptには対応していない。その為、GASにデプロイする時にはJavaScriptに変換しておく必要がある。また、GASはV8ランタイムという実行環境で動作している関係上、最新のJavaScript構文に対応していない可能性がある。GASにデプロイするには、コードをES2019相当にしておく必要がある。
互換性の救世主「Babel」
Babelってなぁに?
Babelは新しめのJavaScript構文や機能で書かれたコードを、古い実行環境でも動作するようなコードに変換するツール(こういう変換をTranspiler(トランスパイラ)という)
開発者は最新の言語機能を使いつつ、古い実行環境でも動作するコードを生成する事が可能である。
また、バージョン変換だけでなくBabel用のプラグインを用いる事で様々な変換が可能になる。
今回工夫した事
- 変換先の設定
ES2019相当のchromeバージョン70に設定。また、moduleの解決はwebpackに任せるので、modulesの設はfalseにする。 - TypeScript変換
TypeScriptからJavaScriptのbuildはbabelで行う。babelでのtypescriptビルドは型情報を削除してトランスパイルするだけなので高速に行える。TypeScriptの型チェック等は時間がかかるので、ビルド時に行わず開発中に行う事にする。 - webpackとの連携
webpackの実行時にBabelも一緒に実行する事で、最適化されたワークフローで運用ができる。
その他
gloalでエラー吐く問題
GAS側でエントリポイントを作成する際、global空間で宣言してやる必要がある為、
declare let global: any;
global.main = () : void => {
}
みたいな感じで記述する。
しかし、ESLintからany型に対して警告が入る為、
globalThis.main = () : void =>{
}
で記述するとエラーが出ない。
この記法はES2020で登場した記法で、ES2019では使えない方法。早速Babel対応した成果が出ている。
globalはNode.jsで用いれる記法で、V8では対応しないので強引にany型で宣言させている。
globalThisはマルチプラットフォームに宣言出来るglobal空間なので、一貫してグローバルオブジェクトとして宣言が出来る。
Discussion