モノリポジトリ内の共有ライブラリの実際の例

DDD
リリース: 2024-10-25 06:23:29
オリジナル
258 人が閲覧しました

A practical example of shared libraries in a monorepo

モノリポジトリでの作業の最も強力な側面の 1 つは、パッケージ/チーム/階層間でコードを共有できることです。この投稿では、非常に単純な現実世界のシナリオを説明していきます

シナリオ例

モノリポジトリの他の部分に役立つと思われるファイル サイズをメガバイト単位で表示するライブラリを開発したいと想像してください。ライブラリはサイズを整数 (例: 2048 バイト) として受け入れ、人間化された文字列 (例: 2 MB) を返すことができます。品質保証を追加するために、同じためのテストも作成します。

Bazel はどのようにしてコードの共有を可能にしますか?

上記のシナリオから、この関数を共有ライブラリとして開発し、使用するために別のパッケージによってインポートする必要があることがわかりました。 Bazel では、ライブラリ内で関数を定義し、それを必要とする他のサービスにエクスポートできるため、これが非常に簡単になります。この投稿の下部にリンクされている以前の投稿で説明したように、他のどのライブラリがそれをインポートして使用できるようにするかを制御することもできます。

コーディングを始めましょう

コードを整理するために、ワークスペースのルートにライブラリ ディレクトリを作成し、そこにライブラリ コードを記述する humanize_filesize という子ディレクトリを作成します。

humanize_filesize.go に非常に初歩的な Go コードを書いてみましょう

package humanize_filesize

import "fmt"

// GetHumanizedFilesize takes size_in_bytes as an int32 pointer and returns the size in megabytes.
func GetHumanizedFilesize(size_in_bytes *int32) string {
    if size_in_bytes != nil {
        size_in_megabytes := float64(*size_in_bytes) / (1024 * 1024)
        return fmt.Sprintf("%.4f MB", size_in_megabytes)
    }
    return "0 MB"
}
ログイン後にコピー
ログイン後にコピー

このコードは単に int32 を入力として受け取り、計算された読み取り可能なメガバイト文字列を 40 進精度で返します

この機能は決して包括的ではなく、間違いなく改善の余地がありますが、それがこの演習のポイントではありません。

また、ロジックが意図したとおりに動作していることを確認します。humanize_filesize_test.go というファイルに go コードと一緒に非常に基本的なテストを追加します

package humanize_filesize

import (
    "testing"
)

func TestHumanizeFilesize(t *testing.T) {
    tests := []struct {
        name          string
        size_in_bytes *int32
        expected      string
    }{
        {
            name:          "nil bytes",
            size_in_bytes: nil,
            expected:      "0 MB",
        },
        {
            name:          "2048 bytes",
            size_in_bytes: int32Ptr(2048),
            expected:      "0.0020 MB",
        },
        {
            name:          "0 bytes",
            size_in_bytes: int32Ptr(0),
            expected:      "0.0000 MB",
        },
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := GetHumanizedFilesize(tt.size_in_bytes)
            if result != tt.expected {
                t.Errorf("expected %s, got %s", tt.expected, result)
            }
        })
    }
}

func int32Ptr(n int32) *int32 {
    return &n
}
ログイン後にコピー
ログイン後にコピー

入力として nil、int32、0 の基本テストを行う非常に単純なテスト

ここからは、この関数をエクスポートして他のパッケージまたはサービス内にインポートできるようにする方法の重要な部分に入ります。ここで BUILD.bazel ファイルを定義する必要があります。

load("@rules_go//go:def.bzl", "go_library", "go_test")

go_library(
    name = "humanize_filesize",
    srcs = ["humanize_filesize.go"],
    importpath = "basil/libraries/humanize_filesize",
    visibility = ["//visibility:public"],
)

go_test(
    name = "humanize_filesize_test",
    srcs = ["humanize_filesize_test.go"],
    embed = [":humanize_filesize"],
)
ログイン後にコピー
ログイン後にコピー

ここでは 2 つの主要なルールを定義します。 1 つは実際のライブラリ用で、もう 1 つは私たちが作成したテスト ファイル用です。

