コンテナに GAS + TypeScript + clasp + Jest の環境を作成したい!

## はじめに

Docker コンテナを利用して、ホストOS の環境を汚さずに Google Apps Script (GAS) の開発環境をセットアップするテンプレートリポジトリを作成しました。

https://github.com/ko-uema2/gas-proj-template

この記事では、このコンテナ環境でできることを紹介します。

## 前提

このテンプレートリポジトリを利用するにあたり、下記事項を満たしている必要があります。

- ホストOS に Docker Desktop がインストールされていること
- ホストOS に VSCode がインストールされていること
- ホストOS の VSCode に Dev Containers 拡張機能がインストールされていること
- ホストOS に Git がインストールされていること
- 自身の GitHub アカウントを持っていること
- 自身の Google アカウントを持っていること
- Google アカウントで Google Apps Script API が有効化されていること
  - [Google Apps Script APIを有効にする](https://zenn.dev/cordelia/articles/3107aaf8b7a3d6#google-apps-script-api%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B)

## このコンテナ環境でできること

このコンテナ環境を起動することで、ホストOS を汚さずに以下のことができるようになります。

1. `clasp` を利用して Google Apps Script のプロジェクトをデプロイすることができる。
   デプロイするコマンドを使い分けることで、本番環境と開発環境を分けてデプロイすることができます。

   ```bash
   # 本番環境にデプロイ
   npm run deploy:prod

   # 開発環境にデプロイ
   npm run deploy:dev
   ```

1. Google Apps Script のプロジェクトを TypeScript で開発することができる。
   `npm run build` コマンドを実行することで、TypeScript で開発したコードを GAS が実行できる JavaScript に変換できます。

   ```bash
   # TypeScript をコンパイルして JavaScript に変換
   npm run build
   ```

1. Google Apps Script のプロジェクトを Jest でテストすることができる。
   Jest を利用して、GAS のプロジェクトをテストすることができます。

   ```bash
   # テストを実行
   npm run test
   ```

1. Biome を利用して、GAS コードのフォーマット / 静的解析をすることができる。

   ```bash
   # 静的解析を実行
   npm run lint
   ```

1. license-check-and-add を利用して、ライセンス表記を各ファイルに追加することができる。

   [license-check-and-add - npm](https://www.npmjs.com/package/license-check-and-add)

   ```bash
   # ライセンス表記の追加
   npm run license
   ```

1. コンテナ環境の VSCode で下記拡張機能がデフォルトでインストールされている。

   - [Biome](https://marketplace.visualstudio.com/items?itemName=biomejs.biome)
   - [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
   - [Docker](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker)
   - [Docker DX](https://marketplace.visualstudio.com/items?itemName=docker.docker)
   - [Git Graph](https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph)
   - [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot)
   - [GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat)
   - [GitHub Pull Request](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github)
   - [gitignore](https://marketplace.visualstudio.com/items?itemName=codezombiech.gitignore)
   - [indent-rainbow](https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow)
   - [Japanese Language Pack for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MS-CEINTL.vscode-language-pack-ja)
   - [Jest](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest)
   - [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner)
   - [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one)
   - [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)
   - [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
   - [JavaScript (ES6) code snippets](https://marketplace.visualstudio.com/items?itemName=xabikos.JavaScriptSnippets)
   - [Material Icon Theme](https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme)
   - [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh)
   - [Remote - SSH: Editing Configuration Files](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh-edit)
   - [Remote - Tunnels](https://marketplace.visualstudio.com/items?itemName=ms-vscode.remote-server)
   - [Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)
   - [Remote Explorer](https://marketplace.visualstudio.com/items?itemName=ms-vscode.remote-explorer)
   - [WSL](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl)

1. `LazyGit` を利用して、VSCode のターミナルから Git の GUI 操作を行うことができる。

   [jesseduffield/lazygit: simple terminal UI for git commands](https://github.com/jesseduffield/lazygit)

   ```bash
   # LazyGit を起動
   lazygit

   # lazygit コマンドのエイリアスとして利用可能
   lg
   ```

1. `zsh` を利用したシェル操作ができる。  
   コンテナを起動すると、`zsh` がデフォルトのシェルとして起動します。

1. `oh-my-zsh` による zsh のカスタマイズができる。

   [ohmyzsh/ohmyzsh: 🙃 A delightful community-driven (with 2,400+ contributors) framework for managing your zsh configuration.](https://github.com/ohmyzsh/ohmyzsh)

   コンテナ起動時点では、作者の `.zshrc` ファイルが適用されています。  
   自身で `zsh` をカスタマイズしたい場合は、コンテナ内で `~/.zshrc` を編集してください。

   ```bash
   # .zshrc を編集
   vim ~/.zshrc
   ```

1. `peco` を利用して**コマンド検索**を行える。
   `ctrl + r` により、過去に実行したコマンドを検索することができます。

1. `peco` を利用して**ディレクトリ移動**を行える。
   `ctrl + u` により、過去に移動したディレクトリを検索することができます。

1. `zsh` の補完機能を利用して、コマンドの補完ができる。
   コマンド入力中に`tab` キーを押すことで、その後の候補を表示してくれます。

   [zsh-users/zsh-completions: Additional completion definitions for Zsh.](https://github.com/zsh-users/zsh-completions)

1. `zsh` の補完機能を利用して、シェルのコマンド履歴に基づいてコマンド候補を表示、入力補完を行える。
   入力途中のコマンドに対して、過去の履歴から続き候補をリアルタイムで表示してくれます。  
   また、候補が表示された状態で `tab` キーを　押すことで、コマンドの入力補完を行うことができます。

    [zsh-users/zsh-autosuggestions: Fish-like autosuggestions for zsh](https://github.com/zsh-users/zsh-autosuggestions)

## フォルダ構造

このテンプレートリポジトリを利用することで、以下のフォルダ構造が作成されます。

```bash
.
├── .devcontainer
│   ├── .env
│   ├── .env.sample
│   ├── devcontainer.json
│   ├── docker-compose.yml
│   ├── Dockerfile
│   │   # zsh の設定用スクリプト
│   │   # .zshrc のクローン / oh-my-zsh プラグインのインストールを実行
│   └── setup-zsh.sh
│   # ビルド時に生成されるフォルダ
│   # GAS のプロジェクトをデプロイする際に必要なファイル郡
├── dist
│   ├── appsscript.json
│   └── index.js
├── doc
│   │   # README.md 用画像ファイル
│   └── img
│       ├── CleanShot 2025-04-19 at 05.35.15.png
│       ├── CleanShot 2025-04-19 at 05.39.49.png
│       ├── CleanShot 2025-04-19 at 06.13.30.png
│       └── CleanShot 2025-04-19 at 06.38.35.png
├── node_modules
│   # GAS ソースコード
├── src
│   ├── example-module.ts
│   └── index.ts
│   # テストコード
├── test
│   └── example-module.test.ts
│   # ビルド用コード
│   # 詳細は tools/README.md を参照
├── tools
│   ├── build.ts
│   ├── exportHandlers.ts
│   └── README.md
├── .clasp.json.example
├── .claspignore
├── .gitignore
├── appsscript.json
├── biome.json
├── jest.config.json
│   # Apache-2.0 ライセンスファイル
├── LICENSE
│   # license-check-and-add 用設定ファイル
├── license-config.json
│   # ライセンスヘッダーファイル
├── license-header.txt
├── package-lock.json
├── package.json
├── README.md
└── tsconfig.json
```