GAS ( Google App Script )GCP (Google Could Platform)JavaScriptNode.jsTypeScriptwebpack

clasp + webpackでGAS(Google App Script)のコードをTypeScriptで書く

claspでGAS(Google App Script)のコードを簡単にデプロイできます。Serverless FrameworkのGAS版っぽい感じ。 ただ、npmのライブラリを使う時に工夫が必要だったのでそれをまとめ […]

広告ここから
広告ここまで

claspでGAS(Google App Script)のコードを簡単にデプロイできます。Serverless FrameworkのGAS版っぽい感じ。

ただ、npmのライブラリを使う時に工夫が必要だったのでそれをまとめました。

プロジェクトの作成

$ mkdir example && cd example
$ clasp create example-app --rootDir ./dist

続けて必要なファイルを空で作っておきます。以下のようなディレクトリ構成になればOKです。

$ mkdir src
$ touch src/Code.ts src/index.ts webpack.config.js .babelrc

$ tree -L 2 -I node_modules
.
├── dist
│   └── appsscript.json
├── package.json
├── src
│   ├── Code.ts
│   └── index.ts
├── .babelrc
├── .clasp.json
├── tsconfig.json
└── webpack.config.js

webpack / TypeScript / Babel

clasp自身もTypeScriptのコンパイルは実行してくれます。ただ、トランスパイルするだけでimport / requireしたnpmライブラリのコードがデプロイされません。

ということで、自前でビルドするようにします。

# webpack
$ yarn add -D webpack webpack-cli gas-webpack-plugin es3ify-webpack-plugin

# babel
$ yarn add -D @babel/core @babel/preset-env @babel/preset-typescript babel-loader

# typescript
$ yarn add -D typescript @types/google-apps-script

webpack.config.js

webpackの設定は参考記事の設定そのままにしています。

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

module.exports = {
  mode: 'development',
  devtool: 'inline-source-map',
  context: __dirname,
  entry: {
    main: path.resolve(__dirname, 'src', 'index.ts')
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.js'
  },
  resolve: {
    extensions: ['.ts', '.js']
  },
  module: {
    rules: [
      {
        test: /\.[tj]s$/,
        loader: 'babel-loader'
      }
    ]
  },
  plugins: [new GasPlugin(), new Es3ifyPlugin()]
};

.babelrc

こちらも設定は参考記事の設定そのままにしています。

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "browsers": ["ie 8"]
        }
      }
    ],
    "@babel/preset-typescript"
  ]
}

tsconfig.json

こちらも設定は参考記事の設定そのままにしています。

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "lib": [
      "es2015",
      "es2016",
      "es2017",
      "es2018"
    ],
    "allowJs": true,
    "declaration": false,
    "outDir": "./dist",
    "rootDir": "./src",
    "downlevelIteration": true,

    "strict": true,
    "noImplicitAny": true,

    "noUnusedLocals": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,

    "moduleResolution": "node",
    "esModuleInterop": true,

    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "include": ["./src/**/*"]
}

.gitignore

Git管理する場合、distディレクトリのappscript.jsonは管理下におく必要があります。ですので、以下のようにビルドされたJSファイルだけ除外するようにしておきます。

node_modules/
dist/*.js

package.json

ビルド->デプロイで2コマンド打つ必要があります。ですのでnpm-scriptを定義しておきましょう。

{
  "scripts": {
    "build": "webpack",
    "deploy": "npm run build && clasp push",
    "watch": "watch 'npm run deploy' ./src"
  },

src/Code.ts

ここに実行するコードを記述します。

export function getUpdatedCalander(e: GoogleAppsScript.Events.CalendarEventUpdated): void {
  try {
    console.log('Event')
    console.log(e)
    const calander = CalendarApp.getCalendarById(e.calendarId)

    const today = new Date()
    const next = new Date()
    next.setMonth(next.getMonth() + 2)

    const events = calander.getEvents( today, next )

    events.forEach(event => {
      console.log(event.getTitle())
    })
  } catch (err) {
    console.log('Error')
    console.log(err)
  }
}

イベントの引数はGoogleAppsScript.Events内に定義されていますので、使いたいトリガーに応じて設定すると良いでしょう。

src/index.ts

最後にglobalオブジェクトに関数を刺してやります。

import {getUpdatedCalander} from './Code'

declare const global: {
  [x: string]: any ;
}

global.getUpdatedCalander = function(e: any) {
  return getUpdatedCalander(e)
}

デプロイ

あとはnpm run deployでGASにデプロイすればOKです。

index.gsのみがデプロイされていますので、こいつを実行してやりましょう。

参考

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts