そんな今日この頃の技術ネタ

本家側に書くほどでもない小ネタ用

claspでのGAS開発環境にLintを追加する

claspを使ってGASにデプロイする話のつづき。

blue1st-tech.hateblo.jp

前の記事でpush時に自動でTypeScriptをトランスコンパイルしてくれるということを書いたのだが、実際にゴリゴリ長いコードを記述するとなるとコード整形などで保守性を良くしておきたくなるもの。 というわけで今回はtslintやpretterもう少し環境を整える話。


作業の前にアップデート

前回から結構間があったので念の為アップデート。v1.5.3→v2.0.0

$ sudo npm install -g -u @google/clasp
/usr/local/bin/clasp -> /usr/local/lib/node_modules/@google/clasp/src/index.js
+ @google/clasp@2.0.0

$ clasp
Usage: clasp <command> [options]

clasp - The Apps Script CLI

Options:
  -v, --version
  -h, --help                                  output usage information

Commands:
  login [options]                             Log in to script.google.com
  logout                                      Log out
  create [options]                            Create a script
  clone [options] [scriptId] [versionNumber]  Clone a project
  pull [options]                              Fetch a remote project
  push [options]                              Update the remote project
  status [options]                            Lists files that will be pushed by clasp
  open [options] [scriptId]                   Open a script
  deployments                                 List deployment ids of a script
  deploy [options]                            Deploy a project
  undeploy [deploymentId]                     Undeploy a deployment of a project
  version [description]                       Creates an immutable version of the script
  versions                                    List versions of a script
  list                                        List App Scripts projects
  logs [options]                              Shows the StackDriver logs
  run [options] [functionName]                Run a function in your Apps Scripts project
  apis [options]                              List, enable, or disable APIs
    list
    enable <api>
    disable <api>
  help                                        Display help
  setting|settings [settingKey] [newValue]    Update <settingKey> in .clasp.json
  *                                           Any other command is not supported

パッと見で気づくとこだとapis系が増強されてるのとsettings系が追加されてる感じ。

ということで以下作業を進めていく。


ソースのディレクトリを変更

これから色々とnodeモジュールを導入していくわけだが、それらスクリプト本体でないものまでpush時にアップロードされてしまうのはよろしくない。.claspignoreに記述するという手もあるが、シンプルにディレクトリを掘ってしまうのが無難だろう。今回は仮にプロジェクトディレクトリ下にsrcディレクトリを設ける。

cloneしてくる前だったりそもそも作り始めるタイミングなら--rootDirオプションで指定すれば良い。

$ clasp clone XXXXXXXXXXXXXXXX --rootDir ./src


一方、すでにローカルにpullしてきている状況の場合はsettingコマンドを用いてrootDirを設定する。

$ clasp setting rootDir src
Updated "rootDir": "" → "src"

もっとも、これだけだと設定を変更しただけで、すでにあるファイルまでは移動してくれない。既存のファイルを手動で移動させるor再度pullしてこよう。

$ mkdir src
$ mv appsscript.json src/
$ mv *.js src/
$ mv *.ts src/


TSLintの導入

そんなこんなでやっと本題。まずはコードの望ましくない記述を指摘してくれるTSLintを導入する。

$ npm init -y
$ npm install typescript tslint -D 

先にinitしておく。

$ node_modules/tslint/bin/tslint --init

package.jsonにlintコマンドを追加。

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "lint": "tslint --fix 'src/**/*.{ts,js}'"
  },

生成されたtslint.jsonを開き、実用上console.log等が塞がれてしまうと辛いのでルールを追記しておく。

     "rules": {
       "no-console": [false]
     },

これで以下のようなコマンドでlintを実施できる。

$ npm run lint


Prettierの導入

どうせだったらチェックだけじゃなくて良い感じに整形してくれると良いよねーってことでPrettierも導入。

$ npm install prettier tslint-config-prettier tslint-plugin-prettier -D

先程のtslint.jsonにprettierを呼び出せるように記述を加えていく。

{
    "defaultSeverity": "error",
    "extends": [
        "tslint:recommended",
        "tslint-config-prettier"
    ],
    "jsRules": {},
    "rules": {
        "no-console": [false],
        "prettier": true
    },
    "rulesDirectory": ["tslint-plugin-prettier"]
}


Lintの実行

そんなわけで実際に使ってみる。以下のようにわざと汚いコードを書いてみる。

$ cat src/Code.ts
function   func1(){
const    dict={a: 1,b: 2,c: 3,d: 4};
}

コード的には動くけど、インデントやらスペースやらめちゃくちゃ。で、早速実行。

$ npm run lint

> tslint --fix 'src/**/*.{ts,js}'

Fixed 2 error(s) in src/Code.ts

ファイルを開くと、見事に整形されている!

$ cat src/Code.ts
function func1() {
  const dict = { a: 1, b: 2, c: 3, d: 4 };
}

実用上、lintを実行した上でデプロイしたりバージョン管理するのが良いだろう。


Makefileを作っておくと便利

最近のマイブームなのがMakefileによる作業の簡略化。今回もこれを使ってみる。

blue1st-tech.hateblo.jp

以下のようなMakefileを設けておいて、make一発でlint実行とpushまで行えるようにすると便利だろう。

default: push

lint:
    npm run lint

push: lint
    clasp push

deploy: push
    clasp deploy

open:
    clasp open

logs:
    clasp logs --open

.PHONY: lint push deploy open logs



以上でコードをきれいな形に保つ開発環境を整えることができた。やはり生でES5を書くのと比較するとTypeScriptの文法は単純に書いていてストレスが少ないし、バッチ的なものを運用する上では型があると格段に保守性が良くなる。

JavaScriptプログラマのための 実践的TypeScript入門 (アスキー書籍)

JavaScriptプログラマのための 実践的TypeScript入門 (アスキー書籍)


ただ、ちょっと辛いのがGASのJavascriptランタイムが古すぎてTypeScriptからトランスコンパイルされた先のコードでも動かない記述が結構あること。使用頻度が高いところだとArray.prototype.find()とかObject.assign()あたりが使えないのがしんどい。

f:id:blue1st:20190120192546p:plain
GASエラー


まあこれもランタイムが新たなものになることがアナウンスされてるので、おいおいより良くなっていくだろう。

mashe.hawksey.info

Modern Javascript – A common request is updating the JavaScript syntax to be able to use more modern features and libraries. At Next ‘18 it was announced that this would be supported by moving to ECMAScript 2017 scripting-language specification.