go_library は、ターゲットの humanize_filesize が、importpath で指定されたパスによってインポートできるソースの 1 つとして humanize_filesize.go を使用することを定義し、インポートする他のパッケージのワークスペース内で公開されます。可視性を制御する方法については、今後の投稿で学びます。

go_test は、go_library の出力からコードを埋め込むテスト ターゲットを定義します。

この時点で、次のようにテスト スイートを実行してライブラリをテストできるはずです

bazel ビルド //... && bazel 実行 //libraries/humanize_filesize:humanize_filesize_test

次のようなテスト出力が表示され、すべてのテストが成功したことがわかります。

package humanize_filesize

import "fmt"

// GetHumanizedFilesize takes size_in_bytes as an int32 pointer and returns the size in megabytes.
func GetHumanizedFilesize(size_in_bytes *int32) string {
    if size_in_bytes != nil {
        size_in_megabytes := float64(*size_in_bytes) / (1024 * 1024)
        return fmt.Sprintf("%.4f MB", size_in_megabytes)
    }
    return "0 MB"
}
ログイン後にコピー
ログイン後にコピー

?うわー!! ?これで、ライブラリが意図したとおりに動作していることがわかりました。

次に、次の go コードと BUILD.bazel ファイルを使用してワークスペースのルートに作成するサービス ディレクトリ内のサービス service1 でこのライブラリを使用しましょう。

service1.go

package humanize_filesize

import (
    "testing"
)

func TestHumanizeFilesize(t *testing.T) {
    tests := []struct {
        name          string
        size_in_bytes *int32
        expected      string
    }{
        {
            name:          "nil bytes",
            size_in_bytes: nil,
            expected:      "0 MB",
        },
        {
            name:          "2048 bytes",
            size_in_bytes: int32Ptr(2048),
            expected:      "0.0020 MB",
        },
        {
            name:          "0 bytes",
            size_in_bytes: int32Ptr(0),
            expected:      "0.0000 MB",
        },
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := GetHumanizedFilesize(tt.size_in_bytes)
            if result != tt.expected {
                t.Errorf("expected %s, got %s", tt.expected, result)
            }
        })
    }
}

func int32Ptr(n int32) *int32 {
    return &n
}
ログイン後にコピー
ログイン後にコピー

BUILD.bazel

load("@rules_go//go:def.bzl", "go_library", "go_test")

go_library(
    name = "humanize_filesize",
    srcs = ["humanize_filesize.go"],
    importpath = "basil/libraries/humanize_filesize",
    visibility = ["//visibility:public"],
)

go_test(
    name = "humanize_filesize_test",
    srcs = ["humanize_filesize_test.go"],
    embed = [":humanize_filesize"],
)
ログイン後にコピー
ログイン後にコピー

Go コードは非常に単純で、前に宣言したライブラリをインポートし、ライブラリから GetHumanizedFilesize 関数を使用してランダムな整数値を渡し、出力を出力します。

ここで bazel build //services/service1 を実行すると、bazel は開発したライブラリを含むターゲットのすべての依存関係を解決してビルドします。

バイナリ ターゲットが 1 つだけ定義されているため、bazel run //services/service1 を使用して service1 を実行できるようになります。複数のバイナリ ターゲット (例:serviceX) がある場合は、bazel run //services/service1:serviceX を使用してそれを実行できます。デフォルトでは、ターゲットを指定しない場合、bazel は常にディレクトリと同じ名前のバイナリ ターゲットを見つけて実行しようとします。

それで...それで。モノリポジトリの他の部分で使用できる最初の共有ライブラリを作成しました。

この例のすべてのコードは、https://github.com/nixclix/basil/pull/3/commits/61c673b8757860bd5e60eb2ab6c35f3f4da78c87 にあります

この投稿の内容が気に入ったら、お気軽に共有してください。また、この投稿についてのご意見や改善してほしい点がございましたら、購読してコメントを残してください。

以上がモノリポジトリ内の共有ライブラリの実際の例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!