Go Modules Packages Workspaces Dependency Management
Selesai membaca dokumentasi ini?
Kembali ke rujukan utama Go (Golang) untuk melanjutkan topik lainnya.
Kembali ke rujukan utama Go (Golang) untuk melanjutkan topik lainnya.
Di Go, satuan organisasi kode tidak cuma package. Ada beberapa lapis yang saling terkait:
go.mod.go.work.Kalau dipakai dengan sehat, empat lapis ini bikin codebase tetap mudah dinavigasi, build tetap deterministik, dan import path tidak berantakan.
Topik ini relevan saat kamu mulai melihat tanda-tanda berikut:
Package adalah cara Go mengelompokkan file .go yang dikompilasi bersama.
Struktur yang sehat bukan yang paling dalam, tapi yang paling mudah dipahami:
Contoh struktur yang lebih sehat:
myapp/
go.mod
cmd/
api/
main.go
internal/
auth/
service.go
token.go
billing/
service.go
storage/
postgres/
repo.go
pkg/
timeutil/
timeutil.gocmd/... untuk entrypoint aplikasi.internal/... untuk logic yang hanya boleh dipakai oleh module itu sendiri.pkg/... hanya kalau kamu memang ingin membentuk library publik yang stabil.utils, common, atau helpers kalau isinya mulai membesar dan bercampur.Kalau terjadi itu, pecah berdasarkan domain atau alur kerja, bukan berdasarkan jenis fungsi semata.
internal packageFolder internal dipakai untuk membatasi visibility di level import path.
internalKode di bawah folder internal hanya bisa di-import oleh package yang berada di dalam parent tree yang sama.
Contoh:
myapp/
internal/
auth/Package lain di dalam myapp/... bisa import myapp/internal/auth, tapi kode di luar tree module itu tidak bisa.
internal tepat dipakaiPakai internal untuk:
internalJangan pakai internal kalau:
internal sebagai “tempat buang” karena belum sempat menamai package dengan benarinternal bagus untuk kontrol boundary, tapi bukan pengganti desain package yang rapi.
go.mod sebagai sumber identitas dan versiSatu module biasanya dimulai dari file go.mod.
go.modContoh sederhana:
module example.com/myapp
go 1.22
require (
github.com/google/uuid v1.6.0
)Bagian paling penting:
module: import path utama module.go: versi bahasa Go yang jadi baseline untuk module itu.require: dependency langsung yang dipakai.replace dan exclude: override atau menolak versi tertentu saat diperlukan.go.modGo memakai go.mod untuk menentukan:
Yang sering dilupakan: module di go.mod harus cocok dengan import path yang dipakai orang untuk mengimpor package dari module itu.
Kalau tidak cocok, import path akan terasa “benar di folder, salah di resolusi”.
go.sum: jejak integritas dependencygo.sum menyimpan checksum untuk memastikan dependency yang diunduh tetap sama dengan yang sudah pernah diverifikasi.
go.sumKalau go.mod menentukan versi, go.sum membantu memastikan isi versi itu konsisten.
Secara praktis:
go.mod = daftar dan versigo.sum = bukti integritas isi dependencygo.sum manual.go yang memperbarui file ini.go.sum kecil pun bisa berarti graph dependency berubah.Go memakai pendekatan yang cenderung deterministik: version selection mengutamakan versi tertinggi yang dibutuhkan dalam graph, dengan beberapa aturan tambahan.
replace bisa mengubah sumber module untuk local development atau patch sementara.go.work)Workspace dipakai saat kamu ingin beberapa module lokal bekerja bersama tanpa harus merilis semuanya dulu.
go.workgo test atau go run memakai source lokal antar-modulego.work kalaureplace sementarago.work dan replacereplace mengubah dependency pada level satu module.go.work menggabungkan beberapa module lokal pada level workspace.go.work biasanya lebih bersih untuk dev experience di monorepo, karena tidak perlu memodifikasi go.mod hanya untuk pointer lokal.
go.mod sendiriIni salah satu jebakan paling umum.
Kalau module sudah v2, import path-nya harus membawa suffix /v2.
Contoh:
import "example.com/lib/v2"Bukan:
import "example.com/lib"Kalau tidak, Go akan menganggap itu module yang berbeda atau versi yang salah.
Kalau repo pindah domain atau org, import path yang lama bisa tetap hidup sementara melalui replace, tapi jangan anggap itu solusi permanen.
Yang perlu dicek:
module line di go.modGo mengandalkan tag seperti v1.2.3.
Jebakan umum:
v/v2module path belum disesuaikanKamu mungkin tidak mengubah dependency langsung, tapi dependency transitive bisa ikut naik karena requirement module lain.
Itulah kenapa build yang stabil perlu:
go.modgo.sumgo list -m all saat ada perilaku anehreplace sering bikin build lokal berbeda dari CIreplace berguna, tapi juga berbahaya kalau dibiarkan terlalu lama.
Risiko:
Kalau replace sudah tidak diperlukan, hapus.
Import path yang baik biasanya:
example.com/myapp/cmd/api
example.com/myapp/internal/auth
example.com/myapp/internal/storage/postgres
example.com/myapp/pkg/timeutilexample.com/myapp/misc
example.com/myapp/stuff
example.com/myapp/tempMasalahnya bukan pada namanya saja, tapi pada fakta bahwa folder seperti itu sering jadi tempat “sementara” yang tidak pernah sementara.
cmd/internal/go.work untuk development lokalChecklist yang biasanya paling cepat membantu:
go.mod root module dan import path.replace yang tidak sengaja masih aktif.go list -m all untuk melihat graph versi yang benar-benar terpakai.go.sum kalau ada checksum mismatch atau module cache yang tampak tidak wajar.internal untuk kode yang tidak boleh jadi API publik.go.work saat beberapa module lokal perlu bekerja bersama.go help modulesgo help work