kintoneのカスタマイズ開発もモダン化傾向を感じる今日この頃ですが、ちょっと前に「TypeScriptでkintoneカスタマイズ開発をしてみよう」といった記事が掲載されました。この記事の中で言及されているeslint
やprettier
の導入と@kintone/customize-uploader
を利用したカスタマイズのデプロイまでを含めた開発の準備をまとめてみました。
準備
TypeScript関連パッケージのインストール
まずは、記事を参考にTypeScriptに関するパッケージをインストールします。
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
npm install -S @babel/polyfill # https://babeljs.io/docs/en/usage#polyfill
ESLint、Prettier関連パッケージのインストール
続けて、eslint
、prettier
周辺のパッケージをインストールします。
npm install -D eslint @typescript-eslint/eslint-plugin \
prettier eslint-config-prettier eslint-plugin-prettier
npm install -D @cybozu/eslint-config
.eslintrc.json
は次のように準備します。この辺(1, 2)の内容ベースですが、eslint:@cybozu/eslint-config
部分を修正したりしています。Prettierルールとの衝突等考慮点がありますが、まだ試行錯誤中です。
{
"extends": [
"@cybozu/eslint-config",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
"prettier/@typescript-eslint"
],
"plugins": [
"@typescript-eslint"
],
"parser": "@typescript-eslint/parser",
"env": {
"browser": true,
"node": true,
"es6": true
},
"parserOptions": {
"sourceType": "module"
},
"globals": {
"kintone": false
},
"rules": {
"indent": ["error", 2]
}
}
インデント2で使いたいのでrules
にそれだけ指定しつつ、.editorconfig
も生成しておきます。
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
TypeScript、Webpack関連の設定ファイルの準備
この辺で、対象のkintoneアプリに合わせたTypeScriptの型定義を生成します。生成されたfields.d.ts
はソースを整理するsrc
を作成して移動しておきます。
npx kintone-dts-gen --host https://xxx.cybozu.com \
-u user \
-p password \
--app-id 596
mkdir src; mv fields.d.ts src
記事の通り、tsconfig.json
、babel.config.js
も準備します。
{
"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",
"dest",
"node_modules"
]
}
module.exports = function (api) {
api.cache(true);
const presets = [
[
"@babel/preset-env",
{
"useBuiltIns": "usage"
}
],
"@babel/typescript"
];
const plugins = [
[
"@babel/proposal-class-properties"
]
];
return {
presets,
plugins,
}
}
webpack.config.js
は次のように整えておきます。
const path = require('path');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
module.exports = {
mode: "development",
entry: {
"customize" : "./src/customize.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(),
]
};
@kintone/customize-uploaderの設定
そして、@kintone/customize-uploader
のインストールと初期設定を行います。
npm install -D @kintone/customize-uploader
$(npm bin)/kintone-customize-uploader init
{
"app": "596",
"scope": "ALL",
"desktop": {
"js": [
"dist/customize.js"
],
"css": []
},
"mobile": {
"js": [
"dist/customize.js"
]
}
}
npm-run-allを利用したwatchの設定
TypeScript等を含めたビルドを担うwebpackのwatchと、その出力をアップロードするための@kintone/customize-uploader
のwatchを共存するために、@kintone/create-plugin
と同様にnpm-run-all
を導入しscripts/npm-start.js
を準備します。
npm i -D npm-run-all
"use strict";
const runAll = require("npm-run-all");
runAll(["develop", "upload"], {
parallel: true,
stdout: process.stdout,
stdin: process.stdin
}).catch(({results}) => {
results
.filter(({code}) => code)
.forEach(({name}) => {
console.log(`"npm run ${name}" was failed`);
})
;
});
package.jsonとフォルダ構成を確認
最後にpackage.json
のscripts
に後々の作業を楽にできるように幾つか足して、次のようにしておきます。update:fields
はパスワード埋め込みになるので、ちょっと悩ましいところです。start
ではtsファイルの変更で、webpackのバンドルからjsファイルのデプロイまで行えるようになります。
{
"name": "kintone-customize-bolierplate-ts",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"update:fields": "npx kintone-dts-gen --host https://xxx.cybozu.com -u user -p passowrd --app-id 596; mv fields.d.ts src",
"start": "node scripts/npm-start.js",
"upload": "kintone-customize-uploader --watch dest/customize-manifest.json",
"develop": "npm run build -- --watch",
"build": "webpack",
"build:prod": "webpack --mode production",
"lint": "eslint src/*"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.4.4",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"@babel/preset-typescript": "^7.3.3",
"@cybozu/eslint-config": "^4.0.1",
"@kintone/customize-uploader": "^1.5.3",
"@kintone/dts-gen": "^1.0.2",
"@typescript-eslint/eslint-plugin": "^1.9.0",
"babel-loader": "^8.0.6",
"eslint": "^5.16.0",
"eslint-config-prettier": "^4.3.0",
"eslint-plugin-prettier": "^3.1.0",
"fork-ts-checker-webpack-plugin": "^1.3.3",
"npm-run-all": "^4.1.5",
"prettier": "^1.17.1",
"typescript": "^3.4.5",
"webpack": "^4.31.0",
"webpack-cli": "^3.3.2"
}
}
❯ tree -L 1 -a
.
├── .editorconfig
├── .eslintrc.json
├── .git
├── .gitignore
├── babel.config.js
├── dest
├── dist
├── node_modules
├── package-lock.json
├── package.json
├── scripts/npm-start.js
├── src
├── tsconfig.json
└── webpack.config.js
以上で設定は終了です。
kintoneカスタマイズコーディング
準備が整ったら、記事にあるように次のようにコーディングを進めましょう。
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;
});
所感
- kintoneの型が収められている
kintone.d.ts
が便利です!-
kintone.d.ts
はtsconfig.json
を見るとfiles
でfields.d.ts
と共に./node_modules/@kintone/dts-gen/kintone.d.ts
として指定されています - これだけ
reference
タグで読み込んで使うというのも便利です
-
- kintoneでよくある複数のアプリを対象にしたカスタマイズでは、
kintone-dts-gen
する際に--namespace
でfields.d.ts
を作り分けて対応すると良さそうです(ドキュメントより) - kintoneのカスタマイズ開発でもコード量が多くなることが見込まれるケースには、TypeScriptの利用は有効かと思いました。TypeScriptでの一般的なメリットをkintoneカスタマイズ開発でも享受できます
- 逆に、コード量が増える見込みがないケースでは無理して使う必要もなさそうかなぁと思いました(ただ、
kintone.d.ts
の利用は幸せになれると思います) - 同様に、kintoneカスタマイズ初学者の方はTypeScript自体の導入・学習コストが高く感じられると思いますし、いきなりコード量が多いカスタマイズに挑むケースは考えづらいとすれば、従来のJavaScriptのカスタマイズに慣れてきて、Webpackを利用する開発が必要になったり、そのメリットが見えてくるケースに遭遇するようになったらTypeScript導入を検討頂くと良いのかなと思いました
- 逆に、コード量が増える見込みがないケースでは無理して使う必要もなさそうかなぁと思いました(ただ、
- ESLint、Prettierの設定が良い感じなのかが自信なく、試行錯誤を続けたいと思います