📕

GAS + TypeScript + devcontainer(VSCode)で開発してみる

2023/01/11に公開

TL;DR

  • GASをTypeScriptで型安全に書くよ
  • VSCodeで作業してclaspでアップロードするよ
  • VSCodeだしdevcontainerで環境依存なくすよ

はじめに

皆さん一度は使ったことがあるでしょう Google Apps Script (GAS)。
私はサーバーを用意するのが面倒できないのでLINE BotやSlack Botを作る際にはGASを利用しています。
普段はWeb上のエディタでそのまま作業しているのですが、他の業務ではVisual Studio Code(VSCode)を利用しているので出来ればGASもVSCodeで書きたいなと思いました。
(Github Copilotに助けられたい気持ちもあった)

ついでに書きなれているTypeScriptからトランスパイルしたり、devcontainerで環境依存をなくしたりしてみました。

みなさんの参考になればうれしいです。
間違いや指摘などがあればどしどしコメントください!🪓

作業したリポジトリ

先に今回作成したリポジトリを置いておきます。特に具体的なコードは書いていないのでコピペしたりForkして活用してください(よろしければスター押してってください🙇‍♀️)。

https://github.com/futahei/gas-ts-template

この記事は作り終わった後に完成物を見ながら別で一から順を追って作りながら書いているのでかなり丁寧に書いています。そのため冗長な部分が多いと思いますが適宜読み飛ばしてください。

前提

  • Google のアカウントの用意
  • Visual Studio Codeのインストール
    • この記事執筆時バージョン:1.74.3
    • 「Dev Containers」という拡張機能を追加してください
  • Dockerの用意

以下の記事に詳しく載っていたので参照してください。
https://chigusa-web.com/blog/vs-code-node-remote/

devcontainerの作成

まず作業するフォルダを作ります。ここではgas-ts-devcontainerという名前で作りました。

次にVSCodeでそのフォルダを開きdevcontainerの設定ファイルを作成します。

コマンドパレットを開き(Ctrl + Shift + P またはVSCode上部メニューから表示>コマンドパレット)、add devと入力します。
コマンドパレットの入力
表示されたDev Containers: Add Dev Container Configurations File...を選択します。
ここでdevcontainerの設定ファイルのベースを選択することになります。
今回はShow All Definitions... > Node.jsを選択しました。バージョンや追加機能はそのままで大丈夫です。

選択が終わるとフォルダ直下に.devcontainerというフォルダと二つのファイルが出来ていると思います。
.devcontainer構造
VSCodeの拡張機能や設定を変更する場合は.devcontainer/devcontainer.jsonに追記してください。以下は私の設定です。

https://github.com/futahei/gas-ts-template/blob/main/.devcontainer/devcontainer.json

追記が終わったら再度コマンドパレットを開き、rebuildと入力します。表示されたDev Containers: Rebuild And Reopen in containerを選択します。

するとdevcontainerがビルドされてコンテナが起動します。
VSCode左下に以下のようにDev Containerの記述があれば成功です。

devcontainerの証明

node packageのインストール

パッケージマネージャーにはyarnを利用します。
以下のコマンドをターミナル(Ctrl + Shift + @またはVSCode上部メニューからターミナル>新しいターミナル)で入力すると、package.jsonの作成が始まります。色々聞かれますが後で設定できるので今はスキップします。

$ yarn init

初期化が終わるとフォルダにpackage.jsonが出来ていると思います。

次に必要なパッケージをインストールします。
基本的にすべて開発時にしか利用しないのですべてdevDependenciesに入れていきます。

$ yarn add -D typescript @google/clasp @types/google-apps-script esbuild esbuild-gas-plugin

インストールが終わったらTypeScriptのコンフィグファイルを作成します。

$ yarn tsc --init

フォルダにtsconfig.jsonが出来ていれば完了です。

claspを使ってGASと接続

claspはGASのプロジェクトをローカルで開発するためのコマンドラインツールです。
https://github.com/google/clasp

まずclaspを使うためにGoogle Apps Script APIを有効化する必要があります。
こちらのリンクからGoogle Apps Script APIをONにしてください。

APIの有効化が完了したら、以下のコマンドを実行してください。

$ yarn clasp login

しばらくするとWebサイトを開くポップアップがでるので開いて、Googleのログイン後アクセスリクエストを許可してください。

リクエスト画面

ターミナルにAuthorization successful.の文字が出ていれば成功です。

次にGASプロジェクトを作成します。
今回はgas-ts-devcontainerという名前を設定します。

$ yarn clasp create --title gas-ts-devcontainer

scriptの形式を聞かれますが適宜選択してください(今回はstandaloneを選びました)。

GASプロジェクトの作成に成功するとフォルダに.clasp.jsonとappsscript.jsonファイルが作成されます。

実際に何か書いてみる

直下にsrcフォルダを作りそこにスクリプトを置きます。また、TypeScriptをトランスパイルした出力先としてdistフォルダも作っておいてください。

srcフォルダにindex.tsファイルを作って以下のコードを書きます。

export function main() {
  console.log('Hello, world!')
}

declare let global: any
global.main = main

後半のglobal変数に関してはビルドツールとして採用したesbuildの都合上、生成物がすべて即時関数包まれてしまうのでGASで関数が呼び出せなくなってしまう問題を解決するためです。

参考にした@Syuparn さんの記事に詳しく載っているので是非ご覧ください。
https://qiita.com/Syuparn/items/80c4f48c66ca53ef12b8#ハマった点-1-ハンドラ関数が呼べなくなってしまう

ビルドする

今回はビルドツールとしてesbuildを採用しています。
https://esbuild.github.io/

esbuild用のGASプラグインが存在するのでこちらを利用してビルドスクリプトを書きます。
https://github.com/mahaker/esbuild-gas-plugin

フォルダ直下にbuild.jsを作成します。

build.js
const { GasPlugin } = require('esbuild-gas-plugin')

require('esbuild')
  .build({
    entryPoints: ['src/index.ts'],
    bundle: true,
    outfile: 'dist/index.js',
    plugins: [GasPlugin],
  })
  .catch(() => process.exit(1))

package.jsonに追記してbuild.jsを呼び出せるようにします。

package.json
{
  // ...
  "scripts": {
    "build": "node build.js"
  }
  // ...
}

では早速ビルドしてみましょう!

$ yarn build

distフォルダにindex.jsが出力されていれば成功です。

claspでコードをアップロード

出力したindex.jsをGASプロジェクトにアップロードします。

.clasp.jsonに以下の変更を加え、distフォルダにappsscript.jsonを移動させます。

.clasp.json
{
  "scriptId":"~~~~~~id~~~~~~",
  "rootDir": "./dist"
}

以下のコマンドを実行してアップロードします。

$ yarn clasp push

成功すると先ほど作成したGASプロジェクトにindex.gsが追加されているはずです!

参考

https://qiita.com/Syuparn/items/80c4f48c66ca53ef12b8
https://bgtu-techblog.com/2022/01/16/google-apps-script開発環境をvisual-studio-codeで構築する/

Discussion