GoLang: Waarom niet het GOPATH

In eerdere versies van Go moesten er omgevingsvariabelen worden ingesteld om het te configureren. Na verloop van tijd werden deze vereisten verwijderd, maar in veel online tutorials worden deze variabelen nog steeds genoemd, waardoor verwarring ontstaat.

Recentelijk is een nieuwe functie genaamd Go Modules uitgebracht, die het GOPATH eindelijk overbodig maakt. In dit artikel zal ik uitleggen wat het GOPATH is, waarom Go Modules de voorkeur hebben en hoe je een project kunt configureren om Go Modules te gebruiken (wat verrassend eenvoudig is).

Het GOPATH is een omgevingsvariabele die Go vertelt waar het alle bronbestanden moet lezen en downloaden die het zal gebruiken voor het compileren van je project. Dit concept heeft een aantal ongebruikelijke beperkingen die u bij andere programmeertalen niet ziet:

  • Het vereist dat u uw Go-projecten in deze directory schrijft die wordt aangegeven door de GOPATH-variabele (standaard ~/go), zelfs als uw andere projecten zich elders bevinden;
  • De directory-hiërarchie in de GOPATH directory moet de URL van uw project weergeven. Bijvoorbeeld, als uw URL github.com/foo/bar is, moet u een directory $GOPATH/src/github.com aanmaken, dan een nieuwe directory daarin: foo/ en daarbinnen een nieuwe directory bar/ . Dan, in de bar/ directory moet je je eigenlijke git project zetten;
  • Er is geen ingebouwde manier om de versies van de pakketten die je gebruikt bij te houden.

Het grootste probleem met deze setup is dat het compleet anders is dan wat we gewend zijn van de meeste andere programmeertalen. Ook, omdat GOPATH een omgevingsvariabele is, vereist het dat gebruikers een beetje weten over het configureren van uw OS, wat vooral voor beginners foutgevoelig is.

Waarom zou u Go Modules gebruiken?

Go Modules is niet afhankelijk van een van de hierboven genoemde afhankelijkheden voor het instellen van specifieke omgevingsvariabelen, noch de vereisten voor het plaatsen van uw project in een specifieke directory zoals het is met GOPATH.

Het is ook retro-compatibel, veilig en gemakkelijk te gebruiken:

  1. Er is maar één commando nodig om een bestaand project te migreren naar Go Modules;
  2. Het heeft alleen invloed op uw ontwikkelomgeving (net als GOPATH), dus het zal uw productie-implementatie op geen enkele manier beïnvloeden;
  3. Het is retro-compatibel met GOPATH, wat betekent dat als u een project bijwerkt om Go Modules te gebruiken en uw collega’s geven nog steeds de voorkeur aan GOPATH, dan kunnen ze dat zonder problemen doen.

Een andere reden om Go Modules te leren gebruiken is dat GOPATH in de toekomst waarschijnlijk niet meer op grote schaal zal worden gebruikt, dus u zult het vroeg of laat moeten leren.

Er zijn echter enkele caveats:

Caveat 1: GoLang versie 1.11 of hoger

Go Modules zal alleen werken met GoLang versie 1.11 of hoger. Ten tijde van het schrijven van dit bericht, gebruikten sommige Linux distributies, Ubuntu inbegrepen, nog steeds GoLang 1.10.

U kunt de huidige versie van uw geïnstalleerde Go pakket testen met het volgende commando:

go version

Het zou iets moeten opleveren als:

go version go1.11.2 linux/amd64

Als de versie die u ziet lager is dan 1.11.x moet u het verwijderen en de onderstaande stappen volgen om de vereiste Go versie te installeren. Merk ook op dat de onderstaande instructies bedoeld zijn om op Ubuntu en afgeleide distro’s te werken, als u een andere distro gebruikt zult u de commando’s moeten aanpassen om ze voor u te laten werken.

Open eerst een terminal en voer dan de volgende commando’s uit:

# If you have already installed the Go package remove it:
sudo apt-get remove --purge --auto-remove golang# Make sure your system is up-to-date:
sudo apt-get update
sudo apt-get -y upgrade# Download the Go 1.11 package and extract it:
wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
sudo tar -xvf go1.11.linux-amd64.tar.gz# Install it manually on your /usr/local directory:
sudo mv go /usr/local
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc# Then close your terminal, open a new one and test if Go is at the correct version:
which go # should output: /usr/local/go/bin/go
go version # should output: go version go1.11.x linux/amd64 or similar
  • Download het Go 1.11 pakket (of nieuwer) en pak het uit:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Installeer het handmatig in uw /usr/local directory:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Sluit vervolgens uw terminal, open een nieuwe en test of Go de juiste versie heeft:
    which go, zou moeten uitvoeren: /usr/local/go/bin/go
    go version, zou moeten uitvoeren: go version go1.11.x linux/amd64 of vergelijkbaar
  • Als u het Go-pakket al hebt geïnstalleerd, verwijder dit dan:
    sudo apt-get remove --purge --auto-remove golang
  • Zorg ervoor dat uw systeem up-to-date is:
    sudo apt-get update
    sudo apt-get -y upgrade
  • Download het Go 1.11-pakket en pak het uit:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Installeer het handmatig in uw /usr/local-directory:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Sluit vervolgens uw terminal, open een nieuwe en test of Go de juiste versie heeft:
    which go, zou moeten uitvoeren: /usr/local/go/bin/go
    go version, zou moeten uitvoeren: go version go1.11.x linux/amd64 of vergelijkbaar

Caveat 2: Wijzigingen in GOPATH en GOROOT ongedaan maken

