Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Contoh praktikal perpustakaan kongsi dalam monorepo

Contoh praktikal perpustakaan kongsi dalam monorepo

DDD
DDDasal
2024-10-25 06:23:29257semak imbas

A practical example of shared libraries in a monorepo

Salah satu aspek yang paling berkuasa dalam bekerja dalam monorepo ialah keupayaan untuk berkongsi kod antara pakej/pasukan/hierarki. Dalam siaran ini saya akan cuba menerangkan senario dunia sebenar yang sangat mudah

Contoh Senario

Bayangkan anda ingin membangunkan perpustakaan untuk menunjukkan saiz fail dalam megabait yang anda rasa mungkin berguna untuk bahagian lain monorepo anda. Pustaka menerima saiz sebagai Integer (cth: 2048 bait) dan boleh mengembalikan rentetan yang dimanusiakan (cth: 2 MB). Untuk menambah beberapa jaminan kualiti, kami juga akan menulis ujian untuk perkara yang sama.

Bagaimanakah Bazel mendayakan kod perkongsian?

Daripada senario di atas, kami sedar bahawa kami perlu membangunkan fungsi ini sebagai perpustakaan kongsi yang kemudiannya diimport oleh pakej lain untuk kegunaan. Bazel menjadikannya sangat mudah dengan membenarkan kami mentakrifkan fungsi dalam perpustakaan dan mengeksportnya perkhidmatan lain yang memerlukannya. Seperti yang dijelaskan dalam catatan saya sebelum ini yang dipautkan di bahagian bawah catatan ini, kami juga boleh mengawal perpustakaan lain yang boleh dibenarkan mengimportnya untuk kegunaan juga.

Jom dapatkan pengekodan

Untuk tujuan organisasi kod, kami akan mempunyai direktori perpustakaan di akar ruang kerja kami dengan direktori kanak-kanak dipanggil humanize_filesize yang mana kami akan menulis kod perpustakaan kami.

Mari kita tulis beberapa kod Go yang sangat asas dalam humanize_filesize.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"
}

Kod ini hanya mengambil int32 sebagai input dan mengembalikan rentetan megabait yang boleh dibaca yang dikira kepada 4 ketepatan perpuluhan

Fungsi ini pastinya tidak menyeluruh dan pasti boleh dipertingkatkan, tetapi bukan itu maksud latihan ini.

Juga menegaskan bahawa logik kami berfungsi seperti yang dimaksudkan, kami akan menambah ujian yang sangat asas bersama kod go kami dalam fail yang dipanggil humanize_filesize_test.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
}

Ujian yang sangat mudah dengan ujian asas untuk nil, int32 dan 0 sebagai input

Kini datang bahagian menarik tentang cara mengeksport fungsi ini supaya ini boleh diimport dalam pakej atau perkhidmatan lain. Di sinilah kita perlu menentukan fail 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"],
)

Di sini kita mentakrifkan dua peraturan utama. Satu untuk pustaka sebenar dan satu untuk fail ujian yang kami tulis.

go_library mentakrifkan bahawa sasaran humanize_filesize menggunakan humanize_filesize.go sebagai salah satu sumbernya yang boleh diimport melalui laluan yang ditentukan dalam importpath dan ia boleh dilihat secara terbuka dalam ruang kerja untuk pakej lain untuk diimport. Kami akan belajar cara mengawal keterlihatan dalam siaran akan datang.

go_test mentakrifkan sasaran ujian yang membenamkan kod daripada output go_library.

Pada ketika ini, kami sepatutnya dapat menguji perpustakaan dengan menjalankan suite ujian kami seperti berikut

binaan bazel //... && larian bazel //libraries/humanize_filesize:humanize_filesize_test

Anda sepatutnya dapat melihat output ujian seperti berikut yang menunjukkan bahawa semua ujian telah lulus.

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"
}

? Wohoo!!! ? Kini kami tahu bahawa perpustakaan kami berfungsi seperti yang diharapkan.

Sekarang mari kita gunakan perpustakaan ini dalam perkhidmatan perkhidmatan1 dalam direktori perkhidmatan yang akan kita cipta pada akar ruang kerja dengan kod go berikut dan fail BUILD.bazel.

perkhidmatan1.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
}

BINA.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"],
)

Kod go adalah agak mudah yang mengimport pustaka kami yang kami nyatakan sebelum ini dan menggunakan fungsi GetHumanizedFilesize daripada pustaka kami dan melepasi nilai integer rawak dan mencetak output.

Sekarang apabila melaksanakan binaan bazel //services/service1 , bazel akan menyelesaikan semua kebergantungan untuk sasaran kami termasuk perpustakaan yang kami bangunkan dan membinanya.

perkhidmatan1 kini boleh dilaksanakan menggunakan bazel run //services/service1 kerana kami hanya mempunyai satu sasaran binari yang ditentukan. Jika anda mempunyai lebih daripada satu sasaran binari, cth: serviceX, anda boleh melaksanakannya menggunakan bazel run //services/service1:serviceX. Secara lalai apabila tidak menyatakan sasaran, bazel akan sentiasa cuba mencari sasaran binari dengan nama yang sama dengan direktori dan menjalankannya.

Jadi... begitulah. Kami telah membuat perpustakaan kongsi pertama anda yang boleh digunakan oleh bahagian lain monorepo kami.

Semua kod untuk contoh ini boleh didapati di https://github.com/nixclix/basil/pull/3/commits/61c673b8757860bd5e60eb2ab6c35f3f4da78c87

Jika anda suka kandungan siaran ini, sila kongsikannya. Juga, sila langgan dan tinggalkan ulasan tentang pendapat anda tentang siaran ini dan jika ada perkara yang anda ingin lihat saya bertambah baik.

Atas ialah kandungan terperinci Contoh praktikal perpustakaan kongsi dalam monorepo. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn