GAS上にReactプロジェクトを作成する方法

# 概要

Google Apps Scriptの環境でReactのWebアプリを作成する際の手順になります.

## 目次

- [概要](#概要)
  - [目次](#目次)
  - [動作環境](#動作環境)
  - [Reactプロジェクトの作成](#reactプロジェクトの作成)
  - [buildの設定](#buildの設定)
  - [claspを用いたデプロイ](#claspを用いたデプロイ)
    - [claspの追加](#claspの追加)
    - [claspのログイン](#claspのログイン)
    - [GASプロジェクトを新規作成](#gasプロジェクトを新規作成)
    - [appsscriptファイルの設定](#appsscriptファイルの設定)
    - [doGet()用ファイルの作成](#doget用ファイルの作成)
    - [アップロードファイルの整理](#アップロードファイルの整理)
    - [push / deploy](#push--deploy)
  - [補足](#補足)
    - [google-apps-scriptの型定義](#google-apps-scriptの型定義)
  - [参考](#参考)


## 動作環境

- Windows 11
- node v20.12.2
- npm 10.5.0
- vite 5.2.11
- gitbash

## Reactプロジェクトの作成

始めにReactプロジェクトをViteから作成します.

```gitbash
~\typescript> npm create vite
√ Project name: ... gas-test-project
? Select a framework: » - Use arrow-keys. Return to submit.
    Vanilla
    Vue
>   React
    Preact
    Lit
    Svelte
    Solid
    Qwik
    Others
? Select a variant: » - Use arrow-keys. Return to submit.
    TypeScript
>   TypeScript + SWC
    JavaScript
    JavaScript + SWC

Scaffolding project in C:~\typescript\gas-test-project...

Done. Now run:

  cd gas-test-project
  npm install
  npm run dev
```

プロジェクトディレクトリに移動し,以下コマンドから問題なく起動できるか確認します.

```gitbash
npm install
npm run dev
```

![Vite_React.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357884/5151ce00-7c85-a586-4be1-87258471021f.png)


## buildの設定

GASプロジェクトにアップロードするファイルを1つにまとめたいので, viteのvite-plugin-singlefileをインストールします.

```gitbash
~/gas-test-project
$ npm install vite-plugin-singlefile --save-dev

added 1 package, and audited 164 packages in 1s

38 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
```

vite.config.tsにvite-plugin-singlefileに関する記述を追加します.

併せてファイル出力先を変更しておきます.

```ts
# vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import { viteSingleFile } from "vite-plugin-singlefile"

export default defineConfig({
  plugins: [react(), viteSingleFile()],
  build: {
    outDir: 'dist/src',
  }
})
```

buildした際に生成したファイルはsrc内, その他のGASプロジェクトにアップロードしたいファイルはdist直下に入れておきます.

```
.
└── dist
    ├── src
    │   ├── index.html
    │   └── vite.svg
    └── // 後ほどファイルを追加 
```


記述後にnpm run buildをするとdistフォルダ, srcフォルダとその中にindex.htmlが出力されます.


## claspを用いたデプロイ

### claspの追加

今回はclaspを用いて管理をしていきます.

プロジェクトにclaspをインストールしていきます.

```gitbash
~\gas-test-project> npm install -g @google/clasp

changed 274 packages in 20s

86 packages are looking for funding
  run `npm fund` for details
```

### claspのログイン

インストール後にclasp loginでログインできます.

ログイン画面が出てくるので進めてください.

```
~/gas-test-project
$ clasp login
Warning: You seem to already be logged in *globally*. You have a ~/.clasprc.json
Logging in globally…
🔑 Authorize clasp by visiting this url:
~~~~~~~~~~~~~~~~~~~

Authorization successful.

Default credentials saved to: C:\Users\black\.clasprc.json.
```

### GASプロジェクトを新規作成

clasp createでGASプロジェクトを作成します.

```
~/gas-test-project
$ clasp create
? Create which script?
  standalone
  docs
  sheets
  slides
  forms
> webapp
  api

Created new webapp script: https://script.google.com/d/~~~~ ← GASプロジェクトのリンク
Warning: files in subfolder are not accounted for unless you set a '~~~' file.
Cloned 1 file.
└─ ~\gas-test-project/appsscript.json
```

### appsscriptファイルの設定

appsscript.jsonファイルはGASプロジェクトの設定ファイルになります.

このファイル中にwebappの項目を追加することでclasp deploy時にwebアプリとして認識してくれるようです.

```json
{
  "timeZone": "America/New_York",
  "dependencies": {
  },
  "webapp":{}, // 空でもいいので作成する
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}
```

タイムゾーンを東京にしWebアプリのアクセスユーザを誰でも,実行権限はデプロイユーザにする場合は以下のようになります.

```json
{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
  },
  "webapp": {
    "executeAs": "USER_DEPLOYING",
    "access": "ANYONE" 
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}
```

### doGet()用ファイルの作成

Webアプリにアクセスした際に(GETリクエストされた際に)doGet関数が実行されます.

その中でsrc/index.htmlを呼び出すように設定します.

```ts
export function doGet() : GoogleAppsScript.HTML.HtmlOutput{
    return HtmlService.createHtmlOutputFromFile("src/index.html")
}
```

### アップロードファイルの整理

上記で編集したappsscript.json, doget.tsはGASプロジェクトにアップロードするのでdistフォルダに移動します.

vite.svgはアップロードできないので削除すると以下のようなフォルダ構成になります.

```
.
└── dist
    ├── src
    │   └── index.html
    ├── appsscript.json
    └── doget.ts
```


### push / deploy

clasp pushでは.clasp.jsonのrootDirの配下にあるファイルをGASプロジェクトにアップロードします.

今回はdist配下のファイルをアップロードしたいのでrootDirの指定先を変えます.

```
{
    "scriptId":"~~~~",
    "rootDir":"C:\\~\\gas-test-project\\dist"
}
```

記載の変更ができたらclasp push, clasp deployでWebアプリのデプロイをします.

```
clasp push
clasp deploy
```


![end.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357884/51f98e7e-a8b5-9682-6d20-964187301fce.png)



## 補足

### google-apps-scriptの型定義

google-apps-scriptの型定義ファイルは以下のコマンドで取得できます.

```
npm install --save @types/google-apps-script
```

## 参考

- [Clasp](https://github.com/google/clasp)
- [@types/google-apps-script](https://www.npmjs.com/package/@types/google-apps-script)
- [vite-plugin-singlefile](https://www.npmjs.com/package/vite-plugin-singlefile)