Slide 1

Slide 1 text

ノーコードツールの裏側につきまとう 「20分岐」との戦い 2025.03.21 1 Muddy Web #11 ~Special Edition~ サイボウズ株式会社 開発本部 おぐえもん(小倉 且也)

Slide 2

Slide 2 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) この発表について はじめに • サイボウズの主力製品・kintoneのフロントエンド刷新を手がける中で 常に付きまとう大量の条件分岐の実態を紹介します • ノーコードツールを支えるフロントエンドの実装を 垣間見ることができます • 大量の条件分岐や型を効率的に捌くテクも用意しています 2

Slide 3

Slide 3 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) 自己紹介① はじめに • サイボウズ株式会社 開発本部 フロントエンドエンジニア • 2022年9月入社/kintoneのフロントエンド刷新に従事 • 2024年からkintoneの主要機能の1つである 「アプリ」機能のUI刷新をリード 3 おぐえもん(小倉 且也) @oguemon_com https://oguemon.com/

Slide 4

Slide 4 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) 自己紹介② はじめに • ↓個人開発で色々作ってるので、みんなみてね! 4 おぐえもん(小倉 且也) @oguemon_com https://oguemon.com/ オススメ!!

Slide 5

Slide 5 text

本題に入る前に、製品とプロジェクトのことを紹介します! 5 今回取り上げる製品の概要

Slide 6

Slide 6 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) kintoneって何? サービスとプロジェクトの概要 • サイボウズの主力製品 • 37,000社が利用(2025年1月時点) • 業務のシステム化や効率化を実現する アプリが「シュシュッと」つくれる ノーコードツール 6

Slide 7

Slide 7 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) kintoneはめっちゃ多機能 サービスとプロジェクトの概要 7 • これらをはじめ 色んな機能がある グラフ・レポート機能 データベース機能 モバイル・通知機能 コミュニケーション機能 プロセス管理機能 ポータル機能 監査ログ機能 アクセス権 多言語対応 日本語・英語・簡体字・繁体字・ スペイン語・タイ語・ポルトガル語(ブラジル) スレッド機能 検索機能

Slide 8

Slide 8 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) kintoneのフロントエンド刷新 サービスとプロジェクトの概要 • kintoneは、開発初期(2010年前後)の フロントエンド実装がレガシー化している • 根幹で採用されている「Google Closure Tools」を使える人がもはや僅少 • →2021年頃から脱レガシー(React + TypeScript化)に着手 • 今回取り上げる「アプリ」機能は2024年から着手 • ついでにUI/UXの改善にもトライ 8

Slide 9

Slide 9 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) 今回のターゲット:kintoneの「アプリ」機能 サービスとプロジェクトの概要 9 • 自由に作ったフォームを通じてデータをレコード単位で登録&閲覧&編集できる kintoneのメイン機能

Slide 10

Slide 10 text

10 ノーコードツールの フロントエンド

Slide 11

Slide 11 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) kintoneの「アプリ」 ノーコードツールのフロントエンド • 入力欄を二次元的に配置したフォームを自作して使える • 入力欄(=フィールド)→文字列、数値、日付など多数 11 入力欄 入力欄 入力欄 入力欄 入力欄 入力欄 溜めたデータの一覧 溜めた個別のデータ

Slide 12

Slide 12 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) 今回取り上げる例:レコード編集画面 ノーコードツールのフロントエンド 12 • あらかじめ作ったフォームの上で登録済データを編集する画面 どうやって作ってる?

Slide 13

Slide 13 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) レコード編集画面のフォームの構造 ノーコードツールのフロントエンド 13 • 基本的な構造は意外と単純で、フィールドを上&左詰めして配置 行(row) 行(row) 行(row) 行(row) 左詰め

Slide 14

Slide 14 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) レコード編集画面のフォームに使うもの ノーコードツールのフロントエンド 14 • バックエンドから次の三点セットをもらって駆使 レイアウト フィールドの配置情報を 二次元配列で保持 スキーマ 各フィールドの詳細情報 (入力規則など) 入力値 レコードに流し込むデータ →変換して状態管理する ※いずれも説明のため簡単にしています

Slide 15

Slide 15 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) レコード編集画面のフォームの作り方① ノーコードツールのフロントエンド 15 • レイアウトの二次元配列を回して、フィールドを縦横に配置 レイアウト フィールドの配置情報を 二次元配列で保持 1行目 2行目 名前 個数 200px 100px 日付

Slide 16

