ローコードサービスの進化のためのモノレポ移行
by
taro
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
ローコードサービスの進化のためのモノレポ移⾏ 2025-3-18 NEWT Tech Talk vol.15 サービスの成⻑に合わせたフロントエンドの進化 株式会社ベースマキナ ⼤⻄太郎(taro)
Slide 2
Slide 2 text
はじめに
Slide 3
Slide 3 text
モノレポ使っていますか?
Slide 4
Slide 4 text
モノレポを使う目的 ● 複数のマイクロサービスの⼀元管理 ● クライアント/サーバー間の型の共有 ● 複数のサービス間での関数や処理の共通化 などなど はじめに
Slide 5
Slide 5 text
モノレポを使う目的 ● 複数のマイクロサービスの⼀元管理 ● クライアント/サーバー間の型の共有 ● 複数のサービス間での関数や処理の共通化 などなど はじめに
Slide 6
Slide 6 text
Webクライアント APIサーバー リクエスト はじめに
Slide 7
Slide 7 text
Webクライアント APIサーバー リクエスト Node.jsクライアント リクエスト 新機能追加!! はじめに
Slide 8
Slide 8 text
Webクライアント APIサーバー リクエスト Node.jsクライアント リクエスト モノレポで処理を共通化したい! はじめに
Slide 9
Slide 9 text
目次 ● ⾃⼰紹介&サービス紹介 ● モノレポ移⾏の背景 ● モノレポの構成 ● モノレポ移⾏の流れ ● モノレポで共通化しているもの ● まとめ ⽬次
Slide 10
Slide 10 text
自己紹介 ● ⼤⻄太郎 ● taro( @taroro_tarotaro) ● 株式会社ベースマキナのソフトウェアエンジニア ● ローコードで管理画⾯を作れるサービスを作ってます ⾃⼰紹介
Slide 11
Slide 11 text
リクエストの情報を設定 APIやDBを呼び出す フォームが出来る! サービス紹介 設定画⾯ 実⾏画⾯
Slide 12
Slide 12 text
モノレポ移⾏の背景
Slide 13
Slide 13 text
Webクライアント APIサーバー リクエスト Node.jsクライアント リクエスト モノレポで処理を共通化したい! モノレポ移⾏の背景
Slide 14
Slide 14 text
リクエストの情報を設定して、 APIを呼び出す処理を作成 フォームから実⾏! 設定画⾯ 実⾏画⾯ モノレポ移⾏の背景
Slide 15
Slide 15 text
フォームで実⾏していた処理を JavaScriptから実⾏できる機能を追加! モノレポ移⾏の背景
Slide 16
Slide 16 text
事前に作成した APIやSQLを呼び出す処理の実⾏ JavaScriptでワークフローを作成できる機能 モノレポ移⾏の背景
Slide 17
Slide 17 text
事前に作成した APIやSQLを呼び出す処理の実⾏ JavaScriptでワークフローを作成できる機能 モノレポ移⾏の背景 アクション ※重要な機能で以降の 話で何度か登場します
Slide 18
Slide 18 text
モノレポ移⾏の背景 フォームで実⾏していたアクションを JavaScriptから実⾏する機能が追加!
Slide 19
Slide 19 text
Webクライアント APIサーバー アクション実⾏ リクエスト Node.jsクライアント ワークフローの JSコードの実⾏環境 モノレポ移⾏の背景
Slide 20
Slide 20 text
Webクライアント APIサーバー Node.jsクライアント 同じ機能の別環境のクライアント間 のモノレポの話 アクション実⾏ リクエスト モノレポ移⾏の背景
Slide 21
Slide 21 text
モノレポの構成
Slide 22
Slide 22 text
root/ ├─ packages/ │ ├─ web/ # Webクライアント │ ├─ js-executor/ # Node.jsクライアント │ └─ lib/ # 共有ライブラリ ├─ pnpm-workspace.yaml └─ package.json モノレポの構成 モノレポの構成
Slide 23
Slide 23 text
モノレポ移⾏の流れ
Slide 24
Slide 24 text
① モノレポのキャッチアップ ② Webクライアントのみのモノレポに移⾏ ③ 開発ツールの設定をモノレポに移⾏ ④ Node.jsクライアントを追加 ⑤ 順番に共有ライブラリに移⾏する モノレポ移行の流れ モノレポ移行の流れ
Slide 25
Slide 25 text
モノレポ移行の流れ モノレポ移行の流れ ① モノレポのキャッチアップ ② Webクライアントのみのモノレポに移⾏ ③ 開発ツールの設定をモノレポに移⾏ ④ Node.jsクライアントを追加 ⑤ 順番に共有ライブラリに移⾏する
Slide 26
Slide 26 text
● pnpmのWorkspaceのドキュメント ○ pnpm.io/workspaces ● Turborepoのガイド(おすすめ) ○ turbo.build/repo/docs/crafting-your-repository ○ ⼀般的なモノレポの構成のことがだいたいわかる ○ Next.jsのstandaloneでのDockerfileとかも書いてある ○ (結局Turborepoは使ってないけど…) モノレポのキャッチアップ モノレポ移行の流れ
Slide 27
Slide 27 text
モノレポ移行の流れ モノレポ移行の流れ ① モノレポのキャッチアップ ② Webクライアントのみのモノレポに移⾏ ③ 開発ツールの設定をモノレポに移⾏ ④ Node.jsクライアントを追加 ⑤ 順番に共有ライブラリに移⾏する
Slide 28
Slide 28 text
root/ ├─ packages/ │ ├─ web/ ├─ pnpm-workspace.yaml └─ package.json root/ ├─src/ │ ├─features/ │ ├─pages/ └─ Dockerfile └─ tsconfig.json └─ next.config.js └─ package.json 移⾏前 移⾏後 稼働中のアプリかつ他の開発ライ ンも動いているので、できるだけ 影響を⼩さく段階的に移⾏した モノレポ移行の流れ
Slide 29
Slide 29 text
root/ ├─ packages/ │ ├─ web/ ├─ pnpm-workspace.yaml └─ package.json root/ ├─src/ │ ├─features/ │ ├─pages/ └─ Dockerfile └─ tsconfig.json └─ next.config.js └─ package.json 移⾏前 移⾏後 src/配下は差分なし それ以外の差分も、ほぼパスに packages/webをつけるだけ モノレポ移行の流れ
Slide 30
Slide 30 text
モノレポ移⾏の流れ npm scriptsも⼀旦今まで同様に動くようにして、 モノレポが⼀通り整うまでは 他のメンバーがこれまでと同じ⽅法で開発できる状態を維持 rootのpackage.json
Slide 31
Slide 31 text
差分のほとんどがlockファイルで、 それ以外もほぼパスにpackages/webがついただけで、 あんまり怖がらずにデプロイできた! モノレポ移行の流れ
Slide 32
Slide 32 text
モノレポ移行の流れ モノレポ移行の流れ ① モノレポのキャッチアップ ② Webクライアントのみのモノレポに移⾏ ③ 開発ツールの設定をモノレポに移⾏ ④ Node.jsクライアントを追加 ⑤ 順番に共有ライブラリに移⾏する
Slide 33
Slide 33 text
● tsconfig ● Jest(当時、今はVitest) ● ESlint ● GraphQL Codegen ● GitHub Actions を共通化できる形式に移⾏(詳細は割愛) 開発ツールの設定をモノレポに移行 モノレポ移行の流れ
Slide 34
Slide 34 text
モノレポ移行の流れ モノレポ移行の流れ Node.jsクライアントの開発を進めつつ、 必要なものをWebクライアントから共有ライブラリに移動していった ① モノレポのキャッチアップ ② Webクライアントのみのモノレポに移⾏ ③ 開発ツールの設定をモノレポに移⾏ ④ Node.jsクライアントを追加 ⑤ 順番に共有ライブラリに移⾏する
Slide 35
Slide 35 text
root/ ├─ packages/ │ ├─ web/ # Webクライアント │ ├─ js-executor/ # Node.jsクライアント │ └─ lib/ # 共有ライブラリ ├─ pnpm-workspace.yaml └─ package.json モノレポの構成 モノレポの構成
Slide 36
Slide 36 text
モノレポの構成 root/ ├─ packages/ │ ├─ web/ # Webクライアント │ ├─ js-executor/ # Node.jsクライアント │ └─ lib/ # 共有ライブラリ ├─ pnpm-workspace.yaml └─ package.json モノレポの構成 運⽤中のアプリでも 意外と簡単にモノレポ移⾏できた!
Slide 37
Slide 37 text
モノレポで共通化しているもの
Slide 38
Slide 38 text
● 特定の機能に依存しないもの ○ 汎⽤の定数、関数、型 ○ 開発ツールの設定(tsconfig, ESLint, etc.) ○ 外部ライブラリの初期化関数 ● 特定の機能に依存するもの ○ 「アクションの実⾏機能」に依存する処理 ○ 「ユーザーがコードを書く機能」に依存する処理 モノレポで共通化しているもの モノレポで共通化しているもの
Slide 39
Slide 39 text
● 特定の機能に依存しないもの ○ 汎⽤の定数、関数、型 ○ 開発ツールの設定(tsconfig, ESLint, etc.) ○ 外部ライブラリの初期化関数 ● 特定の機能に依存するもの ○ 「アクションの実⾏機能」に依存する処理 ○ 「ユーザーがコードを書く機能」に依存する処理 モノレポで共通化しているもの モノレポで共通化しているもの
Slide 40
Slide 40 text
Day.jsの初期化関数 外部ライブラリの初期化関数 ● 各クライアント ● テストのセットアップ で使う
Slide 41
Slide 41 text
モノレポで共通化しているもの モノレポで共通化しているもの ● 特定の機能に依存しないもの ○ 汎⽤の定数、関数、型 ○ 開発ツールの設定(tsconfig, ESLint, etc.) ○ 外部ライブラリの初期化関数 ● 特定の機能に依存するもの ○ 「アクションの実⾏機能」に依存する処理 ○ 「ユーザーがコードを書く機能」に依存する処理
Slide 42
Slide 42 text
① アクションの取得 ② 実⾏できるアクションか判定 ③ フォームの表⽰ ④ ⼊⼒値のバリデーション ⑤ APIサーバーへのリクエスト ⑥ 結果の表⽰ アクションの実行 Web 「アクションの実⾏機能」に依存する処理
Slide 43
Slide 43 text
アクションの実行 Node 「アクションの実⾏機能」に依存する処理 ① アクションの取得 ② 実⾏できるアクションか判定 ③ フォームの表⽰ ④ ⼊⼒値のバリデーション ⑤ APIサーバーへのリクエスト ⑥ 結果の表⽰
Slide 44
Slide 44 text
Web Node ①アクションの取得 「アクションの実⾏機能」に依存する処理 GraphQLでアクションの取得
Slide 45
Slide 45 text
Web Node ②実⾏できるアクションか判定 共通のisExecutableAction関数を使⽤ 「アクションの実⾏機能」に依存する処理
Slide 46
Slide 46 text
Lib
Slide 47
Slide 47 text
Lib GraphQL Fragment
Slide 48
Slide 48 text
https://graphql.org/ GraphQL
Slide 49
Slide 49 text
「アクションの実⾏機能」に依存する処理 Lib Node GraphQL Fragment query内で参照する
Slide 50
Slide 50 text
query内で参照する 「アクションの実⾏機能」に依存する処理 Lib Node Fragment Colocation 関数とその関数で必要な値のFragmentを ⼀緒に定義する
Slide 51
Slide 51 text
Node Web 各クライアントでlibの関数と⼀緒にFragmentを参照すると…
Slide 52
Slide 52 text
Node Web GraphQLのFragment Colocationを使うと、モノレポで 「関数」とその関数のためにサーバーから取得する情報まで 共通化できる!
Slide 53
Slide 53 text
Node 他の処理も、ほぼlibの関数と そのFragmentを使うだけ
Slide 54
Slide 54 text
Node モノレポとGraphQLのおかげで、ほぼ追加実装なしで Nodeクライアントからのアクション実⾏を追加できた!
Slide 55
Slide 55 text
モノレポで共通化しているもの モノレポで共通化しているもの ● 特定の機能に依存しないもの ○ 汎⽤の定数、関数、型 ○ 開発ツールの設定(tsconfig, ESLint, etc.) ○ 外部ライブラリの初期化関数 ● 特定の機能に依存するもの ○ 「アクションの実⾏機能」に依存する処理 ○ 「ユーザーがコードを書く機能」に依存する処理
Slide 56
Slide 56 text
「ユーザーがコードを書く機能」に依存する処理 Node
Slide 57
Slide 57 text
TODO アクションを実⾏する画⾯を JSXで作れる「ビュー」機能 Web
Slide 58
Slide 58 text
Node JavaScriptの実⾏環境は違うが、 関数でアクション実⾏などの ベースマキナの機能を呼ぶのは共通 Web
Slide 59
Slide 59 text
stringの引数に数値を渡してしまっている Node 「ユーザーがコードを書く機能」に依存する処理
Slide 60
Slide 60 text
引数の値を検証する zodのスキーマ Node Web 「ユーザーがコードを書く機能」に依存する処理
Slide 61
Slide 61 text
Lib
Slide 62
Slide 62 text
Lib zodのエラーを頑張って整形
Slide 63
Slide 63 text
● 関数の引数のバリデーション機構 「ユーザーがコードを書く機能」に依存する処理 「ユーザーがコードを書く機能」に依存する処理で、 モノレポで共通化しているもの
Slide 64
Slide 64 text
● 関数の引数のバリデーション機構 モノレポで共通化しているもの 「ユーザーがコードを書く機能」に依存する処理で、 モノレポで共通化 しているする予定のもの もうすぐ共通化を終わらせ て、ビュー機能でも同じ機構 が使えるようになる予定🙏
Slide 65
Slide 65 text
モノレポで共通化しているもの モノレポで共通化しているもの ● 特定の機能に依存しないもの ○ 汎⽤の定数、関数、型 ○ 開発ツールの設定(tsconfig, ESLint, etc.) ○ 外部ライブラリの初期化関数 ● 特定の機能に依存するもの ○ 「アクションの実⾏機能」に依存する処理 ○ 「ユーザーがコードを書く機能」に依存する処理
Slide 66
Slide 66 text
モノレポで共通化しているもの 別環境のクライアント間のモノレポだと、 ⼤きい(機能)単位で、処理を共通化できて嬉しい!
Slide 67
Slide 67 text
モノレポで共通化しているもの 別環境のクライアント間のモノレポだと、 ⼤きい(機能)単位で、処理を共通化できて嬉しい! 共通で使える実装にするのを、実は結構がんばってる🔥 (単位が⼤きい分、⾊々複雑で難しかったりする…)
Slide 68
Slide 68 text
まとめ
Slide 69
Slide 69 text
● 運⽤中のアプリでも、意外とさくっとモノレポ始められた ● GraphQLだと関数と⼀緒に取得する情報も共通化できて嬉 しい ○ モノレポとGraphQL Fragment Colocationはいいぞ ● 別環境のクライアント間のモノレポだと、機能単位で処理 を共通化できる(できるように頑張ってる🔥) まとめ まとめ
Slide 70
Slide 70 text
ありがとうございました! (ぜひベースマキナ使ってください!!)