GAS + TypeScript + devcontainer(VSCode)で開発してみる
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して活用してください(よろしければスター押してってください🙇♀️)。
この記事は作り終わった後に完成物を見ながら別で一から順を追って作りながら書いているのでかなり丁寧に書いています。そのため冗長な部分が多いと思いますが適宜読み飛ばしてください。
前提
- Google のアカウントの用意
-
Visual Studio Codeのインストール
- この記事執筆時バージョン:1.74.3
- 「Dev Containers」という拡張機能を追加してください
- Dockerの用意
以下の記事に詳しく載っていたので参照してください。
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というフォルダと二つのファイルが出来ていると思います。

VSCodeの拡張機能や設定を変更する場合は.devcontainer/devcontainer.jsonに追記してください。以下は私の設定です。
追記が終わったら再度コマンドパレットを開き、rebuildと入力します。表示されたDev Containers: Rebuild And Reopen in containerを選択します。
するとdevcontainerがビルドされてコンテナが起動します。
VSCode左下に以下のようにDev Containerの記述があれば成功です。

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のプロジェクトをローカルで開発するためのコマンドラインツールです。
まず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 さんの記事に詳しく載っているので是非ご覧ください。
ビルドする
今回はビルドツールとしてesbuildを採用しています。
esbuild用のGASプラグインが存在するのでこちらを利用してビルドスクリプトを書きます。
フォルダ直下に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を呼び出せるようにします。
{
// ...
"scripts": {
"build": "node build.js"
}
// ...
}
では早速ビルドしてみましょう!
$ yarn build
distフォルダにindex.jsが出力されていれば成功です。
claspでコードをアップロード
出力したindex.jsをGASプロジェクトにアップロードします。
.clasp.jsonに以下の変更を加え、distフォルダにappsscript.jsonを移動させます。
{
"scriptId":"~~~~~~id~~~~~~",
"rootDir": "./dist"
}
以下のコマンドを実行してアップロードします。
$ yarn clasp push
成功すると先ほど作成したGASプロジェクトにindex.gsが追加されているはずです!

参考
Discussion