見出し画像

Google Apps Scriptライブラリの作り方

ライター

本記事では、Google Apps Scriptのライブラリの使い方と作り方、JSDocコメントやコード補完まで、ワンストップ(2部構成)で全部わかるように詳しく解説しています。

ライブラリの使い方についてはコチラ↓

💡 この記事で得られる知識
・ ライブラリの作り方と公開方法
・ JSDocコメントの書き方
・ スクリプトエディタのコード補完について

4. ライブラリの作り方

4-1. ライブラリを作る

ライブラリの作成手順を説明します。

1) 新しいスクリプトファイルを作成する

Googleドライブで新規に「Google Apps Script」ファイルを作成します。

画像11


2) コードを書く

画像12

3) 新しい版として保存する

メニュー > 「ファイル」 > 「版を管理」を選択します。

画像13

版(=バージョン)の説明を「Desribe what has changed...」に記載し、「Save new version」で新しい版として保存します。

画像14

4) 共有設定をする

全公開、全公開(リンクを知っているユーザーのみ)、組織内、組織内(リンクを知っているユーザーのみ)、特定のユーザーのみ、などの共有設定をします。

画像15


5) スクリプトIDを公開する

3-1.に記載した手順にてスクリプトIDを参照し、公開します。利用者はスクリプトIDさえ知っていれば良いので、ブログやQiita、GitHubなど、公開場所は好きな場所で構いません。

4-2. ライブラリ作成時の注意事項

ライブラリを作成する際に気を付ける点について説明します。ECMAScriptより実装可能なクラスの利用、スクリプトエディタでのコード補完について解説します。

4-2-1. クラスの利用

ライブラリ内にクラスを自作した場合、「識別子.クラス名」としてもライブラリのクラスを参照することはできません。

下記のような結果になります。

▶︎ ライブラリ側(識別子=Lib)

​▶︎ 利用側

​これを解消するためには、以下のような方法があります。

1) クラスをsuper global領域にセットする
2) クラスを取得するsuper globalな関数を作成する
3) クラスのインスタンスを生成し取得するsuper globalな関数を作成する

---
📝 globalについて

JavaScriptのランタイムではいくつかのオブジェクトを持っていますが、このオブジェクトはツリー構造になっています。

共通して出てくる「super global」という言葉ですが、ここで言う「super global」とはその最上位を指しています。

Google Apps Scriptではネストのない場所か、ネストのない場所に書いた「this」がsuper globalな階層に該当します。ただし、ネストのない場所に書いたletやconstはsuper globalのひとつ下の階層(local globalと呼称します)に位置します。

以下の「宣言」と「階層の確認」のコードでそれが確認できます。

▶︎ 宣言

▶︎ 階層の確認

​test()を実行すると、以下のようなログが出力されます。

1
2
undefined
undefined
5

1
2
3
4
5

letで宣言したc、constで宣言したdはthisの直下には存在しませんが、test()内からは参照できる場所に位置していることがわかります。

つまり、以下のことが言えます。

・a, b, e()はsuper globalに位置している
・a, b, c, d, e()はlocal globalに位置している

尚、「super global」や「local global」は、あくまでも本記事内での説明のために使用している用語です。正確な用語があるかもしれません。

---

話を戻して、次よりクラスを利用する3つの方法について実際のコードを交えて説明していきます。

1) クラスをsuper global領域にセットする
2) クラスを取得するsuper globalな関数を作成する
3) クラスのインスタンスを生成し取得するsuper globalな関数を作成する

1) クラスをsuper global領域にセットする
thisのプロパティに対してクラスを代入します。

▶︎ ライブラリ側(識別子=Lib)

​▶︎ 利用側

2) クラスを取得するsuper globalな関数を作成する
クラスを取得するfunctionを作成します。

▶︎ ライブラリ側(識別子=Lib)

​▶︎ 利用側①

​▶︎ 利用側②

3) クラスのインスタンスを生成し取得するsuper globalな関数を作成する
クラスのインスタンスを生成して返却するfunctionを作成します。

▶︎ ライブラリ側(識別子=Lib)

▶︎ 利用側

​4-3. JSDocとコード補完

4-3-1. JSDoc

JSDocの説明について、Wikipedia記事からの引用を拝借します。

JSDocは、JavaScriptのソースコードにアノテーションを追加するために使われるマークアップ言語である。JSDocをコメントの中に含めることで、プログラマーは自分が書いたコードのAPIを記述するドキュメントを追加することができる。JSDocをさまざまなツールで処理することで、HTMLやRich Text Formatなどの形式のアクセス可能なドキュメンテーションを自動生成することができる。JSDocは、Apache License 2.0の元にライセンスされている自由ソフトウェアである。

