B-Teck!

お仕事からゲームまで幅広く

【GAS】claspでTypeScriptを使ってユニットテストもする

前回からの続き
blog.beatdjam.com

claspはデフォルトでTypeScriptに対応していて、作成した.tsファイルを含んだ状態でpushすると自動でトランスパイルしてくれる。
せっかくなのでTypeScriptを導入した上でローカルでユニットテストを実行できるようにした。

claspのプロジェクトでTSを扱えるようにする

まず、GASの型情報を取得する。

$ npm i -S @types/google-apps-script

次に、tsconfig.json を作成する。

{
    "compilerOptions": {
        "lib": [
            "es2019"
        ],
        "experimentalDecorators": true,
        "esModuleInterop": true
    }
}

これで、ローカルで編集する際にGASの型情報を参照した上で、ES2019環境で書くことができるようになった。

ユニットテストを動くようにする

実体としては普通のTSのプロジェクトなので、普通にJestを導入する。

$ npm i jest @types/jest ts-jest -D

jset.config.js でテスト周りの設定をする。
今回は src 配下にファイルを置いているのでそのように指定した

module.exports = {
    "roots": [
        "<rootDir>/src"
    ],
    "testMatch": [
        "**/__tests__/**/*.+(ts|tsx|js)",
        "**/?(*.)+(spec|test).+(ts|tsx|js)"
    ],
    "transform": {
        "^.+\\.(ts|tsx)$": "ts-jest"
    },
}

あとはtestMatchにマッチするようなファイル名でテストを書いて実行してやれば良い。

$ npx jest

不要ファイルの除外

ここまでの手順で、管理する必要がなかったりGASに上げる必要のないファイルが出来たりする。
claspはgitのように .claspignore を設定することで任意のファイルを除外できる。
今回はこのように設定したが、拡張子がjsのファイルも残す場合は書き足す必要がある。

**/**
!src/*.ts
src/*.test.ts
!appsscript.json
coverage/*

一応 .gitignore もこんな感じにしてる

node_modules
.idea
coverage

注意点

一度GAS側に反映されたファイルは $ clasp pull するとjsになって落ちてくる。
TSで書く場合はGitで管理して、オンラインエディタ上で編集を行わないほうが良さそう。

まとめ

  • TS自体は書いて $ clasp push したら動く
  • ローカルで書くなら型情報入れる必要がある
  • ユニットテストとかは普通のTSのプロジェクトとして手元で入れれば良い
  • GAS側に一度反映したファイルはJSになるので注意

今回の作業に使ったリポジトリはこれです。
GitHub - beatdjam/anniversary-notifier

【GAS】claspの環境構築

nodeのインストール

  • nodebrewを入れる
$ brew install nodebrew

下記を利用してるシェルの設定に書いてPATHを通す

export PATH=$HOME/.nodebrew/current/bin:$PATH
  • nodeをインストールして設定する
# インストール可能なバージョンを確認
$ nodebrew ls-remote
$ nodebrew install-binary <version>
$ nodebrew use <version>
  • 下記でバージョンが確認できればインストール完了
$ node -v

claspのインストール

インストールはnpmコマンドで行う

$ npm i @google/clasp -g

インストール完了後、下記のコマンドを入力するとブラウザでログインを求められる。
実行するとホームディレクトリにトークンが保存された.clasprc.jsonファイルが作成される。

$ clasp login

claspでプロジェクトを管理する

初期状態ではGoogle Apps Script APIが無効になっており、プロジェクトの操作が出来ない。
Apps Script の設定画面での使用をオンにする。

clone

helpを打ってみるとこんな感じ。

-> % clasp clone --help
Usage: clasp clone [options] [scriptId] [versionNumber]

Clone a project

Options:
  --rootDir <rootDir>  Local root directory in which clasp will store your project files.
  -h, --help           output usage information

ここで言う scriptId はプロジェクトの編集画面のURLの下記の部分。

  • 旧エディタ https://script.google.com/d/<scriptId>/edit

  • 新エディタ https://script.google.com/home/projects/<scriptId>/edit

任意のディレクトリで下記コマンドを実行するとソースを取得できる

$ clasp clone <scriptId>

push

cloneしたディレクトリをGASに反映するときはgitと同じようにpushする。

$ clasp push

この時pushの対象となるのは下記のみ

  • 拡張子が .gs
  • 拡張子が .html
  • ファイル名が appsscript.json

status

push対象のファイルはstatusコマンドで確認できる

$ clasp status

まとめ

claspを利用する手順は

  • nodeを入れる
  • claspを入れる
  • Google App Script APIの利用を許可する
  • claspでログインして認証する
  • プロジェクトをcloneする

思ってたより簡単に導入できた。
作成したディレクトリはGitでも普通に管理できるのでGAS上だけで管理してたファイルをちょっとずつGitで管理できるようにしていきたい

【Scala】Scalaをはじめよう! ─マルチパラダイム言語への招待─ を読んだ

最近Scalaの話題に触れる機会があり、そういえば全然Scalaの言語仕様を全然知らないなと思ったので、ライブラリに積んであった本書を読んでみました。

sbtの使い方からオブジェクト指向的な機能の紹介、Scala特有の機能の紹介、ファイルを取り扱う実装とそのテストまでをさらっと読める分量で書かれており、とりあえずScalaを触ってみるという場合にはちょうどよい書籍かなと。
ファンクタ・モナド・モノイドあたりは掘り下げすぎず、本書で触れる必要十分な範囲だけコラムで記載されていて、その割り切り方も初学者にはありがたかったです。

以下感想。

  • 書籍内では実行環境としてsbtのみ紹介していたが、IntelliJで書いてみた
  • sbtが慣れなかった
    • 実行が若干遅い?
    • 2018年発刊の書籍記載のライブラリが既にMaven Centralになくて衝撃だった
      • Scala本体のバージョンにライブラリが依存するためEOLのものはバシバシ切られている?
  • 記法はKotlinに近くて馴染みやすかった
    • companion objectはobjectを別で定義するのでKotlinのほうがわかりやすいかなと思った
    • traitは振る舞いを組み合わせる感じで結構好き。
      • 宣言時じゃなくて利用時にもmixinできるのはちょっと気持ち悪い
      • Kotlinのinterfaceやdelegationより直感的に扱える気がした
    • Option, Eitherみたいなエラーハンドリング用の型が言語組み込みであるのは嬉しい
      • これ + KotlinのNullable Typeみたいなのがあれば最高だったかも
      • 成功、失敗は型として扱いつつ、単なるNullableをさばくのにこの形になるのは結構大変
    • Enumがほしい
      • sealed classは表現力高いけどもっとシンプルなEnumはあったら嬉しいかもなと思った
    • Futureの記法が結構シンプルで良い
      • 個人的にはAwaitまで説明してほしかった
    • implicitのユースケースがあまりピンときてない
      • もっと使ってみないとわからないかも
      • implicit classはスコープ内限定の拡張関数定義するのに使う?
    • ユニットテストのFlatSpec?というのがなかなか馴染めなかった
      • これも書いてたら慣れるかも

次はコップ本…と思ったんですが、ハードルが高そうなのでまずは実践Scala入門を読んでみようかなと思います。

実践Scala入門

実践Scala入門