8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

コストゼロからはじめよう!React + Vite + Google Apps ScriptでSPAを無料公開

Last updated at Posted at 2024-03-30

Google Apps Script(GASと呼ばることが多いですが、公式にはApps Scriptと略されます)は、Googleが提供するJavaScriptベースのスクリプティング言語です。このクラウド上で動作する環境を利用することで、GoogleスプレッドシートなどのGoogleアプリと連携したウェブアプリを誰でも無料で開発できます。

この記事では、Apps Scriptの開発ツールであるclaspを用いて、ReactとViteを組み合わせることにより、より洗練されたSingle Page Application(SPA)の開発プロセスを解説します。

  • clasp: Apps Scriptプロジェクトを効率的に管理するためのコマンドラインツール。ローカルでの開発を可能にし、変更を簡単にGoogle Cloudにプッシュできます。
  • React: 再利用可能なUIコンポーネントを作成することで、開発プロセスを加速し、保守が容易なアプリケーションを構築できます。
  • Vite: 開発中の高速なホットリローディングを提供し、最終的なビルドの効率を大幅に向上させるモダンなビルドツールです。

この記事では、clasp + React + Vite + Google Apps Scriptで無料のSPAを公開するまでの手順を具体的に紹介していきます。核となるのは、Reactで作ったフロントエンドをViteのプラグインで一つのindex.htmlにまとめてから、Google Apps Scriptのプロジェクトにpushするプロセスです。Apps Scriptのウェブアプリはページ間のリンク(<a>タグによるハイパーリンク)の扱いが得意ではありません。そこでページ間の遷移はReactで実現し、ファイル自体は一つにまとめてしまいます。

開発者はReactの豊富なコンポーネントを再利用しながら、より優れたUIを構築できます。またViteの効率的なビルドシステムのおかげでストレスなく開発できます。ローカル開発環境を準備するのは少々手間がかかりますがデバッグは容易になるので、結果的により高速な開発サイクルを実現できます。

この記事では、npm createでViteとReactのボイラープレートを作り、Apps Scriptのウェブアプリとして公開するところまでを紹介します。取り上げる題材は簡単なものですが、これを土台にすることで、より複雑なReactアプリをApp Scriptの環境で開発し公開することも可能になります。ぜひ手を動かしながらお楽しみください。

0. 事前準備

PCにNode.jsとclaspをインストールします。

Node.jsのインストール

WindowsやWSL2にNode.jsをインストールするには、マイクロソフトの記事が参考になります。

Macはいろいろな流派がありますが、私はHomebrew + nvmでNode.jsをインストールしています。

この記事では、次のバージョンを使います。

node -v
v20.9.0

claspのインストール

Node.jsのインストールが完了したら、claspをインストールします。

まず、Google Apps Script APIをOnにしておきます。

次に、claspをグローバルにインストールし、Googleアカウントでログインしておきます。

npm install -g @google/clasp
clasp login

この記事では、次のバージョンを使います。

clasp -v
2.4.2

1. Reactアプリを作成

Reactアプリを作成します。今回はJavaScriptで作ります1。アプリ名はhello-apps-scriptにします。プロジェクト名(hello-apps-script)の後に--を記載し忘れないよう注意してください。

npm create vite@latest hello-apps-script -- --template react

hello-apps-scriptディレクトリーができるので、開発用サーバーを動かしてReactアプリが動作することを確認します。なお、IDE、例えばVisual Studio Codeを使っている方は、IDEのターミナルから作業すると便利です。

cd hello-world
npm install
npm run dev

ターミナルにURLが表示されるので、ウェブブラウザーでアクセスして表示を確認します。

  VITE v5.2.7  ready in 1410 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

Vite + Reactの画面

count is 0ボタンをクリックすると、カウントアップしていきます。

2. ビルド環境構築

ViteでApps Scriptにアップロードするファイルをbuildします。

まず必要なパッケージをインストールします。

npm install --save-dev vite-plugin-singlefile vite-plugin-static-copy

vite-plugin-singlefileはJavaScriptやCSSをdist/index.htmlにまとめてくれます。

vite-plugin-static-copyは特定のフォルダーにあるファイルをdist以下にコピーしてくれます。

次にvite.config.jsファイルを編集します。

vite.config.js
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
import { viteSingleFile } from "vite-plugin-singlefile"
import { viteStaticCopy } from "vite-plugin-static-copy"

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    viteSingleFile(),
    viteStaticCopy({ targets: [{ src: "apps-script/*", dest: "./" }] }),
  ],
})

フロントエンドのコードはsrcディレクトリーに、バックエンドの(Apps Scriptの)コードはこれから作るapps-scriptディレクトリーに配置する前提です。

ここまで作業したら、正しくbuildできるか試してみます。

npm run build

> hello-apps-script@0.0.0 build
> vite build

vite v5.2.7 building for production...
✓ 34 modules transformed.
rendering chunks (1)...

