TypeScript で kintone カスタマイズ開発をしてみよう

目次

はじめに

コード量に比例してプログラムをメンテナンスするのが難しいと感じることはありませんか?
実行時に型が決定される JavaScript のようなタイプのプログラミング言語は、コード量の増加に比例して、メンテナンスが難しくなる傾向にあります。
こういった問題を解決するために TypeScript という言語があります。

本記事では TypeScript を使った kintone カスタマイズの方法について解説します。

TypeScript とは

TypeScript は Microsoft が開発する JavaScript の拡張言語です。

TypeScript の大きな特徴のひとつとして静的型チェックがあります。
TypeScript は JavaScript の拡張言語ですが、型情報をプログラム内に埋め込むことができます。
コンパイルと呼ばれる TypeScript から JavaScript への変換処理を通して型チェックを行います。
型チェックに失敗すると TypeScript から JavaScript への変換に失敗します。
プログラム内に適度に型情報を入れることで可読性や型チェックを行うことができるため、大規模なコードでもメンテナンスしやすいコードを書きやすくなります。

TypeScript の詳しい文法や変換される様子などは公式ドキュメントに譲ります。

参考

最後に地味にうれしい特徴として、VSCode や InitelliJ IDE(IDEA,Webstorm)では TypeScript の型情報から強力な補完機能の力を得ることができます。
コード補完については本記事の最後に GIF アニメを載せておきましたので興味ある方はごらんください。

前提知識について

この記事は、webpack と Babel を前提としています。
webpack についての知識がまったくない方は Webpack 入門 を参照してください。

また、実際の開発のときには TypeScript による型チェックだけでなく ESLint や Prettier などの静的解析ツールを合わせて利用することを強くおすすめします。

本記事は、 TypeScript で kintone カスタマイズ開発をやってみよう (External link) に加筆・修正したものです。

チュートリアル

