JavaScript
webpack
kintone
babel

kintone プラグイン開発の環境構築 (Windows)

はじめに

既に kintone カスタマイズの開発環境について先進的な内容の記事を見かけますが、ここではフロントエンド開発の経験があまりない私の kintone のプラグインの開発環境の構築手順と設定内容などについて書いていきます。

要件

プラグインの作成にあたり、以下の要件がありました。

  • Windowsで開発
  • git 管理
  • 共通処理をモジュール化して他のプラグインでも使用する
  • es6 ベースでコーディング (async / await も使用)
  • kintone は IE11 をサポート対象としているので es5 にトランスパイルする
  • 製品版は難読化し、開発版は難読化しない

構成概要

前述の要件を満たす構成として、以下のようにしました。

構築手順と設定

Git for Windows のインストール

kintone developer network のドキュメントにはcygwinという言葉がでてきますが、もっと手軽に bash 環境が得られる Git for Windows を選択しました。

トップページの download からダウンロードしてインストールします。

インストール時のConfiguring the line ending conversionsの設定はCheckout as-is, commit as-isにしておくと改行コードの扱いについて混乱しないかと思います。

make を利用したい!という方もいらっしゃるかもしれませんが、Git bash には make は含まれていません。
ezwinportsからmake-4.1-2-without-guile-w32-bin.zipをダウンロードし、解凍したbinフォルダ配下のmake.exeC:\Program Files\Git\mingw64\bin配下にコピーすることで使用できるようになります。

Visual Studio Code のインストールと設定

以前まで JavaScript のコードを書くのに Eclipse を使用していましたが、重かったりコード補完がうまく動かなかったり(設定が悪かったのでしょうが)と、ストレスが溜まりまくっていたので思い切って変えました。動作が軽く、コード補完も特別な設定なく動き、とても満足しています。

トップページの Download for Windows からダウンロードしてインストールします。

拡張機能として Japanese Language Pack for Visual Studio Code とESLint をインストールしておきます。
インストール方法については省略します。

ターミナルはデフォルトでは Power Shell になっていますが、 bash を選択しておくと、Git bash を別途立ち上げなくても bash コマンドが実行できるようになり便利です。
メニューバーの「表示」→「ビューを開く...」→「ターミナル」を選択し、開いたターミナルビューの「+」アイコンを(初めて)クリックすると、新しい種類のターミナルを追加でき、そこで Git Bash を選択します。

その他の基本設定は、メニューバーから「ファイル」→「基本設定」→「設定」から行い、 JSON で設定します。
既定の改行文字を LF にしておくとよいでしょう。
以下は設定例です。

{
    "window.zoomLevel": -1,
    "editor.renderWhitespace": "all",
    "window.menuBarVisibility": "default",
    "terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe",
    "editor.renderControlCharacters": true,
    "files.eol": "\n",
    "files.exclude": {
        "**/.git": true,
        "**/.svn": true,
        "**/.hg": true,
        "**/CVS": true,
        "**/.DS_Store": true,
        "**/.project": true,
        "**/.tern-project": true
      },
}

Node.js のインストール

トップページの 推奨版をダウンロードしてインストールします。

特筆することはないので詳細は省略します。

kintone-plugin-packer のインストール

プラグインのパッケージ化ツールとして、kintone developer network のドキュメントでは package.sh の使用について記述されていますが、フォルダ配下にドットで始まるファイルがあるとエラーが発生してプラグインが作成できないため、非常に使い勝手が悪いです。
kintone-plugin-packer は、フォルダ配下のドットで始まるファイルは無視してくれます。

グローバルにインストールします。

$ npm install -g @kintone/plugin-packer

ESLint のインストール

Visual Studio Code の拡張機能でインストールしましたが、パッケージとしてもインストールする必要があります。

ローカルにインストールした方がよいかもしれませんが(ESLint をグローバルにインストールせずに使う)、私の場合はグローバルにインストールしています。

$ npm install -g eslint

これ以降は、個々のプラグインについての設定になります。

プラグイン用フォルダの作成

kintone developer network のドキュメントにあるようにパッケージングするためのフォルダ階層及びファイル名は自由なので、適当にフォルダを作成し、manifest.jsonを作成して配置します。
distフォルダはパッケージ化したプラグインの保存用フォルダとして作成しておきます。

