目次
(1) 環境構築編
(2) アプリ構築・設定編(この記事)
(3) アプリ実装編 part1
(4) アプリ実装編 part2
(5) ユニットテスト編
一連のソースは GitHub で公開しています。
前置き
前回 の記事では、 kintone カスタマイズで Vue.js
、TypeScript
、Pug
、SCSS
などのモダンな開発環境を利用しますよと言う趣旨で解説を始めましたが kintone ぜんぜん関係ないじゃんむしろただの Vue CLI で TypeScript プロジェクト作ります って話だったじゃんと言う展開でした。
今回はいよいよちゃんと kintone の話題です。
前提
以下の環境で作業しています。
- macOS Catalina
- Homebrew 2.1.16
- Node.js 13.1.0
- VisualStudio Code 1.40.1
(1) 環境構築編 の記事で、以下をセットアップしました。
- Vue.js 4.0.5
- TypeScript 3.5.3
- vue-cli-plugin-pug 1.0.7
他、プロジェクト作成時の流れで Sass / SCSS
や ESLint
、Prettier
、Jest
などがセットアップされています。
今回のゴール
今回は、 kintone のアプリを作り、前回作ったプロジェクトでそのアプリのカスタマイズスクリプトを開発を進め、その成果を kintone カスタマイズに適用する繋ぎ込みの部分を中心に説明していきます。
- kintone アプリを作成する
- kintone 関連ライブラリをインストールする
- カスタマイズを kintone に適用する
- もう少し楽に開発を進める
(2) アプリ構築編
kintone アプリを作成する
既にある程度 kintone 利用経験がある方にとっては言わずもがなでしょうが、もし kintone 触った事ないですって方は事前に cybozu developer network で kintone 開発者ライセンスを取得しておいてください。
今回はカスタマイズの説明が目的なので、アプリの作成そのものは特に解説しません。
話を簡単にするため、 kintone 側で用意している雛形アプリの中から「案件管理」アプリを使いましょう。
アプリ作成の際、「サンプルデータを含める」のチェックを付けてください。
これでデータがある程度格納されている状態でアプリが新規作成されます。
作成されたアプリはフィールドコードが「文字列__1行_
」など分かりづらい内容になっています。
カスタマイズではフィールド名よりもフィールドコードの方が重要なので、各フィールドのフィールドコードをフィールド名と合わせておくとこの先のカスタマイズが楽になります。
サイボウズさんこの辺までちゃんとしといてくれれば良いのにとは思いますが。
とりあえずこれで一旦アプリの準備は終了です。
kintone 関連ライブラリをインストールする
kintone カスタマイズを便利に進めるためのライブラリ類をインストールします。
前回 の記事で作成したプロジェクト kintone-vue-ts で作業します。
プロジェクトを VS Code で開いてください。
kintone JS SDK
まずは kintone JS SDK をインストールします。
ターミナルで以下のようにします。
% yarn add @kintone/kintone-js-sdk
kintone JS SDK
は、従来のカスタマイズでは冗長な記述になりがちだったレコードの全件取得や複数登録更新など、面倒な API 操作を良い感じに巻き取ってくれる SDK です。
ドキュメント も(英語ですが)平易で体系的にまとまっていますので、着実な工数削減が見込まれます。
kintone dts-gen
TypeScript
では d.ts ファイル(型定義ファイル)のあるなしが開発効率に大きく影響します。
kintone dts-gen はこの型定義ファイルの作成を支援してくれるツールで、よほどカスタマイズの規模が小さくない限りは TypeScript
で kintone 開発を行うなら必須と言えるものです。
kintone 公式ドキュメントではこちらで解説されています。
@kintone/dts-genはkintoneのJavaScriptカスタマイズ用の関数定義に加えて、指定したアプリからフィールド情報を取り出すコマンドラインツールが同梱されています。
との通りで、これをインストールする事により、
- エディタ上でコード補完が有効になる
- 型の誤りや関数に渡す引数の誤りなどと言った実装ミスを機械的に指摘してくれる
などの効果がもたらされ、開発効率の向上に多大に寄与してくれます。
インストールそのものは非常に簡単です。
% yarn add -D @kintone/dts-gen
で、
% npx kintone-dts-gen --help
と実行してヘルプがずらずらっと出て来れば OK です。
アプリのフィールド定義情報を取得する
では、インストールした dts-gen
を使い、先ほど作成した案件管理アプリの d.ts
ファイルを取得してみましょう。
コマンドのフォーマットは以下の通りです。
% npx kintone-dts-gen --host https://(サブドメイン).cybozu.com \
-u (ユーザー名) \
-p (パスワード) \
--app-id (アプリID) \
--namespace (名前空間プレフィクス) \
-o (ファイル出力先)
と言うフォーマットになっています。
例えば、
% npx kintone-dts-gen --host https://example.cybozu.com \
-u kintone-taro \
-p ******** \
--app-id 101 \
--namespace leadManagement.types \
-o src/lead-management.fields.d.ts
と言った具合です。
実行すると案件管理アプリのフィールド情報が格納された src/lead-management.fields.d.ts
ファイルが作成されます。
declare namespace leadManagement.types {
interface Fields {
確度: {
type: "RADIO_BUTTON";
value: string;
disabled?: boolean;
error?: string;
};
単価: {
type: "NUMBER";
value: string;
disabled?: boolean;
error?: string;
};
先方担当者: {
type: "SINGLE_LINE_TEXT";
value: string;
disabled?: boolean;
error?: string;
};
(省略)
}
interface SavedFields extends Fields {
$id: {
type: "__ID__";
value: string;
};
$revision: {
type: "__REVISION__";
value: string;
};
(省略)
}
}
Fields
インターフェイスがアプリに固有のフィールドに関する定義、SavedFields
インターフェイスはレコード ID や作成者・更新者などどのアプリでも必ず存在するフィールドに関する定義が含まれます。
先ほどアプリ作成後にフィールドコードを分かりやすくなるよう修正しましたが、その結果がここに現れて来るわけです。
型定義ファイルの参照を指定する
d.ts
ファイルを取得しただけでは、まだエディタ上でその効果を発揮させることはできません。
これを TypeScript
で参照可能にするために、プロジェクトの直下にある tsconfig.json
を編集します。
+ "files" : [
+ "./node_modules/@kintone/dts-gen/kintone.d.ts",
+ "./src/lead-management.fields.d.ts"
+ ],
"exclude": [
"node_modules"
+ "dist"
]
併せて exclude
にビルドしたファイルが格納される dist
を加えておくと良いでしょう。
コード補完の動作の様子は先ほども紹介した公式ドキュメントでも確認できます。
カスタマイズを kintone に適用する
これで一通り準備は整いましたので、いよいよ開発を進めていきます。
カスタマイズビューで Vue.js のマウントポイントを作成する
Vue.js
は DOM の特定の要素にインスタンスをマウントさせるところから始まりますが、kintone では カスタマイズビュー で DOM を定義してやるのが一般的でしょう。
案件管理 アプリの設定で「一覧」から+ボタン(一覧の追加)をクリックし、「レコード一覧の表示形式」で「カスタマイズ」を選択します。
「HTML」のボックス内に、とりあえずシンプルに以下のように書いて、
<div id="lead-management"></div>
そのあと左上の「保存」をクリックし、アプリの設定も保存してください。
ここで記述した lead-management
が、これから実装する Vue.js
のマウントポイントになるわけです。
カスタマイズビューに Vue.js
インスタンスをマウントする
当然ですが、この時点で「一覧1」ビューを見ても何も表示されません。
kintone カスタマイズの流儀に則り、レコード一覧イベント発生時に動作するよう実装していきます。
main.ts
現在のビューがカスタマイズビューであり、マウントポイントが存在し、インスタンスが未マウントである場合にマウント処理を実行すると言う流れにします。
main.ts
を以下のように修正します。
import Vue from "vue";
import App from "./App.vue";
Vue.config.productionTip = false;
// マウントポイント
const mountPount: string = "lead-management";
// インターフェイス
interface KintoneEvent {
offset: Number;
records: leadManagement.types.SavedFields[];
size: Number;
type: string;
viewName: string;
viewType: string;
}
/**
* イベント処理
*/
kintone.events.on(["app.record.index.show"], (e: KintoneEvent) => {
// カスタマイズビューでないなら何もしない
if (e.viewType !== "custom") {
return e;
}
// マウントポイントが存在するなら
if (
document.querySelector(`#${mountPount}`) ||
document.querySelector("#app")
) {
// 未マウントならマウント実行
if (!document.querySelector("#app")) {
vm = new Vue({
render: h =>
h(App)
}).$mount(`#${mountPount}`);
}
// レコードをセット
Vue.set(vm.$children[0], "records", e.records);
}
});
上記のポイントとしては、
-
kintone.events.on()
で受け取るイベントオブジェクトをインターフェイスとして定義しておく - そのインターフェイスの
records
オブジェクトの型として、先ほどdts-gen
で作成した型定義の配列leadManagement.types.SavedFields[]
を指定してやる - マウントポイントに
App
コンポーネントがマウントされていなければマウントを実行する - イベントオブジェクトで受け取ったレコードを
Vue.set()
関数でApp
コンポーネントに渡してやる
と言った点が挙げられます。
このイベントは最初にアプリのページを開いた時だけでなく、フィルタの設定を変更したりページャーでページを切り替えたりするたびに呼ばれるため、その都度下位コンポーネント(vm.$children[0]
で特定可能)にレコードを引き渡してやらなければなりません。
それを受け持つのが Vue.set
関数と言うわけです。
App.vue
次に、そのレコードを受け取って表示する側の App.vue
を実装します。
<template lang="pug">
#app
table
thead
tr
th 会社名
th 先方担当者
th 見込み時期
th 確度
th 製品名
th 単価
th ユーザー数
th 小計
tbody
tr(v-for="record in records")
td {{record.会社名.value}}
td {{record.先方担当者.value}}
td {{record.見込み時期.value}}
td {{record.確度.value}}
td {{record.製品名.value}}
td {{record.単価.value}}
td {{record.ユーザー数.value}}
td {{record.小計.value}}
</template>
<script lang="ts">
// デコレーター
import { Component, Vue } from "vue-property-decorator";
// コンポーネント
@Component
// クラス本体
export default class App extends Vue {
// [データ] 表示対象のレコード
recordData: leadManagement.types.SavedFields[] = [];
// [算出プロパティ] 表示対象のレコード
get records() {
return this.recordData;
}
set records(value) {
this.recordData = value;
}
}
</script>
<style scoped lang="scss">
#app {
table {
th,
td {
border: 1px solid #9cf;
padding: 2px 10px;
}
thead {
tr {
background-color: #dfd;
}
}
tbody {
tr {
background-color: #fff;
&:nth-child(even) {
background-color: #dff;
}
}
}
}
}
</style>
main.ts
から受け取った records
は setter でローカルの data
である recordData
に格納します。
同時にこれは getter として recordData
をそのまま返却するようにしており、これを使って v-for
で 1 つずつテーブルに出力します。
ビルドしてカスタマイズを適用する
このように実装した .ts
ファイルや .vue
ファイルをそのまま kintone のカスタマイズに適用する事は当然ながらできません。
kintone カスタマイズで利用可能なように、 JavaScript
ファイルにコンパイルしてやります。
VS Code のターミナルで、以下のように実行します。
% yarn build
すると、プロジェクト直下に dist
ディレクトリが作成され、その下に js
とか css
とかのディレクトリ、そして .js
や .css
ファイルが作成されるはずです。
ここで作成されたファイルを案件管理アプリの JavaScript / CSS カスタマイズに適用してやります。
改めて「一覧1」を表示すれば、レコード一覧が出力されるのが確認できます。
もう少し楽に開発を進める
一連の開発の流れを説明して来ましたが、コードにちょっと手を入れるたびに build
して kintone アプリに適用して・・・なんてことをやっていては効率が悪いことこの上ありません。
最終ビルド時は仕方ないとしても、開発中はソースの変更を保存したらすぐにブラウザ上で確認したいですよね。
しかしながら、このような用途で使われる yarn serve
(vue-cli-service serve
)では実ファイルが作成されないため(メモリ上に展開されるため)、そのままでは kintone のカスタマイズに適用する事はできません。
そこで、VS Code の拡張機能の1つである Live Server を利用します。
Live Server 自体のインストールや基本的な設定、HTTPS の設定はこちらを参考にしてください。
Live Server をインストールしたら、package.json
に以下のように設定します。
"scripts": {
"serve": "vue-cli-service serve",
+ "devel": "vue-cli-service build --mode development",
+ "watch": "vue-cli-service build --mode development --watch",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint"
},
さらに、.vscode/settings.json
も以下のようにしておきます。
{
"liveServer.settings.root": "/dist/",
"liveServer.settings.https": {
"enable": true,
"cert": "(フルパス)",
"key": "(フルパス)"
}
}
で、VS Code のターミナルで
% yarn watch
と実行し、エディタ右下の Go Live
をクリックします。
これで、
- ソースコードを編集すると自動的にビルドが実行される
- ローカルの
dist/js/*.js
ファイルをhttps://localhost:5500/*.js
としてブラウザで閲覧可能
となります。
アプリの閲覧結果も先ほどと同じ結果になるのが確認できるはずです。
次回は
というわけで、今回は Vue.js
と TypeScript
で開発するプロジェクトを kintone にはめる一連の流れを見ていきました。
ここから先はもう普通に kintone のカスタマイズの流儀に則って進めればいいだけですが、せっかくですので、このアプリをもう少しいい感じに育てていきたいかと思います。
今回触れなかった kintone JS SDK
の話にも触れていければと思います。