Slide 16 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) スキーマ 各フィールドの詳細情報 レコード編集画面のフォームの作り方② ノーコードツールのフロントエンド 16 • 各フィールドに対応するスキーマを読み込み、フィールドを肉付け 1行目 2行目 名前 [必須] 個数 [必須] テキスト入力欄 数値入力欄 [100まで] 日付 [必須] 日付入力欄 フィールドの照合には”レイアウト”と共通の フィールドIDを使う

Slide 17

Slide 17 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) 入力値 レコードに流し込むデータ →変換して状態管理する レコード編集画面のフォームの作り方③ ノーコードツールのフロントエンド 17 • このレコードの入力値(前回保存時の値)を流し込む 1行目 2行目 名前 [必須] 日付 [必須] 個数 [必須] テスト 太郎 2025-03-21 30 フィールドの照合には”レイアウト”と共通の フィールドIDを使う

Slide 18

Slide 18 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) レコード編集画面のフォームの作り方④ ノーコードツールのフロントエンド 18 • こうしてできあがる

Slide 19

Slide 19 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) レコード編集画面のフォームの保存方法① ノーコードツールのフロントエンド 19 • 入力値は常に状態管理している 1行目 2行目 名前 [必須] 日付 [必須] 個数 [必須] ボウズマン 1997-08-08 100 こんな感じのデータを保持

Slide 20

Slide 20 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) レコード編集画面のフォームの保存方法② ノーコードツールのフロントエンド 20 • その時点の値をAPIリクスエストに変換してバックエンドへ送る 保存 クリック! その時点の値 変換 APIリクエスト バックエンド へ送信

Slide 21

Slide 21 text

kintoneのmuddyポイント 21 中身は条件分岐だらけ!

Slide 22

Slide 22 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) さっきの例は単純だったけど… 中身は条件分岐だらけ! 22 • kintoneのアプリで使える フィールドの種類は実に多い • ラベル/文字列 (1行)/リッチエディター/ 文字列 (複数行)/数値/計算/ラジオボタン/ チェックボックス/複数選択/ドロップダウン/ 日付/時刻/日時/添付ファイル/リンク/ ユーザー選択/組織選択/グループ選択/ 関連レコード一覧/ルックアップ/スペース/ 罫線/グループ/テーブル/レコード番号/ 作成者/作成日時/更新者/更新日時 • 実は右以外にも フィールド扱いされる存在がある • カテゴリー/ステータス/作業者…など これ全部!

Slide 23

Slide 23 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) さっきの例は単純だったけど… 中身は条件分岐だらけ! 23 • 各フィールドで、見た目や保持すべきデータが大きく異なる

Slide 24

Slide 24 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) さっきの例は単純だったけど… 中身は条件分岐だらけ! 24 • フィールドの種類ごとの条件分岐が たくさんある! • 各処理は「フィールド」と一括りにしたもののルー プで行われる • ループの中では、その都度フィールドの種類を 区別する必要がある • いつも20〜30分岐くらいある ←の上部を拡大

Slide 25

Slide 25 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) こんなところに条件分岐が(基本編) 中身は条件分岐だらけ! 25 • フィールドの配置 • フィールドの種類によって見た目が異なる フィールド 分岐

Slide 26

Slide 26 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) こんなところに条件分岐が(基本編) 中身は条件分岐だらけ! 26 • 状態の初期化 • フィールドの種類によって 持つべきデータが異なる • APIのリクエストの組み立て • フィールドの種類によって 送るべきデータが異なる フィールド 分岐 フィールド 分岐

Slide 27

Slide 27 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) こんなところに条件分岐が(その他の機能編) 中身は条件分岐だらけ! 27 • “テーブル”フィールドの中身の配置 • kintoneにはフィールドの中にフィールドがある場面が少なくない • テーブル内の列もフィールドの種類によって見た目が異なる • “関連レコード一覧”テーブルの中身の配置 • これもフィールドの中にフィールドがある場面の1つ • テーブル内の列もフィールドの種類によって見た目が異なる • フィールド間のコピー機能の変換処理 • kintoneが持つ機能(”ルックアップ”機能)の中で登場 • フィールドの種類によってコピーできるフィールドが異なる ラジオボタン ラジオボタン ラジオボタン 文字列 ラジオボタン 数値

Slide 28

Slide 28 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) こんなところに条件分岐が(その他の画面編) 中身は条件分岐だらけ! 28 • レコード一覧テーブルの中身の配置 • フィールドの種類によって見た目が異なる • レコードを絞り込むやつ • フィールドの種類によって(以下略) • レコード詳細画面のアレコレ • フィールドの種類によって(以下略) • などなど…