引用元:
https://ja.wikipedia.org/wiki/JSDoc

Google Apps Scriptでサポートされているアノテーションは以下です。

表3. Google Apps Scriptでサポートされているアノテーション

画像6

Libraries | Apps Script | Google Developers より引用

Only the @param and @return annotations are currently supported.

JSDocですが、3-1.で触れたAPIドキュメントを生成するための元ネタになります。メンテナンスする際や、GitHubなどでライブラリのソースコードを公開する際にも、使い方のヒントになりますので記述しておくと良いです。

▶︎ JSDocドキュメンテーションの例

4-3-2. コード補完

Google Apps Scirptのスクリプトエディタにはコード補完の機能があります。

ライブラリについてもコード補完することが可能ですが、残念ながら完全ではありません。ライブラリ内にclassを定義して利用してもらう場合には注意が必要です。

注意点については検証を交えながら解説していきますが、先に結論を記載します。

・ライブラリ内のglobalなfunctionはコード補完が効く
・classについては補完に問題がある

従って、以下のいずれかの方針でライブラリの作成を検討する。

・ コード補完の完全性までを考慮してライブラリを作成するのであれば、classは使わずにglobalなfunctionのみで構成する
・ ライブラリのAPIを別途ドキュメントで補うという方針であれば、classを使っても問題はない
参考)TypeScriptベースですが、こちらの記事でも検証されていますので、リンクを掲載させていただきます
Google Apps Script でクラス型のコードを書いたさいのスクリプトエディタでの補完への対処方法 (Bad Hack) - ChangeLog - noissefnoc

補完検証 step1
前述の2)のコードの補完は以下のようになります。

▶︎ ライブラリ側(識別子=Lib)

▷ 検証結果

画像7

foo()は認識されましたが、戻り値の型がvoidになっています。

補完検証 step2
JSDocを追加してみます。

▶︎ ライブラリ側(識別子=Lib)

▷ 検証結果

画像8

戻り値の型がドキュメント通りになりました。

補完検証 step3
次に、Fooクラスのメソッド、プロパティが補完されるかを検証します。

▶︎ ライブラリ側(識別子=Lib)

​▷ 検証結果

画像9


残念ながら、何も補完されませんでした。

補完検証 step4
さて、ではどのようにすれば補完されるでしょうか。以下の方法で補完されるようになります。検証してみましょう。

1) Fooクラスのインスタンスを生成するfunctionを作成、さらにJSDocの戻り値の型は識別子にする

2) Fooクラスのメソッドをglobalなfunctionとして宣言、さらにJSDocもメソッドと同じ内容にする

▷ 検証結果

画像10

hogeが補完されるようになりました。

補完の副作用
しかしながら、この方法には副作用があります。先に完全ではないと述べた理由がこちらです。

❗️ Fooインスタンスからの補完にcreateメソッドが表示されてしまう

画像11

❗️ Lib識別子からの補完にhogeメソッドが表示されてしまう

画像12

余計なものが表示されてしまう上に、これらは全て実行可能であるため、予期せぬトラブルの原因にもなります。

さらに言うと、重複したようなコードとコメントを書かなければならないため、ライブラリの改修コストも上がります。

補完の補足
ちなみに、ES5仕様でオブジェクト指向実装をした場合ですが、classと同じようなJSDocを書いても補完されません。

▶︎ ES5での定義

​▷ 検証結果

画像13

画像14

hogeES5は補完されません。

結論
これまでの検証より、以下のことがわかります。

・ライブラリ内のglobalなfunctionはコード補完が効く
・classについては補完に問題がある

従って、コード補完の完全性までを考慮してライブラリを作成するのであれば、classは使わずにglobalなfunctionのみで構成する、といった作り方になるでしょう。

ライブラリのAPIを別途ドキュメントで補うという方針であれば、classを使っても問題はないでしょう。

ライブラリを作成する際には上記の点について注意が必要です。

5. おわりに

作成したライブラリはclaspでダウンロードしてGit上で管理しておくと良いです。

claspについては、以下の記事が参考になりますのでリンクを掲載させていただきます。Bitbucketで管理する方法が書かれています。
claspを使い、Google Apps Scriptプロジェクトをgitでバージョン管理する


この記事が気に入ったら、サポートをしてみませんか?
気軽にクリエイターの支援と、記事のオススメができます!
スキありがとうございます!
4
株式会社シクミヤが運営するVisionaryBaseの編集部です。経営管理・業務自動化・その他経営など実務で活用できる内容を発信して行きます。