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