サンプルプラグインで新しい開発方式を試す

caution
警告

このページで説明している新方式は開発検討中の実験的な機能です。随時、機能の追加を予定しています。また今後、大きな仕様変更や機能自体を削除する可能性もあります。

アップデートオプション内の「開発中の新機能」から動作をお試しいただけます。
設定方法は、 新機能の有効/無効の切り替え手順 (External link) を参照してください。

プラグインの新しい開発方式に関するフィードバックを、ユースケースとともに、 kintoneの改善に協力する (External link) フォームへぜひご登録ください。

サンプルプラグインを使って新しい開発方式を試す

サンプルプラグインを使って新しい開発方式をすぐに試す手順は次のとおりです。

  1. 開発中の新機能を有効化
  2. サンプルプラグインのzipファイルをダウンロード
  3. kintone環境へプラグインをインストール
  4. 対象アプリへプラグインを適用
  5. 対象アプリ内で新しい開発方式を試す

開発中の新機能を有効化

「kintoneシステム管理」から「アップデートオプション」に遷移します。開発中の新機能(APIラボ)の中から、「プラグインの新しい開発方式の試用を有効にする」を有効化することで、新しい開発方式のプラグインをkintone環境で試せます。

サンプルプラグインのzipファイルをダウンロード

次のリンクからサンプルプラグインのzipファイルをダウンロードします。
experimental_new_plugin_sample_v0.1.0.zip (External link)

kintone環境へプラグインをインストール

新しい開発方式のプラグインをインストールするために、kintoneシステム管理から「新方式のプラグイン」のリンクをクリックします。

画面左上にある「プラグインを読み込む」ボタンをクリックします。

「プラグインを読み込むボタン」をクリックすると「プラグインの読み込み」ダイアログが表示されるので、「参照」ボタンからダウンロードしたプラグインのzipファイルを選択肢、「読み込む」ボタンを押します。

プラグインが読み込まれると、manifest.jsonで明示的に宣言されている操作や通信先がダイアログに表示されます。
サンプルプラグインのmanifest.json (External link)

システム管理者はプラグインを追加する前に、あらかじめプラグインが利用する操作や通信を確認できるので、プラグインの安全性を確認したうえで読み込むことができます。

「読み込む」ボタンをクリックすると、一覧画面に新しく「プラグインの新しい開発方式の動作確認用サンプルプラグイン」が追加されます。

対象アプリへプラグインを適用

アプリへのプラグインの追加は従来の方法と同様です。
サンプルプラグインを適用したいアプリの設定画面に遷移し、「設定」タブから「プラグイン」をクリックします。

「設定」タブから「プラグイン」をクリックすると、アプリのプラグインの設定ができる画面に遷移するので、画面左上にある「追加する」ボタンをクリックします。

「追加する」ボタンをクリックすると、プラグインの追加画面に遷移するので、適用したいサンプルプラグインにチェックを入れ、「追加」ボタンをクリックします。

プラグインを追加後に、アプリの設定画面に戻り、右上の「アプリを更新」ボタンをクリックすることで、アプリにサンプルプラグインが適用されます。

対象アプリ内で新しい開発方式を試す

アプリを更新後、対象アプリのレコード一覧画面に遷移すると、サンプルプラグインが適用され、上部にエディタが表示されます。

information

新しい開発方式のプラグインを適用したアプリでは、従来のプラグインは動作しません。また、新しい開発方式のプラグインをアプリに適用すると、 フロントエンド基盤の刷新 (External link) の取組の一環として、開発中の新しいレコード一覧画面に切り替わります。

サンプルプラグインについて

このサンプルプラグインをアプリに適用するとレコード一覧画面の上部にエディタが表示されます。このエディタにJavaScriptのコードを入力し、「Run」ボタンをクリックすることで、入力したコードがプラグイン内で実行されます。

エディタ内に入力したコードはプラグインの実行環境上で実行されます。このエディタを使うことで、毎回プラグインをインストールし直さなくても、どのように動作するかを確認できます。

新しい開発方式の特徴を把握するためにサンプルプラグインを使って、いくつかのコードをエディタへ入力し、実行してみましょう。

許可された操作や通信のみを実行する

プラグインの新しい開発方式ではプラグイン開発時に、あらかじめ利用するJavaScript APIやREST APIをmanifest.jsonで宣言します。プラグイン内では、manifest.jsonで宣言したAPI(操作や通信)のみ実行できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "manifest_version": 2,
  "version": "0.2.0",
  // manifest.jsonで関連する部分のみ記載しています
  "allowed_hosts": ["https://example.com/"],
  "permissions": {
    "js_api": ["kintone.app.getId", "kintone.api", "kintone.app.setFieldStyle"],
    "rest_api": ["/k/v1/records.json:get"]
  }
}

今回のサンプルプラグインでは次のJavaScript APIやREST APIをmanifest.jsonで宣言しています。

  • kintone JavaScript API
    • kintone.app.getId
    • kintone.api
    • kintone.app.setFieldStyle
  • kintone REST API
    • /k/v1/records.jsonのGETメソッド
  • 外部通信先はhttps://example.com/のみ許可

まずは、許可されたAPIを実行してみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
async function main() {
  // 許可されたJavaScript APIなので実行され、アプリのIDが取得できる
  const appId = await kintone.app.getId();
  console.log('kintone.app.getId', appId);

  // 許可されたJavaScript APIとREST APIなので実行され、アプリのレコード一覧が取得できる
  const records = await kintone.api('/k/v1/records.json', 'GET', {
    app: appId,
  });
  console.log('records', records);
}

main();

