
2025.03.19
ドバイ不動産投資の最前線 専門家が語る、3つの投資モデルと市場の展望
Monolith→MultiRepo→MonoRepoにいく上でのリポジトリ戦略(全1記事)
リンクをコピー
記事をブックマーク
松本宏太氏:「Monolith→MultiRepo→MonoRepoにいく上でのリポジトリ戦略」ということでSCOUTERの「@kotamat」が登壇したいと思います。
SCOUTERの紹介ですが、転職回りのサービスを展開しています。
「SCOUTER」はエージェントを誰でもできるようにするサービスです。
他には「SARDINE」というサービスをやっているんですが、これは実際にエージェント業をやっている企業向けの業務管理ツールです。
あとは現在事前登録中ですが「back check」という、面接や履歴書ではわからない転職者のリファレンスチェックサービスをやっていたりします。
基本的に、弊社はずっとLaravelとVueでやってきていて、そのあたりの話をさせていただ来たいと思います。
今回はLaravelとVueの話は出てきません(笑)。
今日しゃべる内容としては、この「リポジトリ戦略って何?」と、「どういう戦略を今までとってきたのか?」という部分の紹介と、実際の事例、メリット・デメリットといった話をしたいと思います。
「リポジトリ戦略とは?」から説明させていただきます。弊社の場合関連するユーザーがすごく多く、四すくみになっているパターンが多かったりして、それぞれがデータをやりとりする仕組みになっています。
以前「LaravelとNuxt.jsを同一レポジトリで管理する」という内容で登壇しておりましたが、やはりそれぞれのユーザーで同じドメインの処理の編集が発生するので、その領域の責務を凝縮しようと思ったときに、それぞれユーザーのリポジトリとドメインのリポジトリを分割する、みたいなことをこの前のLaravelのカンファレンスで話をしました。
これ見ていただくと線が多くて複雑な感じになっているのですが、こういう背景があったので、コードベースの拡大に伴って重複コードの扱いが大変になってきたという課題がありました。
弊社ではリポジトリ戦略をいくつか取り入れてきており、最初はこのMonolithから始まって、MultiRepoから、今はMonoRepoを検討しているような状況です。「これ何なんだろう?」ということを調べていくなかでわかったことを共有したいと思っております。
「Monolithicって何?」というところに関して。いわゆる一般的な構成かなと思います。Monolithicという命名が正しいかどうかはわかりませんが、いわゆるLaravelのアプリケーションを初期インストールするときに、LaravelのComposerのcreate appみたいな感じで入れたときのデフォルトの構成です。
そうすると、ちょっと小さいですがappとか、composer.jsonだったり、package.jsonがあって。appの中にいろいろなコードが入ってたりとか、publicの中にstaticなものが入ってたりとか、なんかいろいろ入っています。
先ほどお話した関連するユーザーが多いよところに関して、各アプリケーションで当時発生した問題としては、複数のアプリケーションでコードをシェアできないという問題が発生しました。
重複するコードがそれぞれのアプリに記述されて、例えばユーザーの取得処理がそれぞれに記述されたり、求人データの取得が、それぞれを編集しないといけない感じで、1個の機能をリリースするたびにいろいろなリポジトリを参照していました。
機能の変更に伴って各アプリケーションのコードを変更しなければならないため、過去のコードがどうしても残ってしまうということが発生していたので、その後MultiRepoという戦略をとりました。
これは何かというと、共通しているコードをパッケージ化します。重複しているコードは単一パッケージの中で管理して、それをcomposerやnpmが、LaravelやVueは対応していると思いますが、これのリポジトリでバージョン管理をしてやっていくみたいな構成にしました。
同じような構成ではありますが、例えばnode_modulesの中に、@babelと一緒にうちの@scouterincが、jobやselectionやstylebookがそれぞれ依存してたりとか。あとvendorの中にはPHP用のものが依存してたりという感じになっています。
これ、一見よさそうだなと思ってこの前もLaravelのカンファレンスで発表してたんですが、質問でも「これ、変更するの大変じゃないですかね?」という質問をされて「そうですね」という話になりました。
やっぱりこの開発手順はとても煩雑でした。
レビューする前は、子どものパッケージを更新して、子どものパッケージをdevビルドでpublishしてから、親パッケージをdevブランチにターゲットし、親パッケージをpushしてレビューください、みたいな感じになってしまいました。
リリースする前は、子どものパッケージのバージョンをセマンティックバージョンに編集して、それをpublishしてから、親をセマンティックバージョンに修正して、親をpublishすると。
「ダイヤモンド依存関係の闇」というものがあるのですが、ABCDという依存があったときに、BとCがDに依存していて、Bの更新頻度高いと、D.1が例えばVueだったときに、2.6に上がっていて、Cは2.3のままみたいな感じで、「Aって何のVueのバージョンを参照してるの?」みたいな感じで闇になるということが発生します。
大手企業ではこういったことが発生してきているので、最近ではありますが、MonoRepoという考え方がメジャーになってきました。
思想としては「1つのリポジトリに全部完結させる」というもので、パッケージの概念は今までどおり残りながら、Gitのリポジトリは1つにします。ルートのアプリケーションは、先ほど言った企業側のアプリケーションも1つのパッケージとして扱って、全部リポジトリに入れます。
構造としてはこんな感じになっていて、package1とかpackage2とかがそれぞれcomposer.jsonとかpackage.jsonを持っていながら、ルートのところにもcomposer.jsonとかpackage.jsonがある形になっています。
ルートのほうには全体のパッケージ、例えばVueとか、それぞれがVueに依存しているのでそういうところを入れつつ、パッケージごとの細かい依存はこっちに入っているみたいな感じになっています。
モノリポ化をすることによって解決できることにはこのようなことがあると思います。
バージョンが単一化させれてダイヤモンド依存の解決ができるところだったり、コードの共有のところ、例えばstylebookとか、そういうところをいろいろなリポジトリで広範囲に適用できたり。あとは依存性の管理が簡潔になったり、全体に波及する部分的な変更が容易になります。
あとは、大規模なリファクタリングやモダン化をするためのツールがだんだん作れるようになったり、ほかのチームとの連携が柔軟性が増したり連携できるようになります。
ちょっと紹介すると、依存性管理の簡潔化で、もはやセマンティックバージョンを管理するのは不要になります。都度都度のテストを通れば最新を使うようにすればいいです。
OSSとかは、外部に公開するパッケージに関しては、バージョンを切っていたりします。Laravelだと「illuminate/」というパッケージがRead Onlyのリポジトリで公開されたり、Babelだと「@babel/babel/」が公開されています。
あとは、すべてのパッケージにまたがる機能の名前空間を変えようと思ったときに、例えば「job」を「jobs」にすると、この変更自体はむちゃくちゃ簡単なんですが、すべてのパッケージがそれを依存していて、それぞれを変えているとめちゃくちゃ時間かかったりします。
1つのGitのリポジトリになるので1つのcommitで全部変えられます。こうすることで一斉置換してもテストは落ちないので、一気にリファクタリングができます。
あと、うちはまだやらないとは思いますが、Googleなんかはコードの解析をやっていて。どういう変更がバグになりそうかを機械学習したり、どういう言語がどこのプロジェクトで使われているかとか、脆弱性のパッチの適用が、1つのリポジトリで管理すると可視性が高くなり、やりやすくなります。
あとは、チーム間でいろいろなリポジトリを使っていて、1つの機能を作るにあたっても様々なパッケージに依存しなきゃいけない場合、例えばこれで言うと、求人と管理者がそれぞれのチームで使っていて依存していますが、1つの施策ごとのプルリクを作れるようになるので、境界がすごく柔軟に変えられたりします。
「デメリットってあるの?」というところについては、1個目がやっぱりコードベースがでかくなるところです。
どうしてもコードベースが大きくなっちゃうので、そこはツールの導入や規則で防ぐ必要があると思っています。
Google製のツールでいうとBazelがあったり、変更のあったところだけをビルドして、テストして、デプロイするといったことをしたりとか、cloneするときは先頭だけ引っ張ってくるようにするといった工夫が必要になります。
また、依存性の解決が簡単になりすぎる問題を挙げられています。簡単に依存性を追加できるようになってしまうので、適当に「依存性入れようぜ」みたいな感じで追加されてしまう懸念があります。最低限の依存だけに絞っていて、「このAPIはここでしか使われないよ」みたいなことを明示しないと、よりまたカオスになります。
あと、コードが社内に公開されてしまいます。1つのGitのリポジトリになるので全部見えちゃうんですけど、オープンな会社の社風じゃないとそもそも入れられません。
「じゃあ実際どこで使っているの?」というと、いろいろな企業で使われています。
OSSでいうと、VueだったらBabelに依存してたりとか、LaravelだったらSymfonyとかに依存していますがこれらはMonorepoで構成されており、Reactもこの構成です。
便利なツールの説明です、LaravelとVueに近しいところをちょっと紹介しようと思います。
「Lerna」はnpmのパッケージのモノリポに適したものになっていて、すべての一斉のpublishやコミット、pushが簡単にできます。既存のGit履歴もそのまま使えるメリットがあります。
あとは、Monorepo BuilderがSymplifyというオーガナイゼーションにあります。これはComposerベースのモノリポ化ツールで、親ディレクトリcomposer.jsonが自動生成されるんですが、コミットしないようにしてね、って書いてあったりします。これも一斉リリースができます。
あとは、Laravelのコアのところで使われているのが、このsplitsh/liteです。これはGoで作られているのですが、CLIベースでコードをディレクトリごとに分割して、Read Onlyなリポジトリにpushしてくれます。OSSでも分けたいニーズあったりするので、そういうところに使えたりします。
まとめです。
事業の特性として、この依存性がキーになってくるプロダクトでは一考の余地があるかなと思っています。うちのアプリだといろいろなパッケージを参照するので、そういうところでは割と使えるかなと思います。
あと、issueトラッカーがGitHubのissueに依存していると、そこらへんも影響されるので、開発フロー全体の設計をしっかり考えた上で導入を検討する必要があります。また、単一のリポジトリだけでいいようなプロジェクトで別にわざわざこんな構成にする必要はないなというところがまとめです。
SCOUTERではエンジニアを募集しているので、もし興味ある方いればお声がけいただければと思います。
以上です。駆け足でしたが、ありがとうございました。
(会場拍手)
関連タグ:
2025.03.17
不確実な時代だからこそ「知らないこと」を武器にする ハーバード主席卒業生の逆説的なメッセージ
2025.03.17
いくら読書をしても「成長しない人」が見落としていること 10分でできる「正しい学び方」
2025.03.17
ソフトバンクとOpenAIにとって「歴史的な日」になった 孫正義氏が語る、AI革命の全ぼう
2025.03.19
部下の「タスクの先延ばし」が少ない上司の特徴とは? 研究が示す、先延ばし行動を減らすリーダーの条件
2025.03.21
マネージャーの「自分でやったほうが早い」という行動で失うもの 効率・スピード重視の職場に足りていない考え方
2025.03.18
フェデラー氏が語る「努力しない成功は神話」という真実 ダートマス卒業生に贈る勝利の秘訣
2025.03.18
全知全能の最先端AI「Cristal」が企業の大脳となる ソフトバンク孫正義氏が語る、現代における「超知性」の可能性
2025.03.19
フェデラー氏が語る「ただの1ポイント」の哲学 ウィンブルドン敗北から学んだ失敗からの立ち直り方
2025.03.18
部下に「そうかなぁ?」と思われない1on1の問いかけ エンゲージメントを高めるマネジメントに欠かせない「聴く」技術
2025.03.19
OpenAIのAIエージェント「Deep research」はビジネスをどう変革するのか? サム・アルトマン氏ら4人がデモンストレーション
【手放すTALK LIVE#046】 出版記念イベント 『大きなシステムと小さなファンタジー』 一つ一つのいのちが大切にされる社会へ
2025.02.03 - 2025.02.03
「聴く」から始まる組織変革 〜篠田真貴子さんと考える対話型マネジメント〜
2025.02.14 - 2025.02.14
「目の前の利益を優先する」心理とは:ビジネスに活かせる意思決定の科学
2025.02.12 - 2025.02.12
新刊『組織をダメにするのは誰か?職場の問題解決入門』出版記念セミナー
2025.02.04 - 2025.02.04
会社の体質、これまでどおりで大丈夫? 職場に新たな風を吹き込むための「ネガティブ・ケイパビリティ」入門
2025.02.10 - 2025.02.10