はじめに
「webpackを利用するkintoneプラグイン開発の流れ」でも触れていますが、kintone界隈の開発手法・ツールの利用についても最近色々とツール拡充がなされ、いわゆるモダンな開発方法というのも取り込みやすくなってきました。
kintoneのカスタマイズ開発で既に webpack を利用されている方も多いと思いますが、今回はwebpack
と @kintone/customize-uploader
を用いたカスタマイズ開発の流れを見ていきたいと思います。
修正点
- 2019.9.1 - Babel 7.4.0 における @babel/polyfill 非推奨を受けて、修正
大まかな流れ
-
npm init -y
でプロジェクトを開始する - webpack関連で必要なモジュールをインストールする
-
@kintone/customize-uploader
のインストールと設定を行う - webpackと
@kintone/customize-uploader
のwatchオプションを共存させる
詳しく見ていきましょう。
プロジェクトを開始する
カスタマイズ対象アプリが1つの簡単なケースをnpmのプロジェクトとして新しく始める流れを考えたいと思います。
プロジェクトフォルダ(今回の例はnew-project
)を作成・移動して、npmプロジェクトを開始します。
mkdir new-project; cd new-project
npm init -y
webpack関連のモジュールをインストールする
webpack
まず、webpack
とwebpack-cli
をインストールします。
npm install --save-dev webpack webpack-cli
ES6
webpackを利用するカスタマイズではES6使いたい意図が含まれることが多いので、ES6関連のパッケージをインストールします。ES6で書いてもkintone対応ブラウザのIE11にも対応できるように、 core-js
、 regenerator-runtime
を利用します(async/await
も利用できるようにしておきます)。
npm install --save-dev babel-loader @babel/core @babel/preset-env
npm install --save-dev core-js regenerator-runtime
webpack.config.jsを準備する
const path = require('path');
module.exports = {
mode: "development",
entry: {
"customize": "./src/js/customize.js"
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist', 'js'),
},
resolve: {
extensions: ['.js', '.json']
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader', // https://webpack.js.org/loaders/babel-loader/#root
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
};
この設定によって、src/js/customize.js
のエントリーからdist/js/customize.js
のバンドルファイルが生成されるイメージで、次のようなフォルダ・ファイル構成になります。
new-project
├── dist/js/customize.js
├── package-lock.json
├── package.json
├── src/js/customize.js
└── webpack.config.js
また、この時点でのpackage.jsonはこのような感じになります。scripts
に webpack の操作を追加しています。npm run build
がwebpack
のショートカットになる、といった具合ですね。
また、webpackはwatchオプションでエントリの変更検知が走りますし、バンドルのリードタイムが都度ビルドより速いことが知られています。
{
"name": "new-project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"develop": "npm run build -- --watch",
"build": "webpack",
"build:prod": "webpack --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"babel-loader": "^8.0.6",
"core-js": "^3.2.1",
"regenerator-runtime": "^0.13.3",
"webpack": "^4.39.3",
"webpack-cli": "^3.3.7"
}
}
@kintone/customize-uploaderのインストールと設定を行う
バンドルファイルをkintoneに適用する方法としては、ローカルWebサーバーを立ち上げたり色々な方法が取られていると思いますが、今回は@kintone/customize-uploader
を利用する方法を示していきます。
@kintone/customize-uploaderのインストール
npm install --save-dev @kintone/customize-uploader
@kintone/customize-uploaderの初期設定
$(npm bin)/kintone-customize-uploader init
# dest/cutomize-manifest.json が生成される
生成されたdest/cutomize-manifest.json
のdesktop.js
に、バンドルファイルであるdist/js/customize.js
を指定します。
{
"app": "599",
"scope": "ALL",
"desktop": {
"js": [
"dist/js/customize.js"
],
"css": []
},
"mobile": {
"js": []
}
}
@kintone/customize-uploader
もwatch
オプションを持っていますので、package.json
のscripts
にupload
を足して使いやすくしておきます。これで、dest/customize-manifest.json
で指定されたファイルの変更に合わせたアップロードがかかるようになります。
{
"name": "new-project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"upload": "kintone-customize-uploader --watch dest/customize-manifest.json",
"develop": "npm run build -- --watch",
"build": "webpack",
"build:prod": "webpack --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@kintone/customize-uploader": "^2.0.4",
"babel-loader": "^8.0.6",
"core-js": "^3.2.1",
"npm-run-all": "^4.1.5",
"regenerator-runtime": "^0.13.3",
"webpack": "^4.39.3",
"webpack-cli": "^3.3.7"
}
}
webpackと@kintone/customize-uploaderのwatchオプションを共存させる
ここまで来ると、watchによる処理がwebpackと@kintone/customize-uploaderによって2つ存在していることに気付きます。
1 webpackでエントリファイルの変更に応じてバンドル処理が走りバンドルファイルが生成される
2 バンドルファイルの変更に変更があった際にkintoneにアップロードする
更にこれらを共存できれば、エントリファイルを変更した際にバンドルが走ってkintoneにアップロードされるといった処理の一連化され、更に開発効率が上がってきます。
これは、@kintone/create-plugin
で利用されているnpm-run-all
というパッケージを利用すれば、同じように対応することが可能です。
まず、パッケージをインストールします。
npm install --save-dev npm-run-all
そして、@kintone/create-plugin
と同じくscripts/npm-start.js
を準備します。
"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
のscripts
を追加します。@kintone/create-plugin
と同じ体験にするために、start
として追加します。
{
"name": "kintone-customize-boilerplate",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"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"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@kintone/customize-uploader": "^2.0.4",
"babel-loader": "^8.0.6",
"core-js": "^3.2.1",
"npm-run-all": "^4.1.5",
"regenerator-runtime": "^0.13.3",
"webpack": "^4.39.3",
"webpack-cli": "^3.3.7"
}
}
これで、npm run start
でエントリファイルの変更時にバンドルとkintoneへのファイルアップロードが都度行われるようになり、開発も捗る状態かと思います。
ちなみに、この時点でのフォルダ構造を確認しておくと、次の通りです。
new-project
├── dest
├── dist
├── node_modules
├── package-lock.json
├── package.json
├── scripts
├── src/js/customize.js
└── webpack.config.js
今回のエントリファイルであるsrc/js/customize.js
を例えばこのような状態から、色々書き換えてみてください。
import "core-js/stable";
import "regenerator-runtime/runtime";
kintone.events.on('app.record.detail.show', event => {
alert('Hello, webpack');
return event;
});
変更すると、バンドルとアップロードが走るはずです。
まとめ
webpackを利用するkintoneカスタマイズ開発の流れについて見てきました。全体に言えることは、フォルダ・ファイル構成についてのベストプラクティスは対象が複数のアプリになったり状況によって変わってきますので、今回の記事はいち例として参考になればと思います(自分も実際にはESLintが入っていたり、複数アプリを対象にするため、少々複雑な構成を扱っています)。
webpackの設定については、CSSを同時にバンドルしたい、Reactを使いたいといった内容に合わせて昇華してもらえれば良いかと思います。これもケースバイケースだと思います。
kintoneへのカスタマイズ適用については、@kintone/customize-uploader
でファイルをアップロードするのか、Webサーバーを利用するのか等は自分は好みの領域かと思っています(ローカルサーバーを立てるのに慣れている人はそうすれば良いと思いますし、証明書発行等色々設定増やしたくない人は今回の方法でも良いでしょう)。