yamamoto-yuta / yamamoto-yuta.github.io

https://yamamoto-yuta.github.io/
0 stars 0 forks source link

Docker で clasp 環境を構築する #35

Open yamamoto-yuta opened 7 months ago

yamamoto-yuta commented 7 months ago
# 必要に合わせてコメントアウトを外して記載してください

# 記事の説明文(無い場合は本文先頭200文字を使用)
#ogp_description:

# サムネイル画像のテーマ -> 'default' or 'upload'
thumbnail_theme: default

# サムネイル画像の背景画像(1280x670px推奨, なくてもOK)
#thumbnail_image_url: 

# 予約投稿の日時(無い場合は現在時刻を使用)
#posted_at: YYYY-MM-DD hh:mm

clasp 環境を Docker で作ってみたので、そのときの作業ログを以下に示す。

Clasp とは

GAS をローカルで開発するためのツール。

公式リポジトリ: google/clasp: 🔗 Command Line Apps Script Projects

前準備: GAS API を有効化する

ここから有効化できる: https://script.google.com/home/usersettings

用意するファイルとディレクトリ構造

ディレクトリ構造:

.
|-- .gitignore
|-- .env
|-- docker-compose.yml

用意するファイル:

.gitignore ``` .* .*/ node_modules/ dist/Code.gs !.gitignore !.*.sample ``` 補足: * `Code.gs` はビルド結果なので gitignore しておく
.env ``` WORKING_DIR=/usr/src/app HOME=$WORKING_DIR ``` 補足: - clasp はログインの credential 情報をコンテナ内のユーザの `$HOME` 直下に作成する( [→参考](https://arc.net/l/quote/lbrrbdld) )ので、 `$HOME` を `$WORKING_DIR` にするよう設定している - docker-compose.yml によってカレントディレクトリが `$WORKING_DIR` にマウントされる=カレントディレクトリに credential 情報が書かれたドットファイルが置かれるが、 .gitignore で指定したドットファイル以外は gitignore するようにすることで誤 push を防いでいる
docker-compose.yml ```yaml version: '3' services: app: image: node:20 container_name: docker_clasp_container env_file: - .env volumes: - ./:$WORKING_DIR working_dir: $WORKING_DIR tty: true ```

環境構築手順

コンテナを起動して中に入る・

$ docker compose up -d
$ docker exec -it <CONTAINER_ID> bash

yarn init し、Clasp と TypeScript をインストールする。

[In the container]# yarn init -y
[In the container]# yarn add -D @google/clasp @types/google-apps-script typescript ts-loader

clasp にログインする。

[In the container]# yarn clasp login
① 出てきた URL にアクセス
② Google アカウントでログイン
③ localhost:*** という無効な URL に遷移すれば OK
④ 別ターミナルでコンテナ内に入り、 curl 'さっきの無効な URL'
⑤ ターミナルにログイン成功の旨が出ていればOK
補足: なぜ別ターミナルで curl する必要があるのか? どうやら `clasp login` の `--no-localhost` オプションがうまく機能しないらしいため。 その回避策として別ターミナルで curl を叩く方法が紹介されていた( [→参考](https://qiita.com/naoyeah/items/0db5fc82561020f2768e) )。 今回、 `--no-localhost` オプションは使用していないが、同じ方法でログインできた。


今回は スクリプトIDが <GAS_SCRIPT_ID> の GAS プロジェクトのソースコードを src/ ディレクトリに配置することにする。

そのため、まず src/ ディレクトリを作成する。

[In the container]# mkdir src

指定したスクリプトIDのGASプロジェクトのコードをローカルへcloneする。

[In the container]# yarn clasp clone <GAS_SCRIPT_ID>

clone 後、次の3ファイルが生成される。

.
|-- src/
|-- .clasp.json
|-- appsscript.json
|-- <YOUR_GAS_SCRIPT>.js

このうち、次の2ファイルを src/ へ移動させる。

[In the container]# mv appsscript.json <YOUR_GAS_SCRIPT>.js src/

.clasp.jsonrootDir を次のように変更する。

-     "rootDir": "/usr/src/app"
+     "rootDir": "/usr/src/app/src"

clasp push で、ローカルのコードを GAS 上へ反映させる。

[In the container]# yarn clasp push

Web 上の GAS エディタのページをリロードすると、ローカルのコードが反映されているはず。

ES modules の利用

2024/03/18現在、 GAS は ES modules に対応しておらず、 import などが使えない。

使えるようにする方法はいくつかあるようだが、今回は gas-webpack-plugin を使ってみる。

Webpack と gas-webpack-plugin をインストール。

[In the container]# yarn add -D gas-webpack-plugin webpack webpack-cli

今回は src/ のソースコードをビルドして dist/ に置くことにする。

そのため、まず dist/ を作成する。

[In the container]# mkdir dist/

続いて、 appsscript.jsondist/ へ移動させる。

[In the container]# mv src/appsscript.json dist/

併せて、 .clasp.jsonrootDir を次のように変更する。

-     "rootDir": "/usr/src/app/src"
+     "rootDir": "/usr/src/app/dist"

webpack.config.json を作成し、次の内容を設定する。

const path = require("path");
const GasPlugin = require("gas-webpack-plugin");

module.exports = {
    context: __dirname,
    entry: "./src/index.ts",
    output: {
        path: path.join(__dirname, "dist"),
        filename: 'Code.gs'
    },
    resolve: {
        extensions: [".ts", ".js"],
    },
    module: {
        rules: [
            {
                test: /\.[tj]s$/,
                use: 'ts-loader',
                exclude: /node_modules/,
            }
        ],
    },
    plugins: [
        new GasPlugin()
    ],

}

この時点で、次のようなディレクトリ構造になっているはず。

.
|-- /dist
|   |-- appsscript.json
|-- src/
|   |-- <YOUR_GAS_SCRIPT>.js
|-- .clasp.json
|-- webpack.config.js

yarn webpack でコードをビルドした後、 clasp push で、ローカルのコードを GAS 上へ反映させる。

[In the container]# yarn webpack --mode production
[In the container]# yarn clasp push

Web 上でローカルのコードが確認できたら OK 。

サンプルコード

clasp create 等の際の動作確認用サンプルコードを以下に示す。

ディレクトリ構造:

.
|-- src/
|-- index.ts
|   |-- main.ts

index.ts

import { mainFunc } from './main'

declare const global: any;

global.mainFunc = mainFunc;

main.ts

export const mainFunc = () => console.log('Hello World')

TIPS

こんな感じで Makefile に clasp push 用コマンドを登録しておくと、 make push で GAS へ push できて楽。

Makefile

.PHONY: push
push:
    docker compose run --rm app bash -c "yarn webpack --mode production && yarn clasp push"

参考記事