上記のコードをエディタ内で実行すると、アプリIDとレコード一覧が右側のパネルに表示されます。

次に、このサンプルプラグインでは許可されていないJavaScript APIkintone.app.record.get()を実行してみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
async function main() {
  const appId = await kintone.app.getId();

  // 許可されていないJavaScript APIなので実行されず、console上に以下のエラーが表示される
  // Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'get')
  const record = await kintone.app.record.get();
  console.log('kintone.app.record.get', record);
}

main();

許可されてないJavaScript APIが含まれているので実行すると、console上にエラーが表示されます。

同様に、許可されていないkintone REST API/k/v1/record.jsonにリクエストを送信してみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
async function main() {
  const appId = await kintone.app.getId();

  // kintone.apiは許可されたJavaScript APIではあるが、
  // レコードを単体を取得する(/k/v1/record.json)は許可されていないREST APIなので、
  // 実行されず、console上に以下のエラーが表示される
  // Uncaught (in promise) Error: api-not-allowed-error
  const record = await kintone.api('/k/v1/record.json', 'GET', {app: appId, id: 1});
  console.log('record', record);
}

main();

許可されてないREST APIが含まれているので実行すると、console上にエラーが表示されます。

また、許可されていない外部通信先https://cybozu.co.jp/にリクエストを送信してみましょう。

1
2
3
4
5
6
7
8
async function main() {
  // 許可されていない外部通信先なので、通信は実行されず、console上に以下のエラーが表示される
  // Error: Failed to fetch
  const response = await fetch('https://cybozu.co.jp/');
  console.log(response);
}

main();

許可されてない外部通信先が含まれているので実行すると、console上にエラーが表示されます。

このようにプラグインの新しい開発方式では、manifest.jsonで宣言した操作や通信のみが許可され、それ以外の操作や通信はブロックされます。

information

プラグインの新しい開発方式では、 Content Security Policy(CSP) (External link) を使い、プラグイン内からの通信を制限しています。

サンプルコードの実行結果をChromeのDevTools上で確認すると、CSPによって通信がブロックされていることを確認できます。

Refused to connect to 'https://cybozu.co.jp/' because it violates the document's Content Security Policy.

プラグインで指定した場所に新しくHTML要素を追加する

プラグインの新しい開発方式では、プラグインで定義したHTML要素を配置する場所があらかじめ用意されています。HTML要素を配置する場所はmanifest.jsonで指定し、プラグイン内ではJavaScriptを使ってHTML要素を作成できます。

今回のサンプルプラグインではレコード一覧画面の上部にエディタを表示するため、manifest.jsonでは次のように宣言しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
  "manifest_version": 2,
  "version": "0.2.0",
  // manifest.jsonで関連する部分のみ記載しています
  "type": "APP",
  "components": [
    {
      // プラグインを表示したい領域であるレコード一覧画面の上部を指定
      "type": "APP_INDEX_HEADER_SPACE",
      // 実際に実行する
      "js": ["js/index.js"],
      "css": ["css/index.css"]
    }
  ]
}

componentstypeAPP_INDEX_HEADER_SPACEを指定することで、次の場所にプラグインで作成したHTML要素を配置できます。

プラグインの新しい開発方式では、この枠内の部分がiframeになっており、kintone本体とは環境が分離されます。この枠内ではプラグイン側で自由にDOM操作が可能です。たとえば次のコードをエディタで入力して実行すると領域内にボタンが追加されます。

1
2
3
4
5
6
7
8
function main() {
  // button要素を作成し、領域内の最後に追加
  const button = document.createElement('button');
  button.textContent = 'Hello, World!';
  document.body.appendChild(button);
}

main();

一方で、iframe外の既存のDOMには直接参照できないようになります。

試しに、iframe外のDOMに対して操作を加える次のようなコードをエディタに入力して実行してみましょう。

1
2
3
4
5
6
function main() {
  // プラグイン側で、iframe領域外のレコード一覧画面のtable要素に対してスタイルを変更しようとしても、変更されない
  document.querySelector('main table').style.backgroundColor = 'red';
}

main();

iframe外のDOMは直接参照できないため、上記のコードを実行しても、レコード一覧画面のtable要素の背景色は変更されません。

information

現在、プラグインの新しい開発方式では、HTML要素の作成に指定できるのはCSS、JavaScriptのみですが、今後、HTMLファイルを追加できるような方法も検討中です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "manifest_version": 2,
  "version": "0.2.0",
  "type": "APP",
  // manifest.jsonで関連する部分のみ記載しています
  "type": "APP",
  "components": [
    {
      "type": "APP_INDEX_HEADER_SPACE",
      "js": ["js/index.js"],
      "css": ["css/index.css"],
      // HTMLを指定
      "html": ["html/index.html"]
    }
  ]
}

既存のDOMをkintone JS APIを使って操作する

新しい開発方式ではiframe領域外の既存のDOMを操作するための新しいJavaScript APIを提供します。

たとえば、kintone.app.setFieldStyleを使うことで、レコード一覧画面の特定の項目のみスタイルを変更できます。
あらかじめフィールドコードに文字列__1行_を指定したフィールドを用意しレコードを作成してから、次のコードをエディタに入力して実行することで、指定したフィールドのスタイルが変更されます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
async function main() {
  // スタイルを変更したい任意のレコードIDとフィールドコードを指定します
  // await kintone.app.setFieldStyle('recordId', 'fieldCode', {
  //   backgroundColor: 'red',
  //   color: 'white',
  //   fontWeight: 'bold',
  //   textDecoration: 'underline',
  // });
  await kintone.app.setFieldStyle('1', '文字列__1行_', {
    backgroundColor: 'red',
  });
}

main();