feature image

2020年5月2日 | ブログ記事

GASの過剰に強強な環境構築【新歓ブログリレー2020 55日目】

この記事はtraP新歓ブログリレー55日目の記事です。


こんにちは。19Bの@mazreanです。

このブログリレーでは他に以下のような記事も書いています。

猫でもわかる(諸説)OAuth 2.0【新歓ブログリレー2020 26日目】
はじめにこちらは新歓ブログリレー2020 26日目の記事です。こんにちは。19Bのmazreanです。traP内ではSysAd班に所属しており、普段はサーバーサイドのコードを書いたり、サーバー触ったり百合漫画を布教したり(下の記事も読んでね)とかをしています。 百合漫画の勧めこの記事は夏のブログリレー 9/8の記事です。19のmazrean(マズリーン)です。この記事では百合漫画の布教をしていこうと思います。 百合とは百合漫画について説明する前に百合というものの概念を説明していきます。といっても、実は百合の定義は人によってかなり変わってきます。そもそも「百合」という言葉はwikipe…

ぜひ読んでみてください。

と前置きはここまでにして、今回はGASの話題を書いていきたいと思います。

GASとは

GASとはGoogle Apps Scriptの略で、Googleのサーバー上で自動で自分の書いたJavaScriptのようなScript[1]を動かせるサービスです。
GoogleスプレッドシートやGoogle Calendarなどとの連携が容易で、簡単に何かを自動化したい場合などに、手軽に使えて便利です。
ただ、GASは基本的にブラウザ上のエディタで書くのですが、この補完などはVSCodeなどの自分の手元のエディタと比べると少し貧弱だったりします。
また、以前のスクリプトに戻したいときなどの処理があまり簡単ではありません。
そこで、今回はこのGASをローカルのエディタで編集でき、Git管理、ついでにCIでtestの実行と、型のある幸せなコードを書けるようTypeScript化もしていこうと思います。

前提

今回の方法ではNode.jsの環境が必要になります。
やる場合はNode.jsの環境構築をした上でやってみてください。
筆者はFedora31上で行ったため、claspでできるファイルなどの位置はLinuxでのものになっています。
他のOSで行う場合は適宜置き換えてください。

手順

ローカルのエディタで編集できるようにする

git管理もCIもTypeScript化も手元でコードを書けるようにならないと話しになりません。
というわけで、まずはローカルのエディタで編集できるようにしていきます。
今回はclaspというコマンドラインツールを使っていきます。

  1. yarn global add @google/claspコマンドでインストールする
  2. clasp loginを叩くと、ブラウザでGASのプロジェクト作成・更新の権限を求めてくるので、同意する
    これによって~/.clasprc.jsonのファイルが作成され、このファイルにログイン情報が保存されます
  3. clasp create {{作りたいプロジェクトの名前}}[2]でGASのプロジェクトが作成されます[3]
    選択肢は自分の作りたいGASで使うスプレッドシートなどのアプリケーションに合わせて適宜選択してください
  4. clasp pullをし、リモートのコードを手元に持ってくる
  5. ローカルで変更した場合、プロジェクトのルートディレクトリでclasp pushをするとremoteに手元での変更が反映されます

ここまででローカルのエディタで編集できるようになります。

TypeScript化

ローカルのエディタで編集できるようになったので、TypeScript化していきます。
実はこのままでもclasp pushをすると自動でclaspがTypeSyriptをトランスパイルしてくれて、GASへの反映はできます。
tsconfig.jsonは必要ありません。
ただ、GASはデフォルトでV8エンジンでコードを動かしてくれるのですが、claspでトランスパイルされた後のコードはGASがV8エンジンに対応する前のコードになるので、うまく動かない場合があったり、ローカルのエディタで書くときにGASのデフォルトのクラス・関数などを使うとエラーを吐かれたりして、快適とは言い難い状態です。
この状態を改善していきます。

  1. ローカルのプロジェクトのルートディレクトリにできているappsscript.jsonruntimeVersionの値を"DEPRECATED_ES5"へ変え、clasp pushをする
  2. yarn add -D @types/google-apps-scriptでGAS固有の関数の型定義を持ってくる
  3. Code.jsの名前をCode.tsに変える

これでローカルのエディタで快適にGASをTypeScriptで書くことができます。

LintとTest

この後、Githubで管理し、Github Actionsでmasterブランチにmergeしたらclasp pushでGASへ反映するようにしていきたいのですが、どうせCI回すならlintとtestもしたいと思いませんか?
というわけで、lintとtestを動くようにしていきます。
この部分は普通のTypeScriptとだいたい同じです。

lint

eslintを使った設定について説明していきます。

  1. yarn add -D eslint\
        @typescript-eslint/eslint-plugin\
        @typescript-eslint/parser prettier\
        eslint-config-prettier\
        eslint-plugin-prettier
    
    でeslintの環境を整える
  2. .eslintrc.jsonを自分の好みで適切に設定する
    参考として自分がこのブログリレーの部員へのリマインダーをこの方法で動かすに当たって使ったeslintの設定は https://github.com/mazrean/blogRelay/blob/master/.eslintrc.json です。
    一つ注意点として、GASで実行させる関数はコード内のどこでも使われません。
    このため.eslint.jsonrules"no-unused-vars": ["error", { "varsIgnorePattern": "^myFunction$" }]のようにunused-varsが吐かれないように除外しておかないとerrorが出ます。
  3. package.jsonscript"lint":"eslint Code.ts"を設定する