チュートリアルでは、TypeScript を使った簡単な kintone カスタマイズを開発をしてみます。
Windows(Powershell)環境では、改行前のエスケープ文字「\(バックスラッシュ)」を「`(アクサングラーブ)」に置き換えてください。

ディレクトリー構造は次のとおりです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ tree -I node_modules
.
├── babel.config.js                   # babelの設定ファイル
├── dist                              # webpackの成果物
│   └── kintone-typescript-sample.js
├── package-lock.json
├── package.json
├── src
│   ├── fields.d.ts                   # @kintone/dts-genで生成した型情報
│   └── kintone-typescript-sample.ts  # カスタマイズのエントリーポイント
├── tsconfig.json                     # TypeScriptコンパイル設定
└── webpack.config.js                 # webpack設定ファイル

カスタマイズをするアプリを準備する

今回はアプリストアの「案件管理」アプリをカスタマイズしてみたいと思います。

プロジェクトの初期化を行う

プロジェクトの初期化を行います。
TypeScript で kintone 開発をするために必要なツールをインストールします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
npm init
npm install -D @kintone/dts-gen \
                         @babel/core @babel/plugin-proposal-class-properties \
                         @babel/preset-env \
                         @babel/preset-typescript \
                         babel-loader \
                         fork-ts-checker-webpack-plugin \
                         typescript \
                         webpack \
                         webpack-cli
  • @kintone/dts-gen ... kintone カスタマイズを開発するためのツール
  • @babel~~ .... ソースコード変換ツール
  • fork-ts-checker-webpack-plugin ... 型チェックを webpack のビルドの中で行うツール
  • TypeScript ... TypeScript コンパイラ
  • webpack,webpack-cli ... ビルドツール

kintone アプリのフィールド情報から型情報を生成してみよう

@kintone/dts-gen は kintone の JavaScript カスタマイズ用の関数定義に加えて、指定したアプリからフィールド情報を取り出すコマンドラインツールが同梱されています。

1
2
3
4
5
6
# npx @kintone/dts-gen ... も可能
# kintone.types.Fields, kintone.types.SavedFieldsがfields.d.tsに生成されます
npx kintone-dts-gen --base-url https://***.cybozu.com \
                                    -u username \
                                    -p password \
                                    --app-id 12
  • --base-url ... カスタマイズする予定の URL
  • -u ... ユーザー名
  • -p ... パスワード
  • --app-id ... カスタマイズする ID
  • --type-name ... 出力する型名(未指定の場合 Fields)
    • 保存ずみの型として SavedFields、保存前の型として Fields が生成されます。
  • --namespace ... 出力する名前空間(未指定の場合 kintone.types)
  • -o ... 出力するファイル名(未指定の場合 fields.d.ts)

上の例を実行すると fields.d.ts という kintone のフィールド情報をもとにした型定義ファイルが生成されます。
kintone のフィールド情報を更新したときはもう一度フィールド情報を作り直すようにしてください。
生成された field.d.ts を src ディレクトリー下に配置しておきましょう。

webpack.config.js を作成する

webpack.config.js の例は次のとおりです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const path = require('path');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

module.exports = {
  entry: {
    'kintone-typescript-sample': './src/kintone-typescript-sample.ts'
  },

  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
  },

  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.json']
  },

  module: {
    rules: [{test: /\.(ts|js)x?$/, loader: 'babel-loader', exclude: /node_modules/}],
  },

  plugins: [
    new ForkTsCheckerWebpackPlugin(),
  ]
};

設定ファイルのひな型は webpack-typescript-babel(github) (External link) の webpack.config.js を参考にしています。

tsconfig.json を作成する

tsconfig.json の例は次のとおりです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "noFallthroughCasesInSwitch": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "esModuleInterop": true,
    "noUnusedLocals": true,
    "noImplicitAny": true,
    "declarationDir": "dist/types",
    "declaration": true,
    "target": "es5",
    "module": "es2015",
    "strict": true
  },
  "files" : [
    "./node_modules/@kintone/dts-gen/kintone.d.ts",
    "./src/fields.d.ts"
  ],
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "dist",
    "node_modules"
  ]
}
  • files ... コンパイル対象のファイルを指定します。
    型情報のファイルを指定することでコンパイル時、未定義関数のエラーを防ぎます。
  • includes ... コンパイル対象のファイルを指定しています。
    * などの glob パターンを利用できます。
  • excludes ... コンパイル対象から除外するファイルを指定しています。

files にチュートリアルにて生成した型定義情報と kintone 上で利用できる関数定義ファイル(kintone.d.ts)を追加します。
TypeScript コンパイラは型チェック時に設定ファイルを読み込み、型定義情報どおりにプログラムが書けているかチェックを行ってくれます。
これ以外の設定方法としてスラッシュを 3 回書く記法もあります。
こちらを使いたい場合は TypeScript の公式ドキュメントを参照してください。

設定ファイルのひな型は webpack-typescript-babel(github) (External link) の tsconfig.json を参考にしています。

Babel の設定ファイルを配置する

babel.config.js の例は次のとおりです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
module.exports = function(api) {
  api.cache(true);
  const presets = [
    [
      '@babel/preset-env',
      {
        useBuiltIns: 'entry',
        corejs: 3,
      }
    ],
    '@babel/typescript'
  ];
  const plugins = [
    [
      '@babel/proposal-class-properties'
    ]
  ];
  return {
    presets,
    plugins,
  };
};

本チュートリアルでは、型チェックを TypeScript で行います。
また、ES5 へのプログラム変換を Babel で行うようにします。
TypeScript は Polyfill を行わないため、Babel で Polyfill も一緒に行います。(よくわからなければ読み飛ばして OK です)

TypeScript でプログラムを書いてみよう

src/kintone-TypeScript-sample.ts の例です。

1
2
3
4
5
6
7
8
9
const HANDLE_EVENT = "app.record.create.show";
interface KintoneEvent {
    record: kintone.types.SavedFields;
}
kintone.events.on(HANDLE_EVENT, (event: KintoneEvent) => {
    event.record.単価.value = "1";
    event.record.ユーザー選択.value = [{name: "名前", code: "コード"}];
    return event;
});

webpack でビルドしてみよう

1
npx webpack-cli --mode development

次のような出力がでてくると成功です。

1
2
3
4
5
6
7
8
9
Starting type checking service...
Using 1 worker with 2048MB memory limit
Hash: 2b19dc578431992634bb
Version: webpack 4.29.3
Time: 2010ms
Built at: 2019-02-14 21:58:08
                       Asset      Size                     Chunks             Chunk Names
kintone-typescript-sample.js  4.15 KiB  kintone-typescript-sample  [emitted]  kintone-typescript-sample
Entrypoint kintone-typescript-sample = kintone-typescript-sample.js

チュートリアルは以上です。お疲れさまでした。

IDE で補完される様子を見てみよう

IDE の細かな設定をしていない状態だと補完が有効に効かず、IDE は過去の入力履歴程度を提案してくれる程度です。
しかし、TypeScript の型情報があると補完を強力に効かせたコーディングを行うことができます。

  1. 型情報を定義している様子

    kintone.types.SavedFields は@kintone/dts-gen で自動生成された型情報です

  2. kintone.events.on などの kintone 上で利用できる関数も補完してくれます。

  3. フィールドコードの補完してくれるのでコーディングがはかどります。

  4. 設定するデータ型を間違えるとコンパイルエラーになって、間違いを教えてくれます。

    VSCode でのコーディングを撮影していますが、型情報があっていない部分はエラー表示してくれます。

information

この Tips は、2019 年 3 月版 kintone で動作を確認しています。