claspでGAS開発をモダンにする|ローカル開発・Git管理・TypeScript対応の実務ガイド
目次
- claspとは
- なぜclaspを使うべきか
- スクリプトエディタの限界
- セットアップ手順
- 前提条件
- claspのインストール
- Googleアカウントへのログイン
- GAS APIの有効化
- プロジェクトの作成とクローン
- 基本操作
- push / pull
- open
- deploy
- .clasp.json の設定
- .claspignore の設定
- TypeScript対応
- なぜTypeScriptを使うのか
- 型定義のインストール
- tsconfig.json の設定
- TypeScriptでのGASコード例
- Git連携の実務
- .gitignore の設計
- ブランチ戦略
- PRベースのデプロイフロー
- プロジェクト構成のベストプラクティス
- ディレクトリ構成
- ファイル分割の指針
- appsscript.json
- Git hookによる品質チェック
- pre-commit hookの設定
- clasp push前チェックスクリプト
- 注意点
- clasp pushの上書きリスク
- 認証の有効期限
- チーム開発時の競合対策
- まとめ
claspとは
clasp(Command Line Apps Script Projects)は、GoogleがOSSで提供するGASのCLIツールです。ローカルのファイルとGASプロジェクトを双方向に同期できます。
通常、GASの開発はブラウザ上のスクリプトエディタで行います。claspを使うと、ローカルのエディタ(VS Codeなど)でコードを書き、コマンドひとつでGASプロジェクトに反映できます。
ローカル開発にすることで、Git管理やTypeScript対応、エディタの補完機能など、モダンな開発体験が得られます。GASプロジェクトが増えてきた段階、または複数人で開発する段階で導入を検討する価値があります。
なぜclaspを使うべきか
スクリプトエディタの限界
GAS標準のスクリプトエディタは、簡単なスクリプトの記述には十分です。しかし、プロジェクトの規模が大きくなると以下の課題が顕在化します。
| 課題 | スクリプトエディタ | clasp + ローカルエディタ |
|---|---|---|
| バージョン管理 | 手動のバージョン保存のみ | Git で全履歴を管理 |
| コード補完 | 基本的な補完のみ | VS Codeの強力な補完 |
| 型チェック | なし | TypeScriptで静的解析 |
| 複数人開発 | 同時編集で上書きリスク | ブランチ + PRベースで安全 |
| コードレビュー | 不可 | GitHubのPR機能を利用 |
| テスト | なし | ローカルでユニットテスト可能 |
| リファクタリング | 手動のみ | エディタのリネーム・検索置換 |
1〜2個のシンプルなスクリプトなら、スクリプトエディタで十分です。しかし、ファイル数が増えてきた場合や、チームで管理する場合は、claspの導入で開発効率が大幅に向上します。
以下の図は、スクリプトエディタでの直接開発と、claspを使ったローカル開発の比較です。
運用メモ claspは既存のGASプロジェクトにも導入できます。
clasp cloneで既存プロジェクトをローカルに取り込み、そこからGit管理を開始する方法が最も低リスクです。新規作成の場合はclasp createを使います。
セットアップ手順
前提条件
claspの実行にはNode.jsが必要です。Node.js v16以降がインストールされていることを確認してください。
node -v
# v20.x.x 以降が推奨
claspのインストール
npmでグローバルにインストールします。
npm install -g @google/clasp
インストール後、clasp --versionでバージョンが表示されれば成功です。
Googleアカウントへのログイン
claspからGASプロジェクトを操作するために、Googleアカウントで認証します。
clasp login
ブラウザが開き、Googleアカウントの選択と権限の承認を求められます。承認が完了すると、ホームディレクトリに.clasprc.jsonが作成されます。
| ファイル | 場所 | 内容 |
|---|---|---|
| .clasprc.json | ホームディレクトリ | ログイン認証情報(トークン) |
| .clasp.json | プロジェクトルート | スクリプトID・ルートディレクトリ設定 |
| .claspignore | プロジェクトルート | pushから除外するファイルのパターン |
GAS APIの有効化
初回利用時は、Google Apps Script APIを有効にする必要があります。以下のURLにアクセスし、APIを有効化してください。
https://script.google.com/home/usersettings
「Google Apps Script API」のトグルをオンにします。これが無効のままだと、clasp pushやclasp createが失敗します。
プロジェクトの作成とクローン
新規プロジェクトを作成する場合はclasp createを使います。
mkdir my-gas-project
cd my-gas-project
clasp create --type sheets --title "レポート自動化"
--typeオプションで紐づけるGoogleサービスを指定できます。
| type | 作成されるもの |
|---|---|
| standalone | 独立したGASプロジェクト |
| sheets | スプレッドシートに紐づくプロジェクト |
| docs | ドキュメントに紐づくプロジェクト |
| slides | スライドに紐づくプロジェクト |
| forms | フォームに紐づくプロジェクト |
既存のGASプロジェクトをローカルに取り込む場合はclasp cloneを使います。
clasp clone <スクリプトID>
スクリプトIDは、スクリプトエディタのURL(https://script.google.com/home/projects/<スクリプトID>/edit)から確認できます。
運用メモ
clasp create --type sheetsで作成した場合、Googleドライブのルートに新しいスプレッドシートが自動作成されます。意図したフォルダに配置したい場合は、作成後にドライブ上で移動するか、--parentIdオプションでフォルダIDを指定してください。
基本操作
push / pull
ローカルのファイルをGASプロジェクトに反映するにはclasp pushを使います。
clasp push
逆に、GASプロジェクトの最新状態をローカルに取り込むにはclasp pullを使います。
clasp pull
open
ブラウザでGASのスクリプトエディタを開きます。
clasp open
動作確認やトリガー設定を管理画面から行いたい場合に便利です。
deploy
デプロイメントを作成し、特定のバージョンを公開します。
clasp deploy --description "v1.0 初回リリース"
Web APIとして公開する場合や、アドオンとして配布する場合にデプロイメントが必要です。通常のスクリプト実行であれば、pushだけで動作します。
.clasp.json の設定
clasp createまたはclasp cloneを実行すると、.clasp.jsonが生成されます。
{
"scriptId": "1a2b3c4d5e6f...",
"rootDir": "./src"
}
rootDirを指定すると、そのディレクトリ内のファイルだけがpush対象になります。TypeScriptのソースコードをsrc/に配置し、設定ファイルやテストはルートに置く構成が一般的です。
.claspignore の設定
pushから除外するファイルを指定します。.gitignoreと同じ書式です。
node_modules/**
tests/**
*.test.ts
tsconfig.json
package.json
package-lock.json
README.md
.git/**
TypeScriptの設定ファイルやテストコード、依存パッケージはGASプロジェクトには不要なため、除外します。
TypeScript対応
claspはTypeScriptファイル(.ts)を自動的にJavaScriptに変換してからpushします。追加のビルドステップは不要です。
なぜTypeScriptを使うのか
GASはJavaScriptベースですが、TypeScriptを使うことで以下のメリットが得られます。
- 型の定義により、関数の引数や戻り値の誤りをコード記述時に検出できる
- VS Codeの補完がGASのAPI(SpreadsheetApp等)に対しても正確に機能する
- リファクタリング時に、型の不整合を即座に発見できる
- コードの可読性が向上し、チーム内での認識のずれが減る
型定義のインストール
GASのグローバルオブジェクト(SpreadsheetApp、DriveApp等)の型定義をインストールします。
npm init -y
npm install --save-dev @types/google-apps-script
tsconfig.json の設定
プロジェクトルートにtsconfig.jsonを作成します。
{
"compilerOptions": {
"lib": ["ES2020"],
"target": "ES2020",
"module": "None",
"strict": true,
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"skipLibCheck": true
},
"include": ["src/**/*.ts"]
}
claspの内部トランスパイラがtsconfig.jsonを参照します。moduleはNoneに設定してください。GASにはモジュールシステムがないため、import/export構文は使用できません。
運用メモ claspのTypeScript変換は、型チェックを行わずにトランスパイルのみ実行します。型エラーがあっても
clasp pushは成功してしまいます。push前にnpx tsc --noEmitを実行して型チェックを行う習慣をつけてください。後述のGit hookで自動化するのが確実です。
TypeScriptでのGASコード例
以下は、TypeScriptで記述した広告レポート集約のコード例です。
/**
* 広告媒体のデータ型定義
*/
interface AdMetrics {
date: string;
platform: string;
campaignName: string;
impressions: number;
clicks: number;
cost: number;
conversions: number;
}
/**
* 設定値の型定義
*/
interface ScriptConfig {
reportSheetName: string;
dataSourceUrl: string;
notifyEmail: string;
cpaThreshold: number;
}
/**
* 設定シートから設定値を読み取る
*/
function loadConfig(): ScriptConfig {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('設定');
if (!sheet) {
throw new Error('設定シートが見つかりません');
}
return {
reportSheetName: String(sheet.getRange('B1').getValue()),
dataSourceUrl: String(sheet.getRange('B2').getValue()),
notifyEmail: String(sheet.getRange('B3').getValue()),
cpaThreshold: Number(sheet.getRange('B4').getValue()),
};
}
/**
* スプレッドシートのデータをAdMetrics型に変換する
*/
function parseAdData(
rawData: unknown[][],
platform: string
): AdMetrics[] {
const result: AdMetrics[] = [];
for (let i = 1; i < rawData.length; i++) {
const row = rawData[i];
const cost = Number(row[4]) || 0;
const conversions = Number(row[5]) || 0;
result.push({
date: Utilities.formatDate(
new Date(row[0] as string), 'Asia/Tokyo', 'yyyy-MM-dd'
),
platform,
campaignName: String(row[1]),
impressions: Number(row[2]) || 0,
clicks: Number(row[3]) || 0,
cost,
conversions,
});
}
return result;
}
/**
* CPAの異常値を検出する
*/
function detectCpaAnomalies(
metrics: AdMetrics[],
threshold: number
): AdMetrics[] {
return metrics.filter((m) => {
if (m.conversions === 0) return false;
const cpa = m.cost / m.conversions;
return cpa > threshold;
});
}
/**
* メイン実行関数
*/
function main(): void {
const config = loadConfig();
const sourceSs = SpreadsheetApp.openByUrl(config.dataSourceUrl);
const sourceData = sourceSs.getSheets()[0].getDataRange().getValues();
const metrics = parseAdData(sourceData, 'Google広告');
const anomalies = detectCpaAnomalies(metrics, config.cpaThreshold);
if (anomalies.length > 0) {
const lines = anomalies.map((a) => {
const cpa = Math.round(a.cost / a.conversions);
return `${a.campaignName}: CPA ${cpa.toLocaleString()}円`;
});
MailApp.sendEmail(
config.notifyEmail,
`【アラート】CPA異常値 ${anomalies.length}件`,
lines.join('\n')
);
}
Logger.log(`処理完了: ${metrics.length}件中 ${anomalies.length}件が異常値`);
}
型定義(interface)を導入することで、データ構造が明示されます。関数の引数と戻り値の型が宣言されているため、呼び出し側での誤用をエディタが検出できます。
Git連携の実務
.gitignore の設計
GASプロジェクトのGit管理では、以下の.gitignoreを設定します。
node_modules/
.clasprc.json
.env
*.log
dist/
.clasprc.jsonにはGoogleアカウントの認証トークンが含まれるため、絶対にGitにコミットしないでください。.clasp.jsonにはスクリプトIDが含まれますが、これは秘密情報ではないためコミットして問題ありません。
| ファイル | Git管理 | 理由 |
|---|---|---|
| .clasp.json | する | スクリプトIDはチームで共有する |
| .clasprc.json | しない | 認証トークンが含まれる |
| .claspignore | する | push対象の定義はチームで統一する |
| tsconfig.json | する | TypeScript設定はチームで統一する |
| package.json | する | 依存パッケージの定義 |
| node_modules/ | しない | npm installで再現可能 |
ブランチ戦略
GASプロジェクトの開発には、シンプルなブランチ戦略が適しています。
main(本番)
└── feature/xxx(機能開発)
GASには「ステージング環境」の概念がないため、複雑なブランチモデルは不要です。mainブランチが本番のGASプロジェクトに対応し、機能追加はfeatureブランチで開発してPRをマージする流れが実用的です。
PRベースのデプロイフロー
PRがマージされた後にclasp pushを実行するのが基本的な流れです。GitHub Actionsで自動化することも可能ですが、GASプロジェクトの認証情報(.clasprc.jsonのトークン)をCI環境に配置する必要があるため、セキュリティ面の検討が必要です。
小規模チームであれば、マージ担当者がローカルでclasp pushを手動実行するシンプルな運用で十分な場合が多いです。
プロジェクト構成のベストプラクティス
ディレクトリ構成
以下は、claspプロジェクトの推奨ディレクトリ構成です。
my-gas-project/
├── .clasp.json # スクリプトID設定
├── .claspignore # push除外ファイル
├── .gitignore # Git除外ファイル
├── package.json # npm依存定義
├── tsconfig.json # TypeScript設定
├── src/ # GASソースコード(pushの対象)
│ ├── main.ts # エントリーポイント
│ ├── config.ts # 設定読み取り
│ ├── fetcher.ts # データ取得
│ ├── reporter.ts # レポート生成
│ ├── notifier.ts # 通知送信
│ └── appsscript.json # GASプロジェクト設定
└── tests/ # テストコード(pushされない)
├── config.test.ts
└── fetcher.test.ts
src/ディレクトリにGASにpushするファイルだけを配置し、.clasp.jsonのrootDirを./srcに設定します。
ファイル分割の指針
| ファイル | 責務 | 内容 |
|---|---|---|
| main.ts | エントリーポイント | トリガーから呼ばれる関数を定義 |
| config.ts | 設定管理 | スクリプトプロパティ・設定シートの読み取り |
| fetcher.ts | データ取得 | 外部APIやスプレッドシートからのデータ取得 |
| reporter.ts | レポート生成 | データの加工・シートへの書き出し |
| notifier.ts | 通知 | Slack・メール通知の送信 |
1ファイルに全処理を書くと、可読性が下がり変更の影響範囲が把握しにくくなります。責務ごとにファイルを分割し、各ファイルは300行以内に収めるのが目安です。
運用メモ GASにはモジュールシステムがないため、TypeScriptの
import/exportは使えません。ファイルを分割しても、すべての関数はグローバルスコープに配置されます。名前の衝突を避けるために、ファイルごとにプレフィックス(config_load、fetch_adData等)を付けるか、名前空間オブジェクトを使う方法があります。
appsscript.json
GASプロジェクトのマニフェストファイルです。使用するGoogleサービスのスコープや、タイムゾーン、ランタイムバージョンを定義します。
{
"timeZone": "Asia/Tokyo",
"dependencies": {},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/script.send_mail"
]
}
oauthScopesを明示的に記述すると、スクリプトが要求する権限を最小限に制御できます。記述しない場合は、GASが使用するAPIから自動的に推定しますが、不要な権限が含まれることがあります。
Git hookによる品質チェック
push前に型チェックとリントを自動実行することで、GASプロジェクトへの不正なコードの反映を防止できます。
pre-commit hookの設定
package.jsonにhuskyとlint-stagedを導入します。
npm install --save-dev husky lint-staged
npx husky init
.husky/pre-commitに以下を記述します。
#!/usr/bin/env sh
npx lint-staged
package.jsonにlint-stagedの設定を追加します。
{
"lint-staged": {
"src/**/*.ts": [
"npx tsc --noEmit"
]
}
}
これにより、git commitのたびにTypeScriptの型チェックが実行されます。型エラーがある場合はコミットが中断されるため、GASプロジェクトに不正なコードがpushされるリスクを低減できます。
clasp push前チェックスクリプト
clasp pushの前にも型チェックを行うスクリプトをpackage.jsonに定義しておくと安全です。
{
"scripts": {
"check": "npx tsc --noEmit",
"push": "npm run check && clasp push",
"deploy": "npm run push && clasp deploy"
}
}
npm run pushを実行すれば、型チェックが通った場合のみclasp pushが実行されます。
注意点
clasp pushの上書きリスク
clasp pushはGASプロジェクトの全ファイルをローカルの内容で上書きします。差分反映ではなく全量置換です。
もし別のメンバーがスクリプトエディタで直接編集した内容があれば、clasp pushで上書きされて消えます。claspを導入したら、スクリプトエディタでの直接編集は原則禁止にしてください。
| 操作 | 動作 | リスク |
|---|---|---|
| clasp push | ローカル → GAS(全量上書き) | エディタの直接編集が消える |
| clasp pull | GAS → ローカル(全量上書き) | ローカルの未コミット変更が消える |
| clasp push —watch | ファイル変更を検知して自動push | 開発中の不完全なコードが反映される |
push前には必ずclasp pullで最新の状態を確認する、もしくは「スクリプトエディタでは編集しない」というルールをチームで徹底してください。
認証の有効期限
.clasprc.jsonに保存される認証トークンには有効期限があります。期限切れになるとclasp push等のコマンドが失敗します。
clasp login --creds creds.json
再ログインで解決します。頻繁にログインが切れる場合は、サービスアカウントを使った認証も検討してください。
チーム開発時の競合対策
複数人で同じGASプロジェクトを開発する場合、以下のルールを設けておくと競合を防げます。
- スクリプトエディタでの直接編集を禁止する
clasp pushの実行権限をmainブランチのマージ担当者に限定する- push前に必ず
git pullでmainブランチの最新を取り込む .clasp.jsonのスクリプトIDは全員が同じ値を使用する
運用メモ 一人で開発する場合でも、claspの導入は有効です。Gitの履歴があれば、「先週まで動いていた処理がなぜ壊れたか」を差分から追跡できます。スクリプトエディタのバージョン保存機能では、変更の理由や背景を記録できません。コミットメッセージに変更の意図を残す習慣は、将来の自分へのドキュメントになります。
まとめ
claspは、GAS開発にバージョン管理・型安全・コードレビューのプラクティスを導入するためのツールです。スクリプトエディタでの開発が手狭に感じ始めたタイミングが導入の適期です。
導入の手順は、npm install → clasp login → clasp clone(またはcreate)の3ステップです。TypeScript対応も@types/google-apps-scriptを追加するだけで始められます。
最初のステップとしては、既存のGASプロジェクトをclasp cloneでローカルに取り込み、Git管理を開始するだけで十分です。TypeScript化やGit hookの導入は、その後で段階的に進めてください。
チームで開発する場合は、「スクリプトエディタでの直接編集を禁止する」というルールだけは初日から徹底することをおすすめします。claspの価値は、コードの一元管理にあります。管理画面での編集が混在すると、その価値が損なわれます。
運用型広告のコンサルタント。Google広告・Meta広告・Yahoo!広告を中心に10年以上の実務経験。