Als u wijzigingen heeft aangebracht in de standaardwaarden van uw GOPATH of GOROOT kan het verstandig zijn om die wijzigingen te verwijderen. Ze zijn niet nodig en het mengen van GOPATH configuraties met Go Modules is een manier om verwarring te veroorzaken. Meer specifiek:

  1. De standaard waarde voor het GOPATH (indien niet ingesteld) is ~/go, dus als ik de directory ~/go noem, bedoel ik de standaard directory die door Go wordt gebruikt. Als u wijzigingen hebt aangebracht in uw GOPATH, kan deze directory ergens anders staan, dus ik stel voor dat u deze wijzigingen ongedaan maakt om verwarring te voorkomen.
  2. U zou de GOROOT omgevingsvariabele niet hoeven te veranderen, omdat we Go in de standaard directory hebben geïnstalleerd: /usr/local. Als u echter deze omgevingsvariabele heeft gewijzigd, stel ik voor dat u dit ongedaan maakt om verwarring te voorkomen.

Caveat 3: U hoeft de ~/go directory niet te wijzigen

Zoals eerder vermeld is ~/go de standaard directory waar Go verwacht uw bestanden te lezen als GOPATH niet is ingesteld. Dit maakt echter alleen een verschil als u van plan bent uw projecten te maken met GOPATH.

Als u Go Modules wilt gebruiken, hoeft u de ~/go directory niet aan te maken, te bewerken of zelfs maar te lezen. Als hij nog niet bestaat, wordt hij automatisch voor u aangemaakt, en als hij bestaat, hoeft u er niets in te veranderen.

Dus u kunt alle stappen van de tutorial negeren die u vragen wijzigingen aan te brengen in deze directory, omdat ze waarschijnlijk verwijzen naar GOPATH-vereisten.

Als u een Go-project heeft dat in deze directory staat en u wilt dat het met Go-modules werkt, moet u het naar buiten verplaatsen, omdat oudere versies van Go de Go-mod in het GOPATH zouden uitschakelen, zelfs als het een go.mod-bestand had.

Gebruik Go Modules

Gebruik Go Modules bestaat in principe uit het gebruik van het volgende commando:

go mod init <your_projects_import_path>

Om een nieuw project te maken hoeft u alleen maar een nieuwe directory aan te maken (ergens buiten ~/go/) en deze vervolgens te initialiseren als een module, d.w.z.:

mkdir myProject/
cd myProject
go mod init github.com/myGithubName/myProject

Het go mod init commando zal een nieuw bestand genaamd go.mod in de directory van uw project maken. Dit bestand zal het import pad van uw project bevatten (gewoonlijk de URL van uw repo) en een lijst met alle pakketten die u momenteel gebruikt in dit project.

U zou dit bestand niet moeten hoeven te bewerken omdat het automatisch wordt beheerd door de meeste go commando’s zoals go run en go get . Dus, na het uitvoeren van deze 3 commando’s bent u klaar met het configureren van deze directory als een Go Module.

Om het te testen maakt u een nieuw main.go bestand in deze directory met deze regels code:

package mainimport "fmt"func main() {
fmt.Println("Hello Go Modules")
}

Test het vervolgens met behulp van het go run commando:

go run main.go 

Wat Hello Go Modules zou moeten opleveren zoals verwacht.

Maar ik heb al een project dat GOPATH gebruikt, hoe kan ik dat migreren?

Het proces is vergelijkbaar:

  1. Verplaats de directory van uw project naar ergens buiten ~/go/
  2. Initialiseer het als een Go Module, bijv.
mv ~/go/src/github.com/myGithubName/myProject ~/anywhere_else/
cd ~/anywhere_else/myProject
go mod init github.com/myGithubName/myProject

Dan kunt u testen of alles werkt met go test ./... of go run main.go , beide commando’s zullen automatisch hun afhankelijkheden downloaden en het go.mod bestand bijwerken.

Dat is cool, dus moet ik nu modules, submodules, en sub-submodules maken? Nope.

Hoewel het mogelijk is om meerdere modules in een enkel project te maken is dit bijna altijd onnodig. Als u een submap wilt om uw Go-code te organiseren, zoekt u naar pakketten, niet naar modules. U moet het go mod init commando slechts eenmaal per project uitvoeren, niet meer.

Wat moet ik doen met de `go.mod` en `go.sum` bestanden?

Zoals bij NPM’s package.json en package-lock.json maakt het Go Modules concept ook enkele bestanden aan om alle versies van uw afhankelijkheden bij te houden, namelijk de go.mod en de go.sum bestanden.

U zou geen van deze 2 bestanden moeten hoeven te bewerken omdat ze automatisch worden beheerd door sommige go tools zoals go get en go test. Het is ook een goed idee om ze aan uw commits toe te voegen omdat ze nodig zijn voor het uitvoeren van reproduceerbare builds van uw project, d.w.z. compileren met dezelfde versies en pakketten die u lokaal heeft.

Conclusie

U zou nu klaar moeten zijn om Go Modules te gebruiken in uw eigen projecten. Het gebruik ervan is niet verplicht, maar als u tot nu toe heeft gelezen heeft u waarschijnlijk gemerkt hoe veel eenvoudiger en intuïtiever Go Modules zijn in vergelijking met GOPATH. Er is ook een feature die alleen Go Modules je kunnen bieden: Reproduceerbare builds.

Als je meer details wilt leren over Go Modules stel ik voor deze post te lezen voor een kortere versie of deze voor een langere versie, beide zijn zeer beknopt en gemakkelijk te lezen. Ik raad je ook ten zeerste aan om je eigen onderzoek te doen, er zijn verschillende geweldige berichten over dit onderwerp op het web. Veel plezier met coderen!

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.