clasp で GAS を書く
動機
自分の好きなエディターを使っていると、GAS を web 上で書くのはとてもストレスが溜まる。GAS は javascript ベースなので、ローカルなエディターで補完等を使って書きたい。さらに言えば typescript で書きたい
というわけで備忘録も兼ねて、手順書を作成する
clasp のセットアップ
clasp とは
clasp とはローカルで GAS を書きそれをデプロイするものである。簡単に始めるには、aside というものがあり(中では clasp を使用している)それで作成してから色々いじると簡単にできるが、ここでは clasp だけを使用する
node & clasp のインストール
- お好きなツールで
nodojs
を入れ、npm install -g clasp
でclasp
コマンドが使えるようになる。 -
clasp login
でログインをする。
プロジェクトの作成
-
clasp create project_name
でプロジェクトの作成ができる。 - インタラクティブに聞かれるので好きなのを選ぶ、後からでも色々いじって変えられる。ここでは
standalone
を選ぶ - そうすると
appsscript.json
ができる。こんな感じになっているはず。
{
"timeZone": "America/New_York",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
Typescript のセットアップ
-
typescript の型定義を入れる。(clasp ≥ 1.5.0 じゃないと typescript は使用できない)
npm i -D @types/google-apps-script
-
tsconfig.json
に以下のように書く{ "compilerOptions": { "lib": ["esnext"], "experimentalDecorators": true } }
-
hello.ts
を書くconst greeter = (person: string) => { return `Hello, ${person}!`; } function testGreeter() { const user = 'Grant'; Logger.log(greeter(user)); }
-
clasp push
でコードをプッシュする-
clasp
は typescript のコードがあると自動で.gs
にとらんスパイスしてくれるので、変更などは必要ない - 注意!
.claspignore
にnode_modules
などを入れておかないと、node_modules
の中のコードとかまでトランスパイルされてしまう。例えばこんな感じに.claspignore
を書く
**/.git/** **/node_modules/** .clasp.json .claspignore package-lock.json package.json tsconfig.json
-
npm のパッケージとか、 ES module を使いたい
clasp は ES module をサポートしていない上に、npm などに対応をしていません。GAS というどう足掻いても使えないパッケージは存在します。しかし、その上でパッケージとして使うには一度シングルファイルに third-party の webpack
等を用いることで変換して push する必要がある
使用できるツールは色々あるがここでは webpack
を用いる
webpack を使う
webpack とは
Webpackは、JavaScriptを中心としたモジュールバンドラで、複数のファイルやアセット(CSS、画像など)を依存関係に基づき効率的にまとめ、最適化して1つまたは複数の出力ファイルを生成します。コード分割、ツリーシェイキング、ホットリロード、プラグインによる拡張が可能で、モダンなWebアプリ開発を支援します。 (ChatGPT)
-
npm install webpack webpack-cli typescript ts-loader --save-dev
で webpack と typescript をインストールする -
tsconfig.json
を記述{ "compilerOptions": { "lib": ["esnext"], "experimentalDecorators": true, "outDir": "./dist/", "noImplicitAny": true, "module": "es6", "target": "es5", "allowJs": true, "moduleResolution": "node" } }
-
src/main.ts
のを作成するfunction hello() { Logger.log("Hello, world!"); }
-
webpack.config.mjs
を作成 ( common js を使いたい場合は.js
を使用する )import path from "node:path"; import { fileURLToPath } from "node:url"; export default { mode: "production", module: { rules: [ { test: /\.tsx?$/, use: "ts-loader", exclude: /node_modules/, }, ], }, entry: "./src/main.ts", output: { filename: "main.js", path: path.resolve(path.dirname(fileURLToPath(import.meta.url)), "dist"), }, experiments: { outputModule: true, // ECMAScript モジュールとして出力することでランタイムを削減 }, optimization: { minimize: false, }, };
-
.claspignore
に**/src/**
、webpack.config.json
を追加 -
package.json
に以下を追加"scripts": { "build": "webpack --config webpack.config.mjs", "push": "clasp push", "deploy": "npm run build && npm run push" }
-
これで
npm run deploy
でトランスパイル & デプロイができる
Discussion