GAS ウェブアプリが突然開けない — ブラウザ用ライブラリ混入と clasp の盲点を API 版比較と読み込みテストで潰す
直前デプロイで混入した minified ライブラリが Apps Script 起動時に例外を投げ全画面が死ぬ事故の診断・修正・再発防止。版番号指定の API 比較、GAS 相当グローバルでの読み込みテスト、clasp がリモート専用ファイルを消さない対処まで。
約5.1万トークンの節約 (API料金換算で約77円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。
この巻物について
「GAS ウェブアプリが突然開けない — ブラウザ用ライブラリ混入と clasp の盲点を API 版比較と読み込みテストで潰す」は、Google WorkspaceカテゴリのAI指示書(MDファイル)です。直前デプロイで混入した minified ライブラリが Apps Script 起動時に例外を投げ全画面が死ぬ事故の診断・修正・再発防止。版番号指定の API 比較、GAS 相当グローバルでの読み込みテスト、clasp がリモート専用ファイルを消さない対処まで。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約5.1万トークン(API料金換算で約77円)・85%のトークンを節約できます。
- カテゴリ
- Google Workspace
- 対応AI
- claude-code、cursor、codex-cli
- ライセンス
- 商用利用可 (再販不可)
- 価格
- 無料
- ゼロから開発時
- 約6万トークン
- この巻物使用時
- 約9,000トークン
- 節約量
- 約5.1万トークン (約77円)
- 更新日
- 2026-10-11
使い方 (AIに渡す3つの方法)
いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。
claude "https://makimono-md.vercel.app/api/v1/files/gas-clasp-api/raw を読み込んで、この指示書どおりに実装して"
中身
GAS ウェブアプリが突然「開けない」— ブラウザ用ライブラリの混入と clasp push の盲点
症状
- Apps Script のウェブアプリが、直前のデプロイまで動いていたのに全画面で開けなくなる(Google のエラーページ、または真っ白)。
doGetだけでなく、同じプロジェクトのトリガー関数やgoogle.script.runもすべて失敗する。- 直前のデプロイで「HTML 側の変更しかしていない」のに起きる。
原因
- Node でのテスト用にプロジェクトのローカルフォルダへ置いたブラウザ用の minified ライブラリ(例:
zxing.min.js、jspdf.min.js、chart.min.jsなど)が、clasp pushでそのままサーバー側 .js として送られた。 - Apps Script はプロジェクト内の全 .gs/.js を毎回の実行開始時にトップレベルから評価する。UMD 形式のライブラリは起動時に
window/global/selfを探し、Apps Script の V8 ランタイムにはどれも無い(globalThisはある)。多くのライブラリはそこで例外を投げる(例:Error: Can't search globals for BigInt!)。 - トップレベルで例外が出るとすべてのエントリポイントが死ぬ。HTML が CDN から同じライブラリを読んでいるなら、サーバー側のコピーはそもそも不要。
診断手順(AI にそのまま実行させる)
- 直前の版と現在の版の中身を Apps Script API で取り、ファイル一覧を比較する。
GET https://script.googleapis.com/v1/projects/<scriptId>/content?versionNumber=<N>- トークンは
~/.clasprc.jsonのtokens.default.access_token(clasp を1回動かすと更新される)。 - 新しく増えたファイルがあれば最有力容疑。
- 全サーバー .js を「Apps Script 相当のグローバル」で読み込む再現テストを回す(下記)。
window/global/self/exports/module/define/requireを存在しない名前として扱うのが肝。UMD の最初の分岐でexportsやdefineがスタブに化けると、ライブラリ本体が実行されずに「読み込み OK」と誤判定する。
// gas-load.test.mjs — node gas-load.test.mjs --src <clasp pull したフォルダ>
import fs from 'node:fs'; import path from 'node:path'; import vm from 'node:vm';
const src = process.argv[process.argv.indexOf('--src') + 1];
const ABSENT = new Set(['window','document','navigator','self','global','exports','module','define','require']);
const base = {}; for (const k of Object.getOwnPropertyNames(globalThis)) { if (ABSENT.has(k) || k === 'globalThis' || k === 'process') continue; try { base[k] = globalThis[k]; } catch {} }
const stub = () => new Proxy(function(){}, { get: (t, p) => p === 'then' ? undefined : stub(), apply: () => stub(), construct: () => stub() });
let ok = true;
for (const f of fs.readdirSync(src).filter(n => n.endsWith('.js') || n.endsWith('.gs')).sort()) {
const ctx = vm.createContext(new Proxy(base, { has: (t, p) => !ABSENT.has(p), get: (t, p) => ABSENT.has(p) ? undefined : (p in t) ? t[p] : (typeof p === 'symbol' ? undefined : stub()) }));
try { vm.runInContext(fs.readFileSync(path.join(src, f), 'utf8'), ctx, { filename: f, timeout: 20000 }); console.log('✅', f); }
catch (e) { ok = false; console.log('❌', f, '→', e.name + ': ' + e.message); }
}
console.log(ok ? 'ALL PASS' : 'FAIL'); process.exit(ok ? 0 : 1);
SpreadsheetApp 等の GAS 固有グローバルはスタブで握りつぶすので、通常の業務コードは「load OK」になり、混入ライブラリだけが落ちる。
修正手順
- ローカルフォルダから混入ファイルを削除する。
clasp push -fは「ローカルに変更が無い」とScript is already up to dateで何も送らず、リモートだけにあるファイルは消えない。この状態でclasp deployすると、壊れたままの新バージョンができる。対処はどちらか:- Apps Script API で全ファイルを丸ごと送る:
PUT /v1/projects/<scriptId>/contentに{ files: [{ name, type: 'SERVER_JS' | 'HTML' | 'JSON', source }] }(.clasp.jsonは含めない、appsscriptはJSON)。 - どれか 1 ファイルに実変更(コメント1行など)を入れてから push する。
- Apps Script API で全ファイルを丸ごと送る:
clasp deploy --deploymentId <既存ID>で同じデプロイ ID に新バージョンを当てる(URL を変えない)。- read-back:
GET /v1/projects/<scriptId>/deployments/<deploymentId>でversionNumberが新番号になっていること、GET .../content?versionNumber=<新番号>のファイル一覧に混入ファイルが無いこと、ローカルと byte 一致することを確認する。
再発防止
- テスト用ライブラリは clasp の
rootDirの外(test/vendor/等、.clasp.jsonの rootDir 配下以外)に置く。または.claspignoreに*.min.jsを書く。 - push 前に上の
gas-load.test.mjsを毎回通す。 - push 後に必ず HEAD の
contentをファイル名一覧で読み戻し、想定ファイル数と一致するか見る。 - デプロイ前の「本番との差分」は
clasp pullの結果同士ではなく、版番号指定の API 取得で比較すると確実(clasp pullは HEAD しか取れない)。
落とし穴まとめ
| 現象 | 実体 |
|---|---|
Script is already up to date と出たのにリモートに余計なファイルが残る | clasp はローカル変更の有無だけを見る。リモート専用ファイルの削除は API で全送信 |
| Node の再現テストで混入ライブラリが「load OK」になる | exports/define がスタブ化され UMD の別分岐に入った。ABSENT に含めること |
| ウェブアプリは curl でサインイン画面までしか見えない | ログイン必須の GAS は外から実描画を確認できない。API の版比較と load テストを一次情報にする |
よくある質問
+「GAS ウェブアプリが突然開けない — ブラウザ用ライブラリ混入と clasp の盲点を API 版比較と読み込みテストで潰す」とは何ですか?
直前デプロイで混入した minified ライブラリが Apps Script 起動時に例外を投げ全画面が死ぬ事故の診断・修正・再発防止。版番号指定の API 比較、GAS 相当グローバルでの読み込みテスト、clasp がリモート専用ファイルを消さない対処まで。
+どれくらいトークン(費用)を節約できますか?
ゼロから開発すると約6万トークンかかりますが、この巻物を使えば約9,000トークンで済みます。差し引き約5.1万トークン(API料金換算で約77円)・85%の節約です。
+どうやって使いますか?
無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。
+どのAIツールに対応していますか?
claude-code、cursor、codex-cli に対応しています。
+商用利用できますか?
ライセンスは「商用利用可 (再販不可)」です。
🤝 自分でAIを動かすのは、まだ不安…という方へ
この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。
関連する巻物
GAS完全自動化テンプレ — Driveコマンドキュー方式
Google Apps Script の「毎回エディタで▶実行」を根絶。Drive 経由のコマンドキューで、初回1クリック以降は AI がすべての GAS 関数をリモート実行できるようになるテンプレート指示書。
人間の手入力台帳を壊さずに自動更新する — GAS Web App upsert 設計
各PC/各拠点の点検結果を、人間が手運用しているスプレッドシート台帳へ自動反映する。手入力列とコメントを絶対に壊さない突合設計、タブ/列の解決、並行POST対策、配布シークレットの落とし穴まで。
数式まみれの業務スプレッドシートを、Webアプリから壊さずに編集させる型
ArrayFormula と per-row 数式が混在する台帳を、セル単位 allowlist・dry-run 既定・適用前バックアップ・触っていないセルの数式不変検査で安全に書き換える設計手順。列ごとの数式復元と、テストが緑のまま壊れる典型例つき。
この巻物、誰かのトークンも救えます
𝕏 で節約レシートをシェア