My External Storage

Jan 16, 2019 - 7 minute read - Comments - gas typescript

Google Apps ScriptをTypeScriptで実装する(clasp/TSLint/Prettier) #gas #typescript

claspというGoogle Apps Script(GAS)をローカルで開発するためのツールがある。claspを使うと、TypeScriptを使ったGASのコーディングも標準で行える。 今回はclaspを使って以下の要求を満たしながらGASの開発を行う際の設定をまとめる。

  • TypeScriptによる実装
  • Gitによる構成管理
  • Prettierによる自動フォーマット
  • TSLintによる静的解析

VSCodeでの実装画面

TL;DR

サンプルコードは以下のリポジトリにある。

今回使っている各ツールのバージョンは以下の通り。

$ node -v
v10.8.0
$ npm -v
6.2.0
$ clasp -v
1.7.0
$ tslint -v
5.12.1
$ prettier -v
1.15.3

なお、私の環境はすでにグローバル環境にTSLintとPrettierがインストールされている。今回TSLintとPrettierの詳細な説明は省略する。

$ npm i tslint -g
$ npm i prettier -g

claspとは

claspはGASをローカルで開発するためのツールだ。clasp pushとすればローカルのjsファイルをgasファイルとしてGoogle Drive上のApps Scriptプロジェクトにアップロードできる。 また、clasp pullとすればDrive上のgasファイルをjsファイルとしてローカルにダウンロードできる。1.5.0からTypeScriptを標準でサポートした。とくにwebpackなどの設定を書かなくても、tsファイルをアップロードすれば自動的にgasファイルに変換してくれる。

clasp自体のインストール方法については以下の記事通りやれば良い。次節以降の処理はすでにログイン処理が実施済みであることを前提にする。

TypeScriptで実装するGASプロジェクトの作成方法

今回はDrive上にプロジェクトを作成していない状態から、Googleスプレットシートと連携するGASプロジェクトをTypeScriptを使って書いていく。まずローカルGASのプロジェクトを作成する。 途中hub createコマンドでGitHubリポジトリも作成している(不要ならhubコマンドは省略してよい)。

$ mkdir gas-typescript
$ cd gas-typescript
$ git init .
$ hub create
$ npm init -y
$ npm i -S @google/clasp tslint
$ npm i -S @types/google-apps-script @types/node

claspのTypeScriptのREADME通り、jsconfig.jsonファイルを用意しておく。

{
  "compilerOptions": {
    "lib": ["esnext"]
  }
}

今回は自動フォーマットも利用するので、Prettierも導入しておく。

$ npm i -D prettier
$ npm i -D tslint-config-prettier
$ npm i -D tslint-plugin-prettier

tslint.jsonは以下の設定を用意した。Stackdriverでログを取るにはconsole系の関数を使うので、no-consolefalseにしてある。 また、prettierと設定が競合しないようにもろもろの設定も含めてある。その他は好みの設定にすれば良いと思う。

$ cat tslint.json
{
    "defaultSeverity": "error",
    "extends": [
        "tslint:recommended",
        "tslint-config-prettier"
    ],
    "jsRules": {},
    "rules": {
        "semicolon": [
            true,
            "always"
        ],
        "prettier": true,
        "no-console": [
            false
        ]
    },
    "rulesDirectory": [
        "tslint-plugin-prettier"
    ]
}

VSCodeを使っている場合は、以下のプラグインをインストールしておく。

VSCode自体のsetting.jsonに以下の設定を書いておくことでファイル保存時にprettierによる自動整形が走るようになる。(Command + Shift + Pを押したあと、open settings(JSON)などで検索すればsetting.jsonが直接編集できる。)

{
    // *.tsは自動でフォーマットする
    "[typescript]": {
        "editor.formatOnSave": true
    },
    // *.tsxは自動でフォーマットする
    "[typescriptreact]": {
        "editor.formatOnSave": true
    }
}

あとはclasp経由でDrive上に紐づくGASプロジェクトを作ればよい。

$ clasp create --title "TypeScript sample" --type sheets --rootDir ./src
$ clasp pull

これでWeb上のプロジェクトと関連付けられたローカルのGASプロジェクトが作成できた。 (clasp createclasp pullの間にWebブラウザでプロジェクトを開くと、clasp pullしたときにjsファイルがダウンロードされるかもしれない。

ここで自動生成されたsrc/appscript.json内のタイムゾーンの設定がニューヨークになっていたので、東京に修正した。

{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER"
}

あとはローカルでtsファイルを追加して編集する。APIについては以下からたどればよい。

今回は簡単にStackdriverへのログ出力とスプレットシートに書き込みをする関数を含むsrc/Hello.tsを作成した。

function main() {
  // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const today = Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd");
  const value = "Hello clasp";

  console.log(value);
  sheet.appendRow([today, value]);
}

VSCode上で上記のファイルを編集していると、TypeScriptを使っているので関数定義などのヘルプも表示され、未定義変数などのエラーも表示されている。また、Prettierによってファイル保存時に自動フォーマットも行われる。

VSCodeでの実装画面

Web上のGASプロジェクトから実行する

コードを書いたらまずclasp pushコマンドでGoogle Drive上にコードをプッシュしてみる。

$ clasp push
? Manifest file has been updated. Do you want to push and overwrite? Yes
└─ src/Hello.ts
└─ src/appsscript.json
Pushed 2 files.

pushが出来たらclasp openコマンドでプロジェクトを開いて内容を確認しておく。

$ clasp open
Opening script: https://script.google.com/d/${.clasp.json内のscroptIdと同じ文字列}/edit

自動的にトランスパイルされたHello.gsファイルがプロジェクト内に配置されている。

var exports = exports || {};
var module = module || { exports: exports };
function main() {
    // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    var today = Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd");
    var value = "Hello clasp";
    console.log(value);
    sheet.appendRow([today, value]);
}

以下画像の赤矢印が指す実行ボタンをクリックしてGASを実行してみる。

Web上のgasファイル

Web上でスクリプトの実行を行おうとすると、初回は許可を与える必要がある旨が表示されるので、案内に則って権限を付与する。 以下は開いたモーダル内の「詳細」ボタンをクリックした後の警告画面。

Web上での警告画面

スプレットシートへのアクセスを許可する。 Web上での認可画面

許可を与えていくと、スクリプトが実行される。実行されない場合はもう一度プロジェクトの実行ボタンをクリックする。

実行結果の確認

私はプロジェクトのページから直接スプレットシートを開く方法を知らないので一度GASのプロジェクト管理コンソールを開く。

https://script.google.com/home/my

ここで、該当プロジェクトの上にマウスオーバーすると、対応するスプレットシートへのリンクが表示されるのでクリックする。

管理コンソール画面 ちゃんとGASで作った文字列が書き込まれていた。

実行結果

あとはローカルのプロジェクトをGitHubにコミットしておけばよい。 権限が正しく設定されていれば問題ないとは思うのだが、私は心配性なのでscriptIdが含まれている.clasp.jsonはコミットしないようにしておいた。

# .gitignoreファイルの中身
node_modules/
.vscode/
.clasp.json

終わりに

今回はローカルでGASの実装をするclaspを試してみた。TypeScriptを使えるようにしておくと補完なども効くようになってサクサク書けそうだ。 また、ついでにTSLintとPrettierなども導入した。GASのオンライエディタもかなり優秀だが、手元でLinter/Formatterを書けながら書けるのはよい。

参考