sample-plugin
    |-- css
    |   |-- customize.css //PC用CSSファイル
    |   `-- config.css //設定画面用CSSファイル
    |-- dist // プラグインの保存用
    |-- html
    |   `-- config.html //設定画面用htmlファイル 
    |-- images
    |   `-- icon.png //アイコンファイル
    |-- js
    |   |-- _customize.js //PC用JavaScriptファイル(編集用)
    |   `-- _config.js //設定画面用JavaScriptファイル(編集用)
    `-- manifest.json //マニフェストファイル

git の初期化と .gitignore の作成

プラグイン用フォルダ直下で以下のコマンドを実行します。これはプラグイン用フォルダを作成した直後に行います。

$ git init

.gitignore は Visual Studio Code またはターミナルからvimコマンド等で作成します。
記述する内容については github/gitignore が参考になります。
Global/VisualStudioCode.gitignoreNode.gitignore の内容を組み合わせたものでよいでしょう。

適宜 git に commit します。

ESLint の設定

プラグイン用フォルダ直下で以下のコマンドを実行します。これはプラグイン用フォルダを作成した直後で JavaScript ファイルを書き始める前に行います。

$ eslint --init

質問に答えていくと.eslintrc.拡張子がプラグイン用フォルダ直下に作成されます。拡張子は json、yml、js のいずれかになります。
下記は設定例ですが、 kintone プラグインなので、browsertrueにする必要があります。

.eslintrc.js
module.exports = {
    "env": {
        "browser": true,
        "es6": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
        "sourceType": "module",
        "ecmaVersion": 2017
    },
    "rules": {
        "indent": [
            "error",
            4
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "single"
        ],
        "semi": [
            "error",
            "always"
        ]
    }
};

各種パッケージのインストールと設定

プラグイン用フォルダ直下で、npm initを実行してpackage.jsonを作成します。

$ npm init

webpack、babel のインストールと設定

$ npm install --save-dev babel-core babel-loader babel-preset-env webpack webpack-cli webpack-obfuscator

babel-preset-envが es5 にトランスパイルするため、webpack-obfuscatorが難読化するためのパッケージです。

プラグイン用フォルダ直下にwebpack.config.jsを作成します。

webpack.config.js
    const JavaScriptObfuscator = require('webpack-obfuscator');
    const path = require('path');

    module.exports = (env, argv) => ({
        devtool: false,
        entry: {
            customize: './js/_customize.js',
            config: './js/_config.js',
        },
        output: {
            path: path.join(__dirname, 'js'),
            filename: '[name].js'
        },
        module: {
            rules: [{
                test: /\.js$/,
                use: [{
                    loader: 'babel-loader',
                    options:  {
                        presets: [
                            ['env', {
                                'targets': { 'ie': 11 },
                                'useBuiltIns': true
                            }]
                        ]
                    }
                }]
            }]
        },
        plugins:
            argv.mode === 'production' ? [
                new JavaScriptObfuscator({
                    rotateUnicodeArray: true
                })
            ] : [],
    });

entryの設定部分で、webpack の処理対象のファイルを指定し、outputの設定部分で出力ファイルの設定をしています。
上記の設定の場合、js/_customize.jsjs/_config.jsを webpack 処理して それぞれjs/customize.jsjs/config.jsとして出力するという意味になります。

es5 へのトランスパイルの設定がmoduleの部分になります。

難読化の設定がpluginsの部分になります。ここでは、モードが production 指定された場合だけ難読化処理を行うようになっています。

その他のパッケージのインストール

プラグインを作成するのに必要な共通処理のモジュールや、ライブラリ等をnpm install --saveコマンドを使用してインストールします。

es5 へのトランスパイル

プラグイン用の処理を行う JavaScript ファイルが完成したら、プラグイン用フォルダ直下で以下のコマンドを実行して es5 へトランスパイルします。

製品版用
$ webpack --colors --mode production

--modeproductionを指定することで、es5にトランスパイルされ、さらに難読化された JavaScript ファイルが js フォルダに吐き出されます。
前述の設定の場合、js/customize.jsjs/config.jsが出力されることになります。manifest.jsonの js ファイルの設定は、これらのファイルのパスを書くことになります。

--modedevelopmentを指定すると、難読化されていない es5 にトランスパイルされた js/customize.jsjs/config.jsが出力されることになります。

開発版用
$ webpack --colors --mode development

トランスパイルに関する補足

トランスパイル対象の (エントリーポイントの)JavaScript ファイルには、以下の記述が必要になります。

import 'babel-polyfill';

しかし、同じ方法でトランスパイルした複数のプラグインを一つのアプリで使用した場合、以下のエラーが発生します。

Uncaught Error: only one instance of babel-polyfill is allowed

これを回避するには、前述の import 文 を以下のように変更します。

if (!window._babelPolyfill) { 
    require('babel-polyfill');
}

参照: https://github.com/babel/babel/issues/4019

プラグインパッケージ化

プラグイン用フォルダ直下で以下のコマンドを実行して kintone のプラグインの形式にパッケージ化します。

$ kintone-plugin-packer --out ./dist/sample-plugin.zip ./

dist フォルダ配下にプラグイン(sample-plugin.zip)と秘密鍵が出力されます。

秘密鍵のファイル名が kintone 上でプラグイン ID となります。
同じ鍵を使用して作成されたプラグインを kintone に登録した状態で、さらに読み込みをすると上書きされ、kintone に設定されたプラグインのコンフィグも引き継がれます。
従って、プラグインをバージョンアップする際には、同じ鍵を使用してパッケージ化する必要があります。

二回目以降のパッケージ化は以下のように鍵を指定します。
(鍵ファイル名をcbpjnaafohfpdelmghnhfkmleinbhpho.ppkとします)

$ kintone-plugin-packer --ppk ./dist/cbpjnaafohfpdelmghnhfkmleinbhpho.ppk --out ./dist/sample-plugin.zip ./

これらを毎回手打ちするのは面倒なので、package.jsonの scripts に登録しておきます。

package.json抜粋
    "scripts": {
        "build-dev": "webpack --colors --mode development && kintone-plugin-packer --ppk ./dist/cbpjnaafohfpdelmghnhfkmleinbhpho.ppk --out ./dist/sample-plugin-dev.zip ./",
        "build": "webpack --colors --mode production && kintone-plugin-packer --ppk ./dist/cbpjnaafohfpdelmghnhfkmleinbhpho.ppk --out ./dist/sample-plugin.zip ./"
    }

これにより、下記のコマンドで es5 へのトランスパイルとプラグインのパッケージ化が行えるようになります。

$ npm run build

開発版の場合は以下のコマンドになります。

$ npm run build-dev

おわりに

なるべくモダンな環境を構築したつもりですが、フロントエンド開発を専門としていないこともあり、 JavaScript のトレンドの変化の早さにはついていけてないのが正直なところです。ご指摘等頂けると幸いです。

このような環境で作成した kintone プラグインを https://webware.theshop.jp/ にて販売中です。