Slide 29

Slide 29 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) こんなところに条件分岐が(結果) 中身は条件分岐だらけ! 29 15 以上 20択以上ある条件分岐の数 ※私のチームが手がけるコードの範囲内のみ

Slide 30

Slide 30 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) フィールドの数と同じくTypeScriptの型の数も膨大に! 中身は条件分岐だらけ! 30 • フィールドの種類によってデータが異なる→型も異なる • ↓こういうのが無数にある 各フィールドの型 各フィールドの型のUnion型 主に条件分岐した後で使う 主に条件分岐する前で使う

Slide 31

Slide 31 text

31 怒涛の条件分岐と型を捌くために やってること

Slide 32

Slide 32 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) vs. 条件分岐|switch文のcaseの並び順の整序 怒涛の条件分岐と型を捌くためにやってること 32 • 大量にcase句があるswitch文あるある:特定の条件を探すのが大変 • →case句が文字列リテラルならばABC順に揃えるESLintプラグインを導入 • eslint-plugin-switch-case-order • チームメンバーが作ってくれました • 詳細はZennの記事としてまとめられています • https://zenn.dev/cybozu_frontend/articles/my-first-eslint-custom-rule

Slide 33

Slide 33 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) vs. 条件分岐| switch文の代わりにオブジェクトを使う 怒涛の条件分岐と型を捌くためにやってること 33 • 条件が整えばオブジェクトを使うとわかりやすい • 全条件で入力(引数・props)が大きく変わらないときに使える コンポーネントもいける 一般的な関数

Slide 34

Slide 34 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) vs. 型| 「判別可能なUnion型」の活用 怒涛の条件分岐と型を捌くためにやってること 34 • これを使ってデータを管理するのが前提になる! • 判別可能なUnion型:共通のキーで各型を特定できるUnion型 • TypeScriptは賢いので 条件分岐後に 型を絞ってくれる 束ねる たくさんの型で unionしているが、 `type`の値を見れば この中のどの型か分かる

Slide 35

Slide 35 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) vs. 型| Extract×ジェネリクス型でよりシンプルに使えることも① 怒涛の条件分岐と型を捌くためにやってること 35 • Extractの「U」は 文字列リテラルでなくても良いのを知ってますか? よくある例 オブジェクトの一部でも絞れる! 一部のプロパティ(`type`)の値で絞れる

Slide 36

Slide 36 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) vs. 型| Extract×ジェネリクス型でよりシンプルに使えることも② 怒涛の条件分岐と型を捌くためにやってること 36 • Unionを構成する全ての型を個別に使いたいが、全部個別にexportせずとも、 ある1つだけを代表してexportするシンプルな形態にできる 全てexport Exportを1つにまとめる この1つだけをexport つぶしが効く存在になる

Slide 37

Slide 37 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) vs. 型|使い勝手の良いアサーション関数を作る① 怒涛の条件分岐と型を捌くためにやってること 37 • 先述したレイアウト・スキーマ・入力値など、 色んなデータでフィールド種別の特定が求められるkintone開発の現場では、 型を効率的に絞るニーズが強い • アサーション関数:無事`return`されたら型が特定される関数

Slide 38

Slide 38 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) vs. 型|使い勝手の良いアサーション関数を作る② 怒涛の条件分岐と型を捌くためにやってること 38 • ジェネリクスを組み合わせると使い勝手が良くなる ①最初の時点ではprops`fieldValue`が どのフィールド種別の型か分からない ②`assert〜`関数の第二引数に与えた フィールド種別の型かどうか判定する ③`assert〜`関数で例外が投げられず ここまでこれたので、型が絞られた

Slide 39

Slide 39 text

39 まとめ

Slide 40

Slide 40 text

ノーコードツールの裏側につきまとう「20分岐」との戦い - おぐえもん(小倉 且也) まとめ まとめ • ノーコードツール・kintoneの裏側には怒涛の条件分岐が蔓延っている • その多くが、20以上あるフィールド種別ごとに処理を分岐するためのもの • フィールド種別による条件分岐を扱いやすくするための いくつかの試みを紹介した • ESLintプラグインの導入/条件分岐の方法/TypeScriptの効率的な型運用 • なんやかんやで、全部に通じる上手い方法は見つかってません!涙 • 今後も色んなアイデアを取り入れていこうと思います 40

Slide 41

Slide 41 text

©️ Cybozu, Inc. 41