Inlining: index-BXGOX9Nt.js
Inlining: style-DiwrgTda.css
computing gzip size (0)...[vite-plugin-static-copy] No items to copy.
dist/index.html  150.09 kB │ gzip: 49.62 kB
✓ built in 395ms

distディレクトリーの下にindex.htmlファイルが出力されました。

3. Apps Scriptのウェブアプリを作成

claspでApps Scriptのウェブアプリを作成します。スプレッドシートをデータベース代わりに使う事が多いので、--type sheetsを指定して、スプレッドシートのスクリプトとして作成します。新しいスプレッドシートはGoogleドライブのマイドライブに作成されます。

clasp create --type sheets --title "HelloAppsScript"

Could not read API credentials. Are you logged in globally?

というエラーが出た場合、clasp loginでログインを済ませてから実行してください。

User has not enabled the Apps Script API. Enable it by visiting https://script.google.com/home/usersettings then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

というエラーが出た場合、指示に従って Google Apps Script APIをONにしてから実行してください。

Project file (.clasp.json) already exists.

というエラーが出た場合、すでにclasp createでプロジェクトを作成済です。もし、再作成する場合は、ローカルにある.clasp.jsonと、Googleドライブに作った関連ファイルを手動で削除してから再実行してください。

この操作が成功すると、次の2つのファイルが作成されます。

  • .clasp.json
    • Apps Scriptのリソースを定義(後ほど修正します)
  • appsscript.json
    • Apps Scriptの設定を定義(後ほど移動、修正します)

.clasp.jsonを修正

.clasp.jsonrootDirは、どのソースコードをGoogle側にpushするかを定義しています。buildした結果をpushしたいので、distディレクトリーを指定しておきます(scriptIdparentIdはそのままで大丈夫です)。

.clasp.json
  "rootDir": "dist"

apps-scriptディレクトリーを作成

バックエンドのソースコードを置くために、apps-scriptディレクトリーを作成します。

mkdir apps-script

appsscript.jsonを移動、修正

appsscript.jsonはマニフェストファイルと呼ばる、プロジェクトの設定ファイルです。バックエンドのソースコードなので、apps-scriptディレクトリーを作り、そこに移動します(buildするタイミングでdistディレクトリーにコピーされます)。

mv appsscript.json apps-script

また、このApps Scriptはウェブアプリとして公開するため、appsscript.jsonを次のように編集しておきます。timeZoneAsia/Tokyoに変更し、webappを追加しています。

