kintone プラグイン無効化の挙動を確認する

結論だけ知りたいと言う人は [まとめ](#まとめ) をご覧ください。

検証に利用したソース全体は [GitHub](https://github.com/iShinkai/kintone-plugin-disabled) にアップしています。

# はじめに

kintone の [2021 年 2 月のアップデート](https://kintone.cybozu.co.jp/update/main/2021-02.html) で、アプリに適用済みのプラグインをプラグイン単位で無効にできる機能が追加されました。
![プラグイン無効化機能](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/2b8f495f-e1fa-97ae-e4e6-2dbb541ac291.png)
弊社が提供するプラグインでもそうですが、kintone の動作仕様上 1 つのアプリに複数のプラグイン・ JS カスタマイズを同時に適用していると動作がかち合ったり意図通りの動きをしなかったりすることがしばしばあります。
イベント処理でレコードをいじって返却するような類のもの、カスタマイズビューや DOM に作用するものなんかではありがちですね。
そう言う時、「他のプラグインを削除してちゃんと動くか確認していただけますか」なんて言うご案内をしたりもするのですが、アプリからプラグインを削除するとプラグインの設定も消えてしまうため、設定画面がガッツリ作り込まれているような大型のプラグインだと再適用・再設定が結構な負担になり得ます。

今回のアップデートで、アプリにプラグインを適用したまま（＝プラグインの設定を残したまま）プラグインを無効化することができるようになりました。
上述のようなトラブルの事例でも「他のプラグインを削除して」ではなく「他のプラグインを無効化して」とご案内できるようになりますので、アプリ設定者側としても心理的負担は和らぐことになるでしょう。

その一方で、

> ※プラグインを無効にした状態でも、プラグインの設定の確認や変更を行うことが可能です。

とある通り、プラグインが完全に「なかったこと」にされるわけではないと言う挙動になるようです。

であれば、通常のアプリ画面ではどのような振る舞いになるのか？

- プラグインが内包する JS 自体がロードされない？
- ロードはされるが、イベントが発火しない？
- CSS についてはどうなる？

と言った挙動はしっかり確認しておいた方が良さそうです。

前置きが長くなりましたが、この記事ではこの辺りを検証していきたいと思います。

# 挙動確認用プラグイン

今回のアップデートの挙動を確認するプラグインは以下のようなものです。

**【1】** プラグインが読み込まれた際、画面右上に 🐹 を表示
**【2】** レコード追加時・編集時にスペースフィールドに「🐱 このテキストはプラグインが挿入しました」 と表示
**【3】** プラグインが読み込まれた際、画面上部のアプリ名の背景をストライプに変更

**【1】** **【2】** は JavaScript によるもの、**【3】** は CSS による挙動です。

実際の画面上にはこんな感じに反映されます。
![デスクトップ・レコード追加画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/8930e682-3609-64b1-1815-c5c0883862fa.png)

モバイル画面ではこう。
![モバイル・レコード追加画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/8efe6e2c-b108-f446-1609-318ab940dd8d.png)

デベロッパーツールの **Network** パネルでリソースのロード状況を確かめてみましょう。
![デスクトップ・レコード追加画面-Network](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/e5a88b9b-e843-de54-3c60-d8758ce71f03.png)
JS と CSS が 1 つずつ読み込まれているのが見てとれますね。

具体的なソースコードは以下の通りです。

```javascript:src/js/desktop.js
;(() => {
  /**
   * 【1】 プラグインロード時処理
   */
  const elem = document.createElement('div')
  elem.innerText = '🐹'
  elem.style.position = 'absolute'
  elem.style.right = '40px'
  elem.style.top = '220px'
  elem.style.fontSize = '36px'
  document.getElementsByTagName('body')[0].appendChild(elem)

  /**
   * 【2】 レコード追加時・編集時イベント
   */
  kintone.events.on(
    ['app.record.create.show', 'app.record.edit.show'],
    (event) => {
      const space = kintone.app.record.getSpaceElement('space')
      space.innerHTML = '🐱このテキストはプラグインが挿入しました'
      space.style.fontSize = '24px'
    }
})()
```

```css:src/css/desktop.css
/* (省略) */

/**
 * 【3】 画面上部のアプリ名の背景をストライプに変更
 */
.gaia-argoui-app-titlebar.gaia-argoui-app-titlebar-has-icon {
  background-image: repeating-linear-gradient(
    135deg,
    #bff5ff,
    #bff5ff 10px,
    #bbe7fe 10px,
    #bbe7fe 20px
  );
}
```

モバイル版のソースコードはほとんど同じなので省略します。

念のためプラグイン設定画面でも同じようなギミックを仕込んでおきます。

**【4】** プラグイン設定画面が読み込まれた際、設定ブロックに「🐰 このテキストはプラグインが挿入しました」と表示
**【5】** プラグイン設定画面が読み込まれた際、設定ブロックの背景の背景をストライプに変更

**【4】** は JavaScript によるもの、**【5】** は CSS による挙動です。
![プラグイン設定画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/61260120-b19c-7e15-927f-51fd0fda1816.png)

```javascript:src/js/config.js
;(() => {
  /**
   * 【4】 プラグイン設定画面ロード時処理
   */
  const textfield = document.querySelector(
    '.settings .kintoneplugin-row .message'
  )
  textfield.innerHTML = '🐰このテキストはプラグインが挿入しました'
  textfield.style.fontSize = '24px'
})()
```

```css:src/css/config.css
/* (省略) */

/**
 * 【5】 設定ブロックの背景をストライプに変更
 */
.onecolumn-gaia .contents-gaia .main-gaia {
  background-image: repeating-linear-gradient(
    135deg,
    #bff5ff,
    #bff5ff 10px,
    #bbe7fe 10px,
    #bbe7fe 20px
  );
}
```

こちらも **Network** パネルの内容を確認。
JS と CSS のほかアイコンの PNG 画像が読み込まれているのが判ります。
![プラグイン設定画面-Network](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/18e44c5e-da75-ff89-9966-9766a7a10f54.png)

# 仮説

プラグインの本来の動作を説明したところで、では次に **プラグインを無効化したらどうなるか** を考えてみたいと思います。

改めて冒頭に述べた仮説を再掲します。

- プラグインが内包する JS 自体がロードされない？
- ロードはされるが、イベントが発火しない？
- CSS についてはどうなる？

## 【仮説 A】 プラグインが内包する JS 自体がロードされない

デスクトップ画面・モバイル画面でプラグインに含まれる JS 自体が読み込まれないと言う仮説です。
もしそうだとすれば、上述の **【1】** **【2】** ともに動かないと言う事になります。
なので画面上には 🐹 も 🐱 も現れないとなりますね。

## 【仮説 B】 JS のロードはされるが、イベントが発火しない

プラグインの JS ファイル自体は読み込まれるが、 `kintone.events.on()` によるイベント処理が動作しないと言う仕様であると言う仮説です。
この仮説が真であれば、イベント処理の外側に記述している **【1】** だけが動作すると言う事になります。
つまり画面上には右上の 🐹 だけが出現する、と言う挙動になると想定されます。

## 【仮説 C】 プラグインが内包する CSS もロードされない

プラグインの CSS が読み込まれるかどうかは **【3】** のヘッダ部のストライプの有無で判断できます。
もし **【仮説 A】** が正しいとすれば、同時にこの **【仮説 C】** も成り立つ（ストライプが出ない）のではないかと想像されます。JS の読み込みはブロックされるのに CSS は読み込まれるって言うのは実装として不合理ですからね。
逆に、 **【仮説 A】** が偽で **【仮説 B】** が真だったとすれば、 **【仮説 C】** もまた偽 ＝ CSS のストライプも表示されるような気がします。

# 検証

それではいよいよ検証です。
アプリのプラグイン設定画面で **無効にする** をクリックしてプラグインを無効化します。
![プラグイン無効化](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/9a837140-b330-541d-db8a-c561eccb39e9.png)

**※※※ 重要 ※※※**
このあと、**アプリの設定** 画面に戻って **アプリを更新** をクリックしないと有効化/無効化設定は反映されません。
一連の設定の流れではそのような案内はされませんし、この記事執筆時点では[ヘルプ](https://jp.cybozu.help/k/ja/user/app_settings/plugine_disable.html)も未整備のようなので気付かない人もいるかも知れませんね。

さて、それではこの状態で改めてレコード追加画面を確認してみます。
![デスクトップ・レコード追加画面（プラグイン無効化）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/8131a2ff-7892-49b3-6e7b-8e0ffffcf948.png)
![モバイル・レコード追加画面（プラグイン無効化）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/429bcf51-7f44-5800-2a22-b589982080a2.png)

この通り、右上の 🐹 もメッセージもストライプも出ていません。
**Network** パネルで確認してみても、 JS/CSS のロードそのものが行われていないようです。
![デスクトップ・レコード追加画面（プラグイン無効化）-Network](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/efd1642c-7a70-9a21-3be0-31ce691ccc94.png)
このことから、上の仮説で言えば **【仮説 A】** **【仮説 C】** が正しかったと言う結果になりました。

その一方で、プラグイン設定画面については、プラグインの有効無効の状態にかかわらず、正しく JS/CSS ともにロードされる挙動になっています。
![プラグイン設定画面（プラグイン無効化）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/99005e74-8fbf-ea14-c1c2-0631302ada93.png)
![プラグイン設定画面（プラグイン無効化）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162138/b4076638-c19b-4143-45fa-2b85529179f5.png)
> ※プラグインを無効にした状態でも、プラグインの設定の確認や変更を行うことが可能です。

との記述通りの挙動ですね。

# まとめ

検証結果のまとめです。

**アプリの設定画面** の **プラグイン** 設定画面でプラグインを **無効** にした場合の挙動は、以下のようになります。

- **デスクトップ画面・モバイル画面** では **プラグインが内包する JS/CSS ともにロードされない**
- **アプリの設定画面** の個々の **プラグイン設定画面** では有効/無効の設定にかかわらず **プラグインが内包する JS/CSS がロードされる**

# 終わりに

と言うわけで、2021 年 2 月 14 日に kintone に実装された **各プラグインの動作を一時停止できる** と言うアップデートの動作を検証してみた本記事。
冒頭にも言いましたが、複数のプラグインやカスタマイズを適用した際に処理がかち合って適切な動作を阻害する事は現場ではままあり、その原因の調査・問題の切り分けに一定の効果が見込めるのは間違いありません。
そう言う意味では、我々ベンダー側だけではなくエンドユーザーにとっても非常に有用な機能追加であると言えるでしょう。

となると、今度は **JS カスタマイズや CSS もファイル単位で個別に有効/無効を切り替えられる機能** なんかも欲しくなるんですがね！
いかがですかねサイボウズさん！！