Direct naar de hoofdinhoud
Module 9 · Les 4 van 544/50 in de cursus~12 min
Modulelessen (4/5)

Ga modules

Een Go-module is een versie-eenheid die bestaat uit een of meer pakketten. Het is de basis van het moderne afhankelijkheidssysteem (Go 1.11+): geen GOPATH meer, geen verplichte vendor, expliciete en reproduceerbare afhankelijkheden.

go.mod: het modulemanifest

Code
module example.com/myapp

go 1.22

require (
    github.com/google/uuid v1.6.0
    golang.org/x/time     v0.5.0
)

Drie belangrijke richtlijnen:

  • module <path> — het importpad van de module. Alle interne pakketten worden geïmporteerd als example.com/myapp/sub/pkg. Het hoeft geen echte URL te zijn, maar om te publiceren via go get moet het worden omgezet.
  • go <version> — de minimaal vereiste Go-versie (wordt ook gebruikt om te bepalen welke taalfuncties zijn toegestaan, bijvoorbeeld range-over-func in 1.23).
  • require — de directe afhankelijkheden met hun exacte versie.

Andere richtlijnen: replace (vervangt een dep door een vork of een lokaal pad), exclude, retract.

go.sum: het cryptografische vergrendelingsbestand

Naast go.mod bevat go.sum een cryptografische hash van ELKE gedownloade versie (inclusief transitieve afhankelijkheden). Het garandeert reproduceerbaarheid: als iemand met een gepubliceerde versie knoeit, mislukt de build.

Altijd vastleggen. Het wordt automatisch bijgewerkt door go opdrachten.

Essentiële commando's

Bash
go mod init example.com/myapp        # create go.mod
go get github.com/google/uuid        # add the dep at its latest version
go get github.com/google/uuid@v1.5.0 # specific version
go get -u ./...                      # upgrade every dep
go mod tidy                          # remove unused deps, add missing ones
go mod download                      # download everything into the cache
go mod why github.com/x/y            # explain why a dep is included
go mod graph                         # full dependency graph

go mod tidy is degene die u na elke importwijziging uitvoert: het garandeert dat go.mod precies de pakketten weergeeft die daadwerkelijk worden gebruikt.

Semantische importversies (SIV)

Versies volgen SemVer: v1.2.3 = MAJOR.MINOR.PATCH. Het interessante deel is major v2+:

  • Hoofd v0 en v1 → normaal pad: github.com/foo/bar.
  • Hoofdversie v2 of hoger → het pad bevat de hoofdversie: github.com/foo/bar/v2.
Go
import "github.com/foo/bar/v2"

Hierdoor kunt u zowel v1 als v2 van dezelfde bibliotheek tegelijkertijd importeren (handig tijdens progressieve migraties).

Importeer paden en interne pakketten

Als uw module example.com/myapp is, wordt een utils/ submap geïmporteerd als:

Go
import "example.com/myapp/utils"

Het pad hangt alleen af van de naam die is opgegeven in go.mod, niet van de locatie op schijf: dezelfde code in een andere map blijft werken.

Werkruimtemodus (Go 1.18+)

Om aan meerdere modules te werken die tegelijkertijd naar elkaar verwijzen (bijvoorbeeld een bibliotheek en een app die deze gebruikt):

Bash
go work init ./lib ./app

Hierdoor wordt go.work gemaakt: go build gebruikt de lokale versie van ./lib in plaats van de gepubliceerde versie te downloaden. Doe geen commit go.work (het is een ontwikkelomgeving).

Oefeningen

Oefening#go.m9.l4.e1
Pogingen: 0Laden…

De module is example.com/myapp en bevat een submap utils. Importeer het subpakket in het hoofdpakket met behulp van het volledige pad.

Editor laden…
Toon hint

Het importpad is de modulenaam (van go.mod) plus het relatieve pad van de map.

Oplossing beschikbaar na 3 pogingen

Oefening#go.m9.l4.e2
Pogingen: 0Laden…

Verander de individuele imports in een importgroep met de import ( ... ) syntaxis, waarbij zowel fmt als os worden geïmporteerd.

Editor laden…

Oplossing beschikbaar na 3 pogingen

Quiz#go.m9.l4.e3
Klaar

Welk commando verwijdert afhankelijkheden die niet langer uit go.mod worden geïmporteerd en voegt de ontbrekende toe?

Go
$ go mod ???
Antwoordmogelijkheden