修正したはずの不具合が、別のアプリで再発する——kintone のカスタマイズを 2 年以上続けた現場で、アプリ数が 30 を超えたあたりから必ず顔を出す現象があります。原因の多くは、同一イベントに対して複数の JavaScript ファイルが走っている状態を、開発者が把握しきれていないことにあると見ています。
単一の JS ファイルを修正してテストが通ったから完了、と判断した瞬間に、別ファイルの処理と競合して本番で事故が起きる。本記事では、私たちが実案件で運用ルール化した「複数 JS 横断 grep」「1 ファイル完了と判断しない」「フィールドコード事前確認」の 3 点を軸に、構造的な再発防止策を整理してみます。
本記事の結論
kintone カスタマイズの事故は、JS の品質ではなく運用ルールの不在から起きる、というのが現場で繰り返し確認してきた経験則です。アプリ単位で 1 つの JS が動くという暗黙の前提が、アプリ数 30 を超えたあたりで崩壊し、同一イベントを複数ファイルが奪い合う状態に至ります。
対策は技術的に難しいものではありません。第一に、修正前にアプリ内の全 JS を横断 grep し、同じイベント・同じフィールドコードを触っている処理を洗い出す。第二に、1 ファイル修正で完了と判断せず、競合可能性のあるファイルを必ず再テストする。第三に、DEV 環境と本番環境でフィールドコードが揃っているかを事前確認する。この 3 つを運用ルールに落とすだけで、不可解な不具合の大半は事前に止まる、というのが私たちの整理です。
修正対象を「ファイル単位」ではなく「イベント単位」で捉え直すと、見えなかった依存関係が表に出てくる。
なぜアプリ数 30 を超えると JS が重なり始めるのか
kintone カスタマイズの初期段階では、1 アプリに 1 つの JS ファイルを紐づける構成が基本です。受注管理アプリには受注管理用の JS、案件管理アプリには案件管理用の JS、というシンプルな対応で済んでいる時期は、事故もほとんど起きません。
問題は業務拡張のフェーズで顕在化してきます。よくあるのは次の 3 種類のスクリプトが積み重なるパターンです。
種類 | 役割 | 増え方 |
|---|---|---|
共通処理ライブラリ | 日付計算・権限チェック・ログ送信などの横断機能 | アプリ全体に配布 |
部署別の追加処理 | 営業・経理・製造など部署ごとの個別要件 | 部署単位で増殖 |
ベンダー納品の派生スクリプト | 外注した拡張機能・連携処理 | アプリごとに散在 |
これらが 1 つのアプリ設定画面の「JavaScript / CSS でカスタマイズ」欄に 3〜5 ファイル並ぶ状態になると、同一イベント(app.record.edit.show や app.record.create.submit 等)に対して複数のハンドラが順番に登録される構造ができあがります。
経験則として、アプリ数 30 を境にこの発生確率は跳ね上がります。理由は単純で、アプリが 30 を超えると 1 人の運用者が全 JS の中身を覚えきれなくなるからです。記憶でカバーしていた依存関係が、ある日を境にコードを読み直さないと把握できなくなる。この閾値を越えた時点で、運用ルールの整備に切り替えなければなりません。
事故が起きる 3 つの典型パターン
実案件で観測してきた競合パターンは、抽象化すると以下の 3 つに集約できそうです。
パターン 1:上書き競合
同一フィールドの値を 2 つの JS が書き換える、最も基本的な競合です。たとえば JS-A が「保存時に消費税額を再計算する」処理を持ち、JS-B が「保存時に値引き後の合計を再計算する」処理を持つ場合、後から登録された方が前の結果を上書きします。症状としては「保存するたびに数字が微妙に変わる」「特定の操作順序でしか再現しない」など、テストで検知しづらい形で出てきます。
パターン 2:分岐切断(early return)
イベント内で先に return false または return event している処理が、後続のハンドラを止めてしまうパターンです。改修者は「自分の修正範囲だけ」を見て early return を入れますが、kintone のイベントハンドラはチェーン構造になっており、前の処理が返した値が次の処理に渡る仕様です。事例セクションで紹介する事故も、まさにこのパターンでした。
パターン 3:依存崩壊
共通ライブラリの関数名や引数を更新した際に、個別 JS 側の参照がずれて動かなくなる現象です。たとえば共通ライブラリの calcTax(amount) を calculateTax(amount, rate) に変更したとき、依存する 7 ファイルのうち 2 ファイルだけ追従漏れがある、というケースです。コンパイル時にエラーが出ないため、本番で該当処理が走った瞬間に初めて発覚します。
3 パターンに共通するのは、修正対象ファイル単体のテストでは検知できない点です。事故の構造はファイル間にあるのに、テストはファイル内で完結してしまう。これがアプリ数 30 を超えた現場で繰り返される失敗の根本構造だと整理しています。
再発防止の運用ルール 3 点
私たちが運用ルール化したのは、以下の 3 点です。技術的には新しいものは何もなく、「やる・やらない」の問題だと考えています。
A. 横断 grep で同一イベント・同一フィールドコードを洗い出す
修正に着手する前に、対象アプリの全 JS ファイルを対象に以下のような grep を必ず実行します。
# 同一イベントを触っている処理を一覧化
grep -rn "app.record.edit.show" customize/app-042/
# 同一フィールドコードを参照している箇所を一覧化
grep -rn "credit_check_status" customize/app-042/
この出力をそのまま PR の本文に貼り付けることをルール化すると、レビュアー側も依存関係を一目で把握できます。
B. 1 ファイル修正で完了と判断しない
修正したファイルだけテストして PR を出す運用は禁じ手にしています。代わりに、PR テンプレートに「競合可能性のあるファイル一覧」と「それぞれの再テスト結果」を記載する欄を設けました。grep の結果ヒットしたファイルは、原則すべて再テスト対象です。
C. DEV と本番のフィールドコード差分を事前確認
事故の半分は、DEV で動いていた JS が本番のフィールドコード差異で落ちることに起因します。チェックリストには次のような項目を入れています。
- 修正対象アプリのフィールドコード一覧を DEV / 本番でエクスポート
- diff を取り、命名・型・選択肢の差分がないか確認
- 差分があれば、本番反映前に DEV 側を本番に揃える
ルール定着の鍵は、PR テンプレートに強制的に欄を作ることです。チェックリストを別ファイルに置いても誰も見ません。PR のフォーマットに組み込んで、空欄では merge できない状態にすると一気に守られるようになります。
DEV から本番へのデプロイ運用で押さえる点
DEV 環境を「アプリテンプレートのコピー」で作っている現場では、本番でフィールドが追加・改名されるたびに、DEV 側との差分が静かに溜まっていきます。半年も運用すれば、DEV と本番でフィールドコードが微妙に異なるアプリが複数発生しているのが普通です。
デプロイ前に必ず実行すべきは、次の 2 つです。
タイミング | 実施内容 | 目的 |
|---|---|---|
デプロイ前 | フィールドコード一覧を DEV / 本番でエクスポートし diff | 命名差分の検知 |
デプロイ直後 | アプリ単位のスモークテスト項目を実行 | 主要イベントの動作確認 |
スモークテストは難しい必要はありません。アプリごとに「レコード新規作成 → 保存 → 編集 → 保存 → 一覧表示」の 5 ステップを通すだけでも、JS 競合の大半は検知できます。所要時間はアプリあたり 3 分程度です。
もう一つ重要なのは、フィールドコードの命名規約を初期に決めることです。後から揃えるのは骨が折れるため、運用初年度のうちに「英小文字スネークケース」「日本語禁止」「業務略号プレフィックス」などのルールを敷いておくと、3 年後の DEV / 本番差分問題が劇的に減ります。kintone のアプリ運用全般の劣化サインについては、kintone ガバナンス劣化が始まる 3 つのサイン でも整理しているので、合わせて参照してみてください。
製造業 50 アプリ運用での競合事故と再発防止までの 6 ヶ月
ある中堅製造業で、kintone アプリ 50 件・カスタマイズ JS 70 ファイルを 3 年運用してきた現場の事例を紹介します。受注管理アプリで「保存時に在庫アプリへ自動反映する処理」を改修したところ、本番リリース後に既存の与信チェック処理が動かなくなる事故が発生しました。
原因は単純で、改修対象の JS と与信チェックの JS が、同じ app.record.create.submit イベントに登録されており、改修側で return event の手前に early return を追加した結果、後続の与信チェックが実行されなくなっていた、というものでした。改修者は対象ファイル単体のテストで完了と判断しており、与信チェック側の動作確認は範囲外と認識していた状態です。
この事故を機に、私たちは前述の 3 つの運用ルールを導入しました。第一に、修正対象アプリ内の全 JS を grep で横断確認し、同一イベントを触っている処理を一覧化することを PR の必須項目に。第二に、関連ファイルの再テスト範囲を PR テンプレート内で宣言する欄を設置。第三に、DEV と本番のフィールドコード差分を月次で確認するチェックリストを整備しました。
運用ルール導入後の 6 ヶ月で、同種の競合事故はゼロ件で推移しています。技術的に新しいことは何もしていません。修正対象を「ファイル単位」ではなく「イベント単位」で捉え直しただけで、見えなかった依存関係が表に出るようになった、というのが現場の実感です。
kintone 既存スクリプト群の横断レビュー
kintone カスタマイズの運用ルール整備や、既存スクリプト群の健全化についてのご相談は、システム受託開発サービスから受け付けています。アプリ数が 30 を超えて運用が重くなってきた組織に向けて、JS 横断レビューの初期診断もご用意しています。
「最近、修正のたびに別の場所で不具合が出る」「JS の依存関係を誰も把握できていない」といった兆候が見え始めているなら、ルール整備のタイミングだと考えています。診断では、現状の JS ファイル一覧・イベント登録状況・フィールドコード差分を可視化し、優先度の高い改善ポイントを 3 点に絞ってお返ししています。
関連記事: