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とBabel、Polyfillを導入してkintoneカスタマイズを効率化する

また、実際の開発のときには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で動作を確認しています。