Modul adalah pohon direktori berisi package Go dengan file go.mod di akarnya. go.mod memberi nama modul itu dan mendaftar versi dari setiap modul lain yang menjadi dependensinya. Kamu membuatnya dengan go mod init:
mkdir myapp
cd myapp
go mod init example.com/myapp
go: creating new go.mod: module example.com/myapp
go.mod yang dihasilkan:
module example.com/myapp
go 1.24.5
Itu sudah cukup untuk build. Setiap proyek Go sejak Go 1.16 adalah modul, dan go build, go run ., serta go test menolak bekerja tanpanya:
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
Memilih Module Path
Module path adalah awalan dari setiap import path di dalam modul. Dengan modul example.com/myapp, package di direktori internal/store di-import sebagai example.com/myapp/internal/store.
| Situasi | Module path |
|---|---|
| Kode yang di-host di GitHub dan mungkin di-import orang lain | github.com/yourname/project |
| Kode milik perusahaanmu | yourcompany.com/project atau URL repository |
| Program pribadi atau latihan | example.com/myapp atau cukup myapp |
| Versi 2 atau lebih baru dari modul yang sudah dipublikasikan | github.com/yourname/project/v2 |
Untuk library, path-nya harus sesuai dengan lokasi kode, karena go get memakainya untuk menemukan repository. Untuk program yang hanya kamu jalankan sendiri, path itu sekadar nama. Hindari satu kata yang sama dengan package standard library, seperti go mod init fmt atau go mod init strings: build-nya akan gagal dengan ambiguous import: found package fmt in multiple modules.
Menjalankan go mod init tanpa argumen akan gagal di luar susunan GOPATH yang lama:
go: cannot determine module path for source directory /home/ana/myapp (outside GOPATH, module path must be specified)
Berikan sebuah path.
Menambahkan Dependensi
Tulis import-nya, lalu biarkan Go mengambilnya. Misalkan main.go meng-import github.com/google/uuid. Melakukan build sebelum modul mengenalinya memberi instruksi yang jelas:
main.go:6:2: no required module provides package github.com/google/uuid; to add it:
go get github.com/google/uuid
Salah satu perintah ini memperbaikinya:
go get github.com/google/uuid
# or, to sync go.mod with every import in the module:
go mod tidy
go get melaporkan apa yang diubahnya:
go: downloading github.com/google/uuid v1.6.0
go: added github.com/google/uuid v1.6.0
go mod tidy melaporkan bagaimana ia menemukan import tersebut:
go: finding module for package github.com/google/uuid
go: downloading github.com/google/uuid v1.6.0
go: found github.com/google/uuid in github.com/google/uuid v1.6.0
go.mod sekarang punya baris require:
module example.com/myapp
go 1.24.5
require github.com/google/uuid v1.6.0
go get dengan versi
| Perintah | Efek |
|---|---|
go get pkg | tambahkan pkg di rilis terbarunya, atau pertahankan versi saat ini kalau sudah dibutuhkan |
go get pkg@v1.5.0 | pakai tepat v1.5.0 (upgrade atau downgrade) |
go get pkg@latest | pindah ke rilis terbaru |
go get pkg@abc1234 | pakai commit tertentu (dicatat sebagai pseudo-version) |
go get -u ./... | upgrade setiap dependensi ke rilis minor atau patch terbarunya |
go get -u=patch ./... | upgrade hanya ke rilis patch terbaru |
go get pkg@none | hapus requirement tersebut |
go get go@1.24 | naikkan versi Go minimum milik modul |
go get mengubah go.mod. Perintah ini tidak lagi melakukan build atau menginstal program; sejak Go 1.18 itu adalah tugas go install pkg@version.
Dependensi tidak langsung
Requirement yang ditandai // indirect adalah modul yang tidak di-import langsung oleh kodemu, tetapi dibutuhkan oleh build. Sejak Go 1.17, go.mod mendaftar setiap modul yang menyediakan package untuk build, jadi dependensi dari dependensimu muncul di sini dengan penanda itu. go mod tidy mengurus penanda ini; kamu tidak menambahkannya sendiri.
go mod tidy
Jalankan go mod tidy setiap kali kamu menambah atau menghapus import. Perintah ini:
- menambahkan requirement untuk package yang di-import tetapi belum ada,
- menghapus requirement yang sudah tidak di-import apa pun,
- menambahkan entri
go.sumyang dibutuhkan build dan membuang entri yang usang.
Perintah ini memeriksa setiap package di dalam modul, termasuk test dan setiap kombinasi build tag, jadi kadang ia mempertahankan dependensi yang tidak kamu lihat terpakai di platformmu. Menjalankan go mod tidy sebelum setiap commit, dan memeriksa di CI bahwa perintah itu tidak menghasilkan diff, menjaga go.mod tetap jujur.
go.sum
go.sum mencatat sebuah hash untuk setiap versi modul yang dipakai build:
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
Baris pertama adalah hash dari file-file modul, baris kedua hanya dari go.mod-nya. Saat perintah go mengunduh sebuah modul, ia memeriksa hash-nya terhadap go.sum dan terhadap checksum database publik (sum.golang.org), jadi rilis yang dirusak atau diam-diam diubah akan menggagalkan build. Commit go.sum bersama go.mod, dan jangan pernah mengeditnya secara manual.
Cara Go Memilih Versi
Go memakai minimal version selection. Setiap modul mendaftar versi minimum dari setiap dependensi yang dibutuhkannya, dan build memakai yang tertinggi dari versi-versi minimum itu, tidak pernah yang lebih baru. Kalau modulmu membutuhkan uuid v1.5.0 dan sebuah dependensi membutuhkan uuid v1.6.0, build memakai v1.6.0, meskipun v1.7.0 sudah ada. Tidak ada yang di-upgrade kecuali seseorang memintanya dengan go get.
Akibatnya, build bisa direproduksi tanpa lock file: go.mod ditambah graf dependensinya sudah sepenuhnya menentukan setiap versi. go list -m all mencetak hasilnya:
go list -m all
example.com/myapp
github.com/google/uuid v1.6.0
Major version
Modul di v2 atau lebih harus menyertakan major version di path-nya: github.com/yourname/project/v2. Import path-nya ikut berubah, jadi project dan project/v2 adalah modul yang berbeda dan bisa sama-sama ada dalam satu build. Inilah aturan Go untuk perubahan yang tidak kompatibel, dan karena itulah kamu melihat import seperti github.com/jackc/pgx/v5.
replace: Mengerjakan Dependensi Secara Lokal
Untuk menguji perubahan pada sebuah dependensi sebelum mempublikasikannya, arahkan path-nya ke direktori lokal:
module example.com/myapp
go 1.24.5
require example.com/mylib v1.2.0
replace example.com/mylib => ../mylib
Atau dari command line:
go mod edit -replace example.com/mylib=../mylib
go mod tidy
Direktori itu harus punya go.mod-nya sendiri. replace hanya berlaku saat membangun modul ini secara langsung, bukan saat orang lain bergantung padanya, jadi ingat untuk menghapusnya sebelum kamu memberi tag pada sebuah rilis.
Untuk mengedit beberapa modul sekaligus tanpa menyentuh file go.mod mereka, Go 1.18 menambahkan workspace:
go work init . ../mylib
Perintah itu menulis file go.work yang membuat mylib lokal lebih diutamakan. Jangan masukkan go.work ke version control kecuali seluruh tim memakai susunan yang sama.
Dependensi Tool (Go 1.24)
Go 1.24 menambahkan direktif tool, sehingga code generator dan linter bisa diberi versi di go.mod alih-alih diinstal secara global:
go get -tool golang.org/x/tools/cmd/stringer
go tool stringer -type=Color
func init Adalah Hal Lain
Pencarian "golang init" sering kali bermaksud fungsi init, yang tidak berhubungan dengan go mod init. Package mana pun boleh mendeklarasikan func init(). Fungsi ini tidak menerima argumen, tidak bisa dipanggil oleh kodemu, dan berjalan sekali secara otomatis, setelah variabel di level package diisi dan sebelum main:
Satu file boleh punya beberapa fungsi init, dan semuanya berjalan sesuai urutan kemunculannya. Package yang di-import menyelesaikan inisialisasinya sendiri lebih dulu. Jaga init tetap kecil: pekerjaan yang bisa gagal lebih mudah ditangani dan diuji sebagai fungsi biasa yang dipanggil dari main.
Modul Privat dan Proxy
Secara default, go mengunduh modul lewat proxy.golang.org. Proxy itu tidak bisa melihat repository privat, jadi beri tahu Go path mana saja yang privat:
go env -w GOPRIVATE=github.com/yourcompany/*
Modul yang cocok dengan GOPRIVATE diambil langsung dari repository dengan kredensial git milikmu dan melewati checksum database.
Pertanyaan yang sering diajukan
Apa yang dilakukan go mod init?
Perintah ini membuat file go.mod di direktori saat ini, yang menjadikan direktori itu akar dari sebuah modul. go mod init example.com/myapp menulis module path dan versi Go:
module example.com/myapp
go 1.24.5
Jalankan sekali per proyek, sebelum go build atau go get.
Apa yang sebaiknya dipakai sebagai module path di go mod init?
Alamat tempat kode akan diambil kalau orang lain meng-import-nya, biasanya path repository: go mod init github.com/yourname/project. Untuk program yang tidak akan di-import siapa pun, nama apa saja bisa (go mod init myapp), tetapi path bergaya domain dengan titik seperti example.com/myapp menghindari bentrok dengan nama package di standard library.
Apa bedanya go get dan go mod tidy?
go get pkg@version menambahkan dependensi atau mengubah versinya. go mod tidy membaca file sumbermu, menambahkan modul yang dibutuhkan import-mu tetapi belum ada di go.mod, menghapus requirement yang tidak di-import apa pun, dan memperbarui go.sum. Alur yang umum adalah menulis import-nya dulu, lalu menjalankan go mod tidy.
Apakah go.sum perlu di-commit?
Ya. go.sum menyimpan hash kriptografis dari setiap versi modul yang dipakai build-mu. Meng-commit file ini memungkinkan perintah go memverifikasi bahwa semua orang mengunduh dependensi yang identik sampai ke setiap byte-nya. Jangan pernah mengeditnya secara manual; go mod tidy yang mengurusnya.
Apakah "golang init" sama dengan go mod init?
Tidak, keduanya hal yang berbeda yang kebetulan memakai kata yang sama. go mod init adalah perintah terminal yang membuat go.mod. func init() adalah fungsi yang kamu tulis di kode Go; fungsi ini berjalan otomatis sekali, sebelum main, setelah variabel package diinisialisasi.