ホームページ バックエンド開発 Golang モノリポジトリ内の共有ライブラリの実際の例

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

Oct 25, 2024 am 06:23 AM

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 サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Golang vs. Python:パフォーマンスとスケーラビリティ Golang vs. Python:パフォーマンスとスケーラビリティ Apr 19, 2025 am 12:18 AM

Golangは、パフォーマンスとスケーラビリティの点でPythonよりも優れています。 1)Golangのコンピレーションタイプの特性と効率的な並行性モデルにより、高い並行性シナリオでうまく機能します。 2)Pythonは解釈された言語として、ゆっくりと実行されますが、Cythonなどのツールを介してパフォーマンスを最適化できます。

Golang and C:Concurrency vs. Raw Speed Golang and C:Concurrency vs. Raw Speed Apr 21, 2025 am 12:16 AM

Golangは並行性がCよりも優れていますが、Cは生の速度ではGolangよりも優れています。 1)Golangは、GoroutineとChannelを通じて効率的な並行性を達成します。これは、多数の同時タスクの処理に適しています。 2)Cコンパイラの最適化と標準ライブラリを介して、極端な最適化を必要とするアプリケーションに適したハードウェアに近い高性能を提供します。

ゴーを始めましょう:初心者のガイド ゴーを始めましょう:初心者のガイド Apr 26, 2025 am 12:21 AM

goisidealforforbeginnersandsutable forcloudnetworkservicesduetoitssimplicity、andconcurrencyfeatures.1)installgofromtheofficialwebsiteandverify with'goversion'.2)

Golang vs. C:パフォーマンスと速度の比較 Golang vs. C:パフォーマンスと速度の比較 Apr 21, 2025 am 12:13 AM

Golangは迅速な発展と同時シナリオに適しており、Cは極端なパフォーマンスと低レベルの制御が必要なシナリオに適しています。 1)Golangは、ごみ収集と並行機関のメカニズムを通じてパフォーマンスを向上させ、高配列Webサービス開発に適しています。 2)Cは、手動のメモリ管理とコンパイラの最適化を通じて究極のパフォーマンスを実現し、埋め込みシステム開発に適しています。

Golang vs. Python:重要な違​​いと類似点 Golang vs. Python:重要な違​​いと類似点 Apr 17, 2025 am 12:15 AM

GolangとPythonにはそれぞれ独自の利点があります。Golangは高性能と同時プログラミングに適していますが、PythonはデータサイエンスとWeb開発に適しています。 Golangは同時性モデルと効率的なパフォーマンスで知られていますが、Pythonは簡潔な構文とリッチライブラリエコシステムで知られています。

GolangとC:パフォーマンスのトレードオフ GolangとC:パフォーマンスのトレードオフ Apr 17, 2025 am 12:18 AM

GolangとCのパフォーマンスの違いは、主にメモリ管理、コンピレーションの最適化、ランタイム効率に反映されています。 1)Golangのゴミ収集メカニズムは便利ですが、パフォーマンスに影響を与える可能性があります。

パフォーマンスレース:ゴラン対c パフォーマンスレース:ゴラン対c Apr 16, 2025 am 12:07 AM

GolangとCにはそれぞれパフォーマンス競争において独自の利点があります。1)Golangは、高い並行性と迅速な発展に適しており、2)Cはより高いパフォーマンスと微細な制御を提供します。選択は、プロジェクトの要件とチームテクノロジースタックに基づいている必要があります。

Golang vs. Python:長所と短所 Golang vs. Python:長所と短所 Apr 21, 2025 am 12:17 AM

GolangisidealforBuildingsCalables Systemsduetoitsefficiency andConcurrency、Whilepythonexcelsinquickscriptinganddataanalysisduetoitssimplicityand vastecosystem.golang'ssignencouragesclean、readisinediteNeditinesinedinediseNabletinedinedinedisedisedioncourase

See all articles