モノレポは議論のホットトピックです。最近、プロジェクトでこのタイプのアーキテクチャを使用する必要がある理由と使用しない理由について多くの記事がありますが、それらのほとんどは何らかの形で偏っています。このシリーズは、モノリポジトリをいつどのように使用するかを理解するために、可能な限り多くの情報を収集して説明する試みです。
に モノリポジトリ は建築の概念であり、基本的にそのタイトルにすべての意味が含まれています。複数のリポジトリを管理する代わりに、分離されたすべてのコード部分を1つのリポジトリ内に保持します。言葉を覚えておいてください 孤立 —monorepoにはモノリシックアプリとの共通点がないことを意味します。 1つのリポジトリ内にさまざまな種類の論理アプリを保持できます。たとえば、WebサイトとそのiOSアプリ。
この概念は比較的古く、約10年前に登場しました。 Googleは、コードベースを管理するためにこのアプローチを採用した最初の企業の1つでした。それが10年間存在していたのなら、なぜ今だけそんなにホットな話題なのかと疑問に思うかもしれません。ほとんどの場合、過去5〜6年の間に、多くのことが劇的な変化を遂げました。 ES6、SCSSプリプロセッサ、タスクマネージャー、npmなど。現在、小さなReactベースのアプリを維持するには、プロジェクトバンドラー、テストスイート、CI / CDスクリプト、Docker構成、および他に何を知っているかを処理する必要があります。そして今、小さなアプリの代わりに、多くの機能領域で構成される巨大なプラットフォームを維持する必要があると想像してください。アーキテクチャについて考えている場合は、主に2つのことを行う必要があります。関心の分離とコードの重複の回避です。
これを実現するには、大きな機能をいくつかのパッケージに分離してから、メインアプリの単一のエントリポイントを介してそれらを使用することをお勧めします。しかし、これらのパッケージをどのように管理しますか?各パッケージには独自のワークフロー環境構成が必要です。つまり、新しいパッケージを作成するたびに、新しい環境を構成したり、すべての構成ファイルをコピーしたりする必要があります。または、たとえば、ビルドシステムで何かを変更する必要がある場合は、各リポジトリを確認し、コミットを実行し、プルリクエストを作成して、ビルドごとに待機する必要があります。これにより、処理速度が大幅に低下します。このステップで、私たちはモノレポに会っています。
独自の構成を持つ多くのリポジトリを用意する代わりに、信頼できる唯一の情報源、つまり、1つのテストスイートランナー、1つのDocker構成ファイル、およびWebpackの1つの構成のみを使用します。そして、スケーラビリティ、関心の分離の機会、共通パッケージとのコード共有、および他の多くの長所がまだあります。いいですね。そうですね。しかし、いくつかの欠点もあります。野生でモノレポを使用することの正確な長所と短所を詳しく見てみましょう。
Monorepo Advantages:
モノレポのデメリット:
大規模なプロジェクトで作業する場合のGitのパフォーマンスが低い。 この問題はにのみ表示され始めます 巨大 100万を超えるコミットと数百の開発者が同じリポジトリで毎日同時に作業を行っているアプリケーション。 Gitは有向非巡回グラフ(DAG)を使用してプロジェクトの履歴を表すため、これは特に厄介になります。コミット数が多いと、履歴が深くなるにつれて、グラフをウォークするコマンドが遅くなる可能性があります。参照の数(つまり、ブランチやタグ、不要になった参照を削除することで解決可能)と追跡されるファイルの量(および、重いファイルの問題は次の方法で解決できますが、その重み)により、パフォーマンスも低下します。 LFSに行く )。
注意: 現在、FacebookはVCSのスケーラビリティに関する問題を解決しようとしています Mercurialにパッチを適用する そして、おそらくすぐに、これはそれほど大きな問題にはならないでしょう。
モノリポジトリを管理するためのツールのセットは絶えず成長しており、現在、モノリポジトリのさまざまな構築システムのすべてで迷子になるのは非常に簡単です。あなたはいつでも使用することによって人気のある解決策を知ることができます このレポ 。しかし今のところ、JavaScriptで最近頻繁に使用されているツールを簡単に見てみましょう。
ほとんどのツールは非常によく似たアプローチを使用していますが、微妙な違いがあります。
この記事のパート2はかなり大きなトピックであるため、Lernaワークフローと他のツールについて詳しく説明します。とりあえず、中身の概要を見てみましょう。
このツールは、セマンティックバージョンの処理、ビルドワークフローの設定、パッケージのプッシュなどに非常に役立ちます。Lernaの背後にある主なアイデアは、プロジェクトにパッケージフォルダーがあり、そこにすべての分離されたコードパーツが含まれていることです。また、パッケージの他に、たとえばsrcフォルダーに配置できるメインアプリがあります。 Lernaのほとんどすべての操作は、単純なルールで機能します。すべてのパッケージを反復処理し、パッケージバージョンの増加、すべてのパッケージの依存関係の更新、すべてのパッケージのビルドなど、いくつかのアクションを実行します。
Lernaでは、パッケージの使用方法について2つのオプションがあります。
最初のアプローチを使用している間、パッケージにローカル参照を使用することができ、基本的にそれらを解決するためにシンボリックリンクを気にする必要はありません。
ただし、2番目のアプローチを使用している場合は、リモートからパッケージをインポートする必要があります。 (例:import { something } from @yourcompanyname/packagename;
)、これは、パッケージのリモートバージョンを常に取得することを意味します。ローカル開発の場合、node_modules/
内にあるパッケージを使用する代わりに、フォルダーのルートにシンボリックリンクを作成して、バンドラーにローカルパッケージを解決させる必要があります。そのため、Webpackまたはお気に入りのバンドラーを起動する前に、起動する必要があります lerna bootstrap
、すべてのパッケージを自動的にリンクします。
Yarnは当初、NPMパッケージの依存関係マネージャーであり、当初はモノリポジトリをサポートするように構築されていませんでした。しかし、バージョン1.0では、 糸開発者 と呼ばれる機能をリリースしました ワークスペース 。リリース時にはそれほど安定していませんでしたが、しばらくすると本番プロジェクトで使用できるようになりました。
ワークスペース 基本的には独自のパッケージです package.json いくつかの特定のビルドルールを持つことができます(たとえば、個別の tsconfig.json プロジェクトでTypeScriptを使用する場合)。実際には、bashを使用してYarn Workspacesなしで管理でき、まったく同じセットアップが可能ですが、このツールは、パッケージごとの依存関係のインストールと更新のプロセスを容易にするのに役立ちます。
一目で、Yarnとそのワークスペースは次の便利な機能を提供します。
node_modules
すべてのパッケージのルートにあるフォルダー。たとえば、packages/package_a
がある場合およびpackages/package_b
—独自のpackage.json
—すべての依存関係はルートにのみインストールされます。これは、YarnとLernaの動作の違いの1つです。-focus
を使用して実行できます。国旗。便利なリンク:
Bazelは、多言語の依存関係を処理し、多くの最新言語(Java、JS、Go、C ++など)をサポートできる大規模アプリケーション用のビルドツールです。ほとんどの場合、中小規模のJSアプリケーションにBazelを使用するのはやり過ぎですが、大規模な場合は、そのパフォーマンスのために多くのメリットが得られる可能性があります。
Bazelは、その性質上、Make、Gradle、Maven、およびビルドルールとプロジェクトの依存関係の説明を含むファイルに基づいてプロジェクトをビルドできるその他のツールに似ています。 Bazelの同じファイルは 構築する Bazelプロジェクトのワークスペース内にあります。ザ・ 構築する ファイルはそのを使用します スターラーク 、Pythonによく似た、人間が読める高レベルのビルド言語。
通常、あなたは多くを扱うことはありません 構築する Webで簡単に見つけることができ、すでに構成されて開発の準備ができている定型文がたくさんあるからです。プロジェクトをビルドするときはいつでも、Bazelは基本的に次のことを行います。
便利なリンク:
モノレポは単なるツールです。未来があるかどうかについては多くの議論がありますが、真実は、場合によっては、このツールがその仕事をし、効率的な方法でそれを処理するということです。過去数年の間に、このツールは進化し、柔軟性が大幅に向上し、多くの問題を克服し、構成の面で複雑なレイヤーを削除しました。
Gitのパフォーマンスの低下など、理解すべき問題はまだたくさんありますが、近い将来、これが解決されることを願っています。
アプリ用の堅牢なCI / CDパイプラインの構築方法を学びたい場合は、お勧めします GitLabCIを使用して効果的な初期デプロイメントパイプラインを構築する方法 。
関連: 強化されたGitフローの説明ソフトウェア開発におけるモノリシックアーキテクチャとは、アプリケーションを緊密に結合されたコンポーネント/機能のセットとして1つのピースに構成するアプローチを意味します。アプリの範囲外のコンポーネントを使用することはできません。
css用のスケーラブルでモジュラーなアーキテクチャ
リポジトリは、インストール/開発するためのソースコードを保存および取得する場所です。リポジトリは、関連するメタデータとともにすべてのバージョンのデータを保存します。これにより、履歴の改訂や、同じプロジェクトの個別の並列バージョンでの作業が可能になります。
疎結合コードは、他の場所で物事を壊すことを恐れずに変更を導入できるため、より信頼性が高いことが証明されています。これにより、開発がより安全になり、リファクタリングが簡素化されます。
シンボリックリンク(シンボリックリンク)は、実際のコンテンツではなく、相対パスまたは絶対パスの形式で元のフォルダー/ファイルを参照するファイルです。この場合、これらはパス名の適切な場所への解決に影響を与えるために使用されます。
最近、コードを個別のモジュールに分離する最も一般的な方法は、npmパッケージを使用することです(Yarnまたはnpmで実行できます)。それらは、独自の構成ファイルを含むフォルダーにラップされてから、リモートサーバーにプッシュされます。