Visual StudioでGoogle Apps Script開発

VS(Visual Studio)を用いたGAS(Google Apps Script)開発環境の備忘録

#サンプル
・GitHub : https://github.com/MAX-eipi/VsGasSampleProject.git

リポジトリをクローンして、npmの依存モジュールをインストールしてください。

```
git clone --depth 1 https://github.com/MAX-eipi/VsGasSampleProject.git
cd ./VsGasSampleProject/GasTestProject
npm install
```

また、.clasp.jsonの[scriptId]に自身のGASプロジェクトのIDを指定してください。

# 参考サイト(一度目を通してもらえると助かります)
- [Google Apps Script をローカル環境で快適に開発するためのテンプレートを作りました](https://qiita.com/howdy39/items/0e799a9bfc1d3bccf6e5)
- [Visual StudioでC#とTypeScriptのUnitTestを一覧してみる。](http://dblog.athome.co.jp/entry/2018/04/04/120000)
- [Google Apps Scriptの新しい3つの機能 その③ CLI Tool Clasp](https://qiita.com/soundTricker/items/354a993e354016945e44)

開発環境がVSであることに拘らない場合は[一番上の記事](https://qiita.com/howdy39/items/0e799a9bfc1d3bccf6e5)の方法をおススメします。

# 前提
- VSが導入されていること(当記事で取り扱っているのはVS Community 2017)<br>
導入方法 : [Visual Studio 2017 のインストール
](https://docs.microsoft.com/ja-jp/visualstudio/install/install-visual-studio) (注1)
- Googleのアカウントを所持していること<br>
アカウントの作成方法 : [Google アカウントの作成](https://support.google.com/accounts/answer/27441?hl=ja)

<details><summary>注1: ワークロードの指定</summary>
VS 2017 からワークロードというものを指定してインストールする方式になりました。
これによって、自分の開発用途にあったコンポーネントだけをインストールすることが可能になりました。
当記事に該当するワークロードは「Node.js 開発」ですので、最低限これを指定してください。
![alt](https://qiita-image-store.s3.amazonaws.com/0/117833/92304662-e106-4f3a-46f9-7a2c2b93c508.png)
</details>

# 構築手順
## 1. VSのプロジェクトを作成する
[<b>空の Node.js コンソール アプリケーション</b>]を作成します。

## 2. パッケージや拡張機能をインストールする
### 2-1. 開発に必要なパッケージをインストールする

<details><summary>インストールするパッケージ</summary><div>

- @google/clasp ← [他のnpm引数]に[-g]を指定
- @types/google-apps-script
- @types/jasmine
- cpx
- gas-webpack-plugin
- requirejs
- rimraf
- ts-loader
- typescript
- webpack
- webpack-cli
</div></details>

[補足]
既に「@types/node」がインストールされている場合はアンインストールしてください。

### 2-2. 拡張機能をインストールする
テスト環境を構築するために拡張機能をインストールする必要があります。
「<b>Chutzpah Test Adapter for the Test Explorer</b>」をインストールしてください。

## 3. 各種設定ファイルの作成

<details><summary>tsconfig.json - TypeScript構成ファイル</summary><div>

```json:tsconfig.json
{
  "compilerOptions": {
    "module": "amd",
    "target": "es5",
    "lib": ["es5"],
    "sourceMap": true,
    "outDir": "out"
  },
  "exclude": [
    "node_modules"
  ]
}
```
</div></details>

<details><summary>webpack.config.js - バンドル化設定ファイル</summary><div>

```js:webpack.config.js

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

module.exports = {
    mode: 'development',
    entry: './src/app.ts',
    devtool: false,
    output: {
        filename: 'bundle.js',
        path: path.join(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                use: 'ts-loader'
            }
        ]
    },
    resolve: {
        extensions: [
            '.ts'
        ]
    },
    plugins: [
        new GasPlugin()
    ]
};
```
</div></details>

<details><summary>chutzpah.json - テスト環境設定ファイル</summary><div>

```json:chutzpah.json
{
  "Framework": "jasmine",
  "TestHarnessReferenceMode": "AMD",
  "TestHarnessLocationMode": "SettingsFileAdjacent",
  "EnableTestFileBatching": true,
  "AMDBaseUrl": "out",
  "AMDAppDirectory": "./",
  "References": [
    {
      "Path": "node_modules/requirejs/require.js",
      "IsTestFrameworkFile": true
    }
  ],
  "Tests": [
    { "Path": "test" }
  ],
  "Compile": {
    "Extensions": [ ".ts" ],
    "ExtensionsWithNoOutput": [ ".d.ts" ],
    "OutDirectory": "out",
    "Mode": "External"
  }
}
```
</div></details>


## 4.ソースファイルの配置
ソースコードは/srcに、テストコードは/testに配置してください。

## 5.GASプロジェクトと紐づける
ターミナルでコマンドを実行します。(実行する場所はプロジェクトのルートディレクトリ)

```
clasp login
clasp create <project_name>
```
コマンドを実行すると、ルートディレクトリにappsscript.jsonが生成されますが、これを/srcに移動します。

また、デプロイするコードを/dist内のものにしたいので、設定ファイルを編集します。

```json:.clasp.json
{
  "scriptId": <project_id>,
+ "rootDir":  "dist"
}
```

後は任意でデプロイ用のコマンドをpackage.jsonに追記します。

```
"scripts": {
  "build": "rimraf dist && webpack && cpx src/appsscript.json dist",
  "deploy": "npm run build && clasp push"
}
```

これを追加しておくと `npm run deploy` を実行することでビルド(=バンドル化と必要なファイルのコピー)とGASプロジェクトへのpushを実行してくれます。


# 余談
需要がありそうならもう少し詳細詰めます。(本来の目的は自分用のメモなので \_(:3」∠)_)


もしかしたらVSで他に導入している拡張機能やらテンプレートがあるかもしれない、、あるかもしれなくない？
「これないんだけど？」っていうのがあれば教えてください。

また、当記事におけるプロジェクトの構成は、自分が実現したいことを満たすのに十分ではありますがミニマムとは限りません。
「この設定しなくても大丈夫だよ」「jasmineじゃなくてQUnit使いたいときはこうだね」みたいなのがあれば、それもまた教えていただければ幸いです。