これでLintは動くようになります。

test

今回はjestを使ったtestを書いていきます。

  1. yarn add -D jest\
        @types/jest\
        ts-jest
    
    でjestの環境を整える。
  2. jest --initをする
  3. テストを書く
    基本的に普通のjestでのテストを書くのと同じです。
    ただ、GAS独自のオブジェクトはモックする必要があります。
  4. package.jsonscript"test": "jest"を設定します

これでtestができるようになりました。

Github Actionsの設定

これらを利用してCIが回るようにします。
まず、lintとtest部分は通常のTypeScriptのlint、testと同様に https://github.com/mazrean/blogRelay/blob/master/.github/workflows/main.yml のようにします。
次に、GASへの反映の部分はclaspを使っていくのですが、ローカルでは手動でログインすることができたのですがCIで手動でログインするわけにはいきません。
このため、ローカルの認証情報が保存された.clasprc.json.clasp.jsonをSecretに設定し、それを読み込んでCIにこの2つのファイルを保存する、という方法を使います。
今回は.clasprc.jsonの中身をそのままSecretに入れてCIの過程でechoコマンドで.clasprc.jsonに入れるという形を取りました。
そのため、Secretに入れる値は{などを\でエスケープした値になります。
このようなことをやって最終的には https://github.com/mazrean/blogRelay/blob/master/.github/workflows/master.yml のようになりました。

Githubに上げる

ここまでできれば後はGithubにpushするだけなのですが、.clasp.jsonにはGASのscriptのIDが書かれています。
.clasprc.jsonに書かれている認証情報がなければ恐らくスクリプトの閲覧・変更はできないと思われますが、一応認証情報なので.gitignoreで指定しておいたほうが良いでしょう。
これでリポジトリを作ってpushすれば、Githubでバージョン管理ができて、しっかり補完の効く型付の環境でコーディングできる幸せなGASの環境の完成です。

本当にこんなことする必要あるの

とここまで、GASの幸せな環境を作る方法を解説してきましたが、本当にこんなことする価値があるのでしょうか?
私は実際にやってみた感想としてないと思います。
というのも、この過程でかかる手間が用途に対して大きすぎるからです。
最初にも言ったように、GASは本来「簡単に自動化したい」ときに使うものです。
このため、lintやtestを行わなければならないほどの保守性が求められる用途で使用するべきものではありません。
今回自分は、このブログリレーの担当者[4]へ担当日の1週間前・当日にtraQでリマインドをするために利用しました。
正直、これだけのためにeslintの設定やtestをするのは手間がかかり過ぎます。
また、GASでV8エンジンが使えるようになった今、かなりモダンなJavaScriptが使えるようになっています。
このため、わざわざTypeScriptにしなくとも十分快適にコードを書けます。
これらのことを考えると、ブラウザ上のエディタで十分快適に書けます。
せいぜいやったとしてもclaspでローカルのエディタで書けるようにするぐらいかな、というのが自分の感想です。

まとめ

GASは便利ですが、あくまでも「簡単に自動化したい」ときに使うのに適したものです。
しっかりと用途に適しているか考えた上で幸せなGASライフを送りましょう!
明日は@Fourmsushiさんの記事です。お楽しみに!


  1. JavaScriptと記法はかなり似ていますがJavaScriptでは使えてもGASでは使えない文法などもあるのでこのように書いています。 ↩︎

  2. 既に作ったプロジェクトをローカルで編集したい場合はclasp clone {{プロジェクトID}}(プロジェクトIDはブラウザのエディタのファイル→プロジェクトのプロパティで見れます)をすれば、既にあるプロジェクトを手元に持ってこれます ↩︎

  3. これまでにGASを使ったことがない場合、「権限がない」というエラーが出るので、https://script.google.com/home/usersettingsで「Google Apps Script API 」という項目をONにしてください ↩︎

  4. このブログリレーは部員の中で記事を書きたい人が好きな日付に自分の名前を書き込んで、それぞれの日の担当者を決める、という形で行っています ↩︎

mazrean icon
この記事を書いた人
mazrean

SysAd班で活動したり、百合漫画の布教をしたりしている人。

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2020年5月15日
【新歓ゲーム制作特集 第2弾】Inverse製作秘話
Saltn icon Saltn
2020年5月19日
【新歓ゲーム制作特集 第6弾】個人でゲームを作る話
Facish icon Facish
2020年5月1日
爆☆誕 traQ-S【新歓ブログリレー2020 54日目】
spa icon spa
2020年4月12日
Growl Bassの研究【新歓ブログリレー2020 35日目】
fomalhaut icon fomalhaut
2020年4月6日
はじめてのドット絵
xxpoxx icon xxpoxx
2020年4月3日
猫でもわかる(諸説)OAuth 2.0【新歓ブログリレー2020 26日目】
mazrean icon mazrean
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記