apps-script/appsscript.json
{
  "timeZone": "Asia/Tokyo",
  "dependencies": {},
  "webapp":  {
    "access": "MYSELF",
    "executeAs": "USER_DEPLOYING"
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}

apps-script/Code.jsを追加

バックエンドのコードとして、apps-scriptディレクトリーの下にCode.jsを追加します。ウェブアプリにアクセスがあると、index.htmlを返却するために、doGet()を実装します。

apps-script/Code.js
function doGet() {
  return HtmlService.createHtmlOutputFromFile("index.html")
    .addMetaTag("viewport", "width=device-width, initial-scale=1")
    .setTitle("React Router Tutorial");
}

buildしてGoogle側へpush

ここまでに、次のような作業を実施してきました。

.
├── .clasp.json (rootDirをdistに修正)
└── apps-script
    ├── Code.js (doGetを実装)
    └── appsscript.json (webappを追加)

buildして、distディレクトリー以下にGoogleへpushするファイル群を作り、pushします。マニフェストファイルを修正しているため、更新してもよいか聞かれるので、yと入力します。

npm run build && clasp push

? Manifest file has been updated. Do you want to push and overwrite? Yes
└─ dist/appsscript.json
└─ dist/Code.js
└─ dist/index.html
Pushed 3 files.

Google側に正しくpushできたかどうかは、スクリプトエディターで確認できます。なお、スクリプトエディター側でソースコードを修正しないようご注意ください(ローカルには反映されません。clasp pullをする必要があります)。

clasp open

Google Apps Scriptのスクリプトエディター

4. ウェブアプリの確認と修正

Google側にpushしたウェブアプリが正しく動作するか、ウェブブラウザーで確認します。--webappオプションをつけてclasp openを実行します。どのデプロイメントを確認するか聞かれますが@HEADを選択してください。

clasp open --webapp
? Open which deployment?                               @HEAD - 
AKfycbzLwLPOUK5pChztlBpdGeQDpoSDcAlP-WsJm1els15I
Opening web application: AKfycbzLwLPOUK5pChztlBpdGeQDpoSDcAlP-WsJm1els15I

@HEADデプロイメントは、Google側にpushしたソースコードが即時に反映される開発用のデプロイです。ウェブブラウザーで開いたURLの末尾が/devになっています。このURLには、Apps Scriptの編集権限を持っている人しかアクセスできないことに注意してください。

さて、ウェブアプリを確認してみると、Viteのロゴが表示されていません。一方、Reactのロゴは正しく表示されています。

Google Apps Scriptで公開したReactアプリ(Viteのロゴが表示されない)

ソースコードを確認してみると、それぞれのロゴデータの置き場所が異なるようです。

.
├── public
│   └── vite.svg
└── src
    ├── assets
    │   └── react.svg
    ├── App.jsx
App.jsx
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "vite.svg";

今回は、正しく表示されているReactのロゴに合わせて、Viteのロゴを移動してみます。

mv public/vite.svg src/assets
App.jsx
import { useState } from "react";
import reactLogo from "./assets/react.svg";
- import viteLogo from "vite.svg";
+ import viteLogo from "./assets/vite.svg";

ここまで作業できたら、まずローカル環境で正しく動作しているか確認しましょう。

npm run dev

正しく動作していれば、buildとpushをして、@HEADデプロイを確認します。

npm run build && clasp push
clasp open --webapp
(@HEADを選びます)

スクリーンショット 2024-03-30 16.33.54.png

今度は正しく動作しているようです。

5. ウェブアプリをデプロイして他の人が使えるようにする

ここまでは開発用の@HEADデプロイメントで動作を確認してきました。このデプロイはApps Scriptの編集権限を持っている開発者しかアクセスできません。

ウェブアプリを自分以外にも使ってもらうためには、新しくデプロイする必要があります。具体的にはマニフェストファイルappsscript.jsonwebappaccessMYSELF以外(DOMAINANYONEANYONE_ANONYMOUS)を設定する場合です。

なお、ウェブアプリのURLは新しくデプロイをすると変更されます。URLは変更せずに、ウェブアプリの動作を変える場合には、deployment IDを指定した再デプロイを実行する必要があります。

とはいえ、最初の一度は新しくデプロイする必要があります。

clasp deploy

Created version 1.
- AKfycbwQgENC3rb2Upr6crhbCJPcfMRbP_Mk9tyw-9kgYSyNrxGrm18ZUJUTNfK7WBqR9g6DmA @1.

Created version 1.の次の行、@1 までの文字列が deployment IDです。再デプロイに必要となります。clasp deploymentsを実行すると、再表示できます。

clasp deployements

2 Deployments.
- AKfycbzLwLPOUK5pChztlBpdGeQDpoSDcAlP-WsJm1els15I @HEAD 
- AKfycbwQgENC3rb2Upr6crhbCJPcfMRbP_Mk9tyw-9kgYSyNrxGrm18ZUJUTNfK7WBqR9g6DmA @1 

自分以外の人も使えるウェブアプリのURLは、末尾が/execになっています。clasp open --webappで、新しくデプロイしたウェブアプリを選択し、ウェブブラウザーのURLを自分以外の人に動作の確認をお願いしてください。

ウェブアプリの修正が完了したら再デプロイする

ウェブアプリの修正をし、@HEADデプロイでの動作が完了したら、再デプロイが必要になります。再デプロイするまでは、他の人のウェブアプリに動作は反映されません。

他の人に「修正したって聞いたけど、前と動作が同じだよ」と連絡をもらったら、再デプロイし忘れていないかを確認しましょう。

再デプロイはdeployment IDを指定する必要があります。

clasp deploy --deploymentId AKfycbwQgENC3rb2Upr6crhbCJPcfMRbP_Mk9tyw-9kgYSyNrxGrm18ZUJUTNfK7WBqR9g6DmA

Created version 2.
- AKfycbwQgENC3rb2Upr6crhbCJPcfMRbP_Mk9tyw-9kgYSyNrxGrm18ZUJUTNfK7WBqR9g6DmA @2.

再デプロイすると、@の後のバージョン番号が増えていきます。

開発用・本番用のデプロイまとめ

開発用と本番用でデプロイが分かれているのは、慣れてしまえば便利ですが、最初は混乱しがちです。特徴を以下にまとめておきます。

開発用デプロイ 本番用デプロイ
URL 末尾が/dev 末尾が /exec
アクセスできるのは 自分だけ2 自分以外も3
修正後の動作確認 pushだけでOK 再デプロイが必要

なお再デプロイにはdeployment IDが必要です。再デプロイではなく、新しくデプロイするとURLが変更になるのでご注意ください。

参考にした記事

次の記事を大いに参考にさせていただきました。とてもわかりやすい記事をありがとうございます。

題材は同じなのですが、この記事とは細かい相違点があります。

  • ビルドした成果物をdistに格納し、gitの管理対象外とする
    • 成果物は他のソースコードからいつでも再生成できます
    • 成果物はサイズも大きくなりがちです
    • 上記の理由から、distはgitでは管理していません
  • 開発用デプロイを使った動作確認
    • pushするだけで(デプロイ不要で)動作が変わる開発用デプロイ@HEADの使い方を紹介しています
  1. TypeScriptで作ることもできます。

  2. 正しくは、Apps Scriptの編集権限を持っている人がアクセスできる

  3. 正しくは、デプロイの公開設定による(自分だけ / Googleアカウントを持っている人 / 全員)

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?