IkumaTadokoro / diary

MIT License
0 stars 0 forks source link

2022-07-01 #48

Open IkumaTadokoro opened 2 years ago

IkumaTadokoro commented 2 years ago

TypeScriptでGoogle Apps Scriptを書こう!

とりあえずスクラップ

https://zenn.dev/kyo9bo/articles/ffc0d8b8076052

https://zenn.dev/fillz_noh/articles/c6a3a504b0cefc

https://zenn.dev/phi/articles/google-apps-script-snippets

https://zenn.dev/offers/articles/20220616-google-app-script-technique

https://zenn.dev/daria_nicht/articles/41c39bb4413db8

https://zenn.dev/kkenjii/articles/gas-clasp-usage

claspを使って、TypeScriptでGASを書くのが良さそう。

claspを使ってみる

https://github.com/google/clasp

インストール

$ npm i @google/clasp -g

ログインする

$ clasp login
Logging in globally…
🔑 Authorize clasp by visiting this url:
https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fscript.deployments%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fscript.projects%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fscript.webapp.deploy%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fservice.management%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Flogging.read%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&response_type=code&client_id=1072944905499-vm2v2i5dvn0a0d2o4ca36i1vge8cvbn0.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A65472

Authorization successful.

Default credentials saved to: /Users/tadokoroikuma/.clasprc.json.

claspでTypeScriptを使えるようにする

https://github.com/google/clasp/blob/master/docs/typescript.md

$ mkdir hello-world-clasp
$ cd hello-world-clasp
$ npm i @types/google-apps-script
$ vim tsconfig.json
{
  "compilerOptions": {
    "lib": ["es2022"],
    "experimentalDecorators": true
  }
}

プロジェクトの作成

❯ clasp create --help
Usage: clasp create [options]

Create a script

Options:
  --type <type>        Creates a new Apps Script project attached to a new Document, Spreadsheet, Presentation, Form, or as a standalone script, web app, or API.
  --title <title>      The project title.
  --parentId <id>      A project parent Id.
  --rootDir <rootDir>  Local root directory in which clasp will store your project files.
  -h, --help           display help for command

$ clasp create --title "Hello World" --type standalone

$ ls -la
# appscript.jsonが作成される

TimezoneがAmerica/NewYorkなので、Asia/Tokyoに変更する

{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}
~

Hello World

const greeter = (person: string) => {
  return `Hello, ${person}!`;
}

const testGreeter() {
  const user = 'ikuma';
  Logger.log(greeter(user))
}

デプロイする

❯ clasp push
? Manifest file has been updated. Do you want to push and
overwrite? Yes
└─ appsscript.json
└─ hello.ts
Pushed 2 files.

正直何を上書きしたのかはわからない

$ clasp open

これでウェブのエディタが開く。hello.gsが表示された。

// Compiled using hello-world-clasp 1.0.0 (TypeScript 4.7.4)
var greeter = function (person) {
    return "Hello, ".concat(person, "!");
};
var testGreeter;
(function () {
    var user = 'ikuma';
    Logger.log(greeter(user));
});

TypeScriptも最新っぽいね

Logger.logが表示されない→testGreeterが関数じゃなかった

const greeter = (person: string) => {
  return `Hello, ${person}!`;
}

const testGreeter = ():void => {
  const user = 'ikuma';
  Logger.log(greeter(user))
}
IkumaTadokoro commented 2 years ago

https://zenn.dev/ryo_kawamata/articles/2c6cc4e7c27210

webpackでできるならViteもできる?

https://www.npmjs.com/package/gas-webpack-plugin

これが必要みたい。GASで実行可能な関数がトップレベル関数だけなので、このプラグインがバンドルするタイミングで実行対象の関数をトップレベルに配置するという仕組み。

実行可能というのはGASのエディタで実行の選択肢に出てくる関数っぽいので、private的な役割だったら大丈夫みたい。

https://qiita.com/mahaker/items/7beb8aaf357fb3c32144

こんなの見つけた。これはesbuildの例。 結局のところ、グローバルオブジェクトに関数宣言文で関数を定義できればwebpack縛りである必要はない。

https://github.com/fossamagna/gas-entry-generator

これを使えばどうも関数宣言文を作成できるみたいで、これを組み込んだプラグインを作ればViteでもチャンスはあるみたい。

仕組み的にはgas-entry-generatorを動かして、その生成物 + ビルド結果を単純に合成しているみたい。

IkumaTadokoro commented 2 years ago

まずはwebpackのテンプレートリポジトリをコピーして使ってみて、使い勝手を確かめる

https://github.com/IkumaTadokoro/gas-webpack-sample

う〜ん、build落ちちゃうな。これは自分で一から作っていった方が良さそう。

IkumaTadokoro commented 2 years ago

esbuildを使ってpjを作成してみる

https://engineering.mercari.com/blog/entry/20211215-operation-tool-coupon/

https://aloerina01.github.io/blog/2021-09-15-1

$ mkdir esbuild-gas-sample
$ npm install -D esbuild
$ npm install -D esbuild-gas-plugin

たぶんなんか適当に作ればGASっぽい感じになると思われるので、やっている。

$ mkdir src
$ mkdir dist
$ touch src/index.ts
$ touch bin/build

# index.tsとbin/buildを修正

$ chmod u+x bin/build
$ bin/build
✘ [ERROR] Expected ";" but found "add"

    src/utils.ts:1:5:
      1 │ onst add = (n1: number, n2: number): number =...
        │      ~~~
        ╵      ;

1 error
✘ [ERROR] [plugin gas-plugin] ENOENT: no such file or directory, open 'dist/bundle.js'

    /Users/tadokoroikuma/src/github.com/IkumaTadokoro/esbuild-gas-sample/node_modules/esbuild-gas-plugin/dist/index.js:7:25:
      7 │ ...  const outfile = fs.readFileSync(build.in...
        ╵                         ^

ちょっと修正する。onstになってた。

$ bin/build

え!早すぎでは!!


ここからclaspを使ってpushできるようにしていく。

$ touch .clasp.json
"scripts": {
  "build": "bin/build",
  "deploy": "bin/build && clasp push",
}

あ、appscripts.jsonがないって言われている。これどこに追加すればいいのかな?とりあえずsrcにおいてみる、多分ダメ。

ENOENT: no such file or directory, open 'dist/appsscript.json'

一旦、直接distに配置するappsscript.json。m名前間違いやすい

Could not find script.
Did you provide the correct scriptId?
Are you logged in to the correct account with the script?

あれ、もしかして.clasp.jsonも移動する必要がある? そういうことじゃないみたい。移動してもだめだった。

なんかIDが違ったみたい。修正したらとりあえずdeployはできたけど、エディタでみると何もなかった...。

う〜ん、何もデプロイされていないなあ

とりあえずできた。