GoLang: Varför inte använda GOPATH

I tidigare versioner av Go krävdes det några miljövariabler för att konfigurera Go. Med tiden togs dessa krav bort, men många handledningar på nätet nämner fortfarande dessa variabler vilket skapar förvirring.

Nyligen släpptes en ny funktion kallad Go Modules som äntligen gör GOPATH onödig. I det här inlägget kommer jag att förklara vad GOPATH är, varför Go Modules är att föredra och hur man konfigurerar ett projekt för att använda Go Modules (vilket är förvånansvärt enkelt).

GOPATH är en miljövariabel som talar om för Go var den ska läsa och hämta alla källkodsfiler som den ska använda för att kompilera ditt projekt. Detta koncept kommer med några ovanliga begränsningar som du inte ser i andra programmeringsspråk:

  • Det kräver att du skriver dina Go-projekt i denna katalog som pekas ut av GOPATH-variabeln (som standard ~/go), även om dina andra projekt finns någon annanstans;
  • Kataloghierarkin i GOPATH-katalogen måste återspegla URL:en för ditt projekt. Om din URL till exempel är github.com/foo/bar måste du skapa en katalog $GOPATH/src/github.com och sedan skapa en ny katalog i den: foo/ och inuti den en ny katalog bar/ . Inom katalogen bar/ ska du sedan lägga ditt egentliga git-projekt;
  • Det finns inget inbyggt sätt att hålla reda på versionerna av de paket du använder.

Det värsta problemet med den här inställningen är att den är helt annorlunda än vad vi är vana vid i de flesta andra programmeringsspråk. Eftersom GOPATH är en miljövariabel kräver det också att användarna vet lite om hur man konfigurerar sitt operativsystem, vilket är felkänsligt, särskilt för nybörjare.

Varför ska du använda Go Modules?

Go Modules är inte beroende av något av de beroenden som nämnts ovan för att ställa in specifika miljövariabler, och inte heller av kraven på att placera ditt projekt i en specifik katalog som det är med GOPATH.

Det är också retrokompatibelt, säkert och lätt att använda:

  1. Det krävs ett enda kommando för att migrera ett befintligt projekt för att använda Go Modules;
  2. Det påverkar bara din utvecklingsmiljö (precis som GOPATH) så det kommer inte att påverka din produktionsinstallation på något sätt;
  3. Det är retrokompatibelt med GOPATH, vilket innebär att om du uppdaterar ett projekt för att använda Go Modules och dina medarbetare fortfarande föredrar att använda GOPATH så kan de göra det utan några problem.

En annan anledning att lära sig att använda Go Modules är att GOPATH troligen kommer att sluta användas i stor utsträckning i framtiden, så du kommer att behöva lära dig det förr eller senare.

Det finns dock några förbehåll:

Krav 1: GoLang version 1.11 eller senare

Go Modules fungerar endast med GoLang version 1.11 eller senare. När det här inlägget skrevs använde vissa Linuxdistributioner, inklusive Ubuntu, fortfarande GoLang 1.10.

Du kan testa den aktuella versionen av ditt installerade Go-paket med följande kommando:

go version

Det bör ge ut något i stil med:

go version go1.11.2 linux/amd64

Om den version som visas är lägre än 1.11.x måste du avinstallera det och följa nedanstående steg för att installera den Go-version som krävs. Observera också att instruktionerna nedan är tänkta att fungera på Ubuntu och härledda distributioner, om du använder någon annan distro måste du anpassa kommandona för att de ska fungera för dig.

Först öppnar du en terminal sedan kan du köra följande kommandon:

# 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
  • Hämta Go 1.11-paketet (eller nyare) och extrahera det:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Installera det manuellt i din /usr/local-katalog:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Slut sedan terminalen, öppna en ny och testa om Go har rätt version:
    which go, bör ge ut: /usr/local/go/bin/go
    go version, bör ge ut: go version go1.11.x linux/amd64 eller liknande
  • Om du redan har installerat Go-paketet ta bort det:
    sudo apt-get remove --purge --auto-remove golang
  • Säkerställ att ditt system är uppdaterat:
    sudo apt-get update
    sudo apt-get -y upgrade
  • Ladda ner Go-paketet 1.11 och extrahera det:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Installera det manuellt i din /usr/local katalog:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Slut sedan terminalen, öppna en ny och testa om Go har rätt version:
    which go, bör ge ut: /usr/local/go/bin/go
    go version, bör ge ut: go version go1.11.x linux/amd64 eller liknande

Caveat 2: Ångra ändringar i GOPATH och GOROOT

Om du har gjort ändringar i standardvärdena för din GOPATH eller GOROOT kan det vara klokt att ta bort dessa ändringar. De är inte nödvändiga och att blanda GOPATH-konfigurationer med Go-moduler är ett sätt att skapa förvirring. Mer specifikt:

  1. Standardvärdet för GOPATH (när det inte är inställt) är ~/go , så när jag nämner katalogen ~/go menar jag den standardkatalog som används av Go. Om du har gjort ändringar i din GOPATH kan denna katalog vara någon annanstans, så jag föreslår att du ångrar dessa ändringar för att undvika förvirring.
  2. Du bör inte behöva ändra miljövariabeln GOROOT eftersom vi har installerat Go i standardkatalogen: /usr/local. Om du dock har ändrat denna miljövariabel föreslår jag att du ångrar detta för att undvika förvirring.

Caveat 3: Du behöver inte ändra katalogen ~/go

Som tidigare nämnts är ~/go standardkatalogen där Go förväntar sig att läsa dina filer när GOPATH inte är satt. Detta gör dock bara skillnad om du planerar att skapa dina projekt med hjälp av GOPATH.

Om du vill använda Go Modules behöver du inte skapa, redigera eller ens läsa katalogen ~/go. Om den inte finns ännu kommer den att skapas automatiskt åt dig, och om den finns bör du inte behöva ändra något i den.

Så du kan ignorera alla steg i handledningen som ber dig att göra ändringar i den här katalogen eftersom de förmodligen hänvisar till GOPATH-krav.

Också, om du har ett Go-projekt som för närvarande ligger i denna katalog och du vill att det ska fungera med Go Modules bör du flytta det utanför eftersom äldre versioner av Go skulle inaktivera go mod i GOPATH även om det hade en go.mod-fil.

Användning av Go Modules

Användning av Go Modules består i princip av att använda följande kommando:

go mod init <your_projects_import_path>

För att skapa ett nytt projekt behöver du bara skapa en ny katalog (var som helst utanför ~/go/) och sedan initiera den som en modul, det vill säga:

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

Kommandot go mod init kommer att skapa en ny fil med namnet go.mod i ditt projekts katalog. Denna fil kommer att innehålla ditt projekts importväg (vanligtvis din repo’s URL) och en lista med alla paket som du för närvarande använder i projektet.

Du bör inte behöva redigera denna fil eftersom den hanteras automatiskt av de flesta go-kommandon som go run och go get . Efter att ha kört dessa tre kommandon har du konfigurerat den här katalogen som en Go-modul.

För att testa den skapar du en ny fil main.go i den här katalogen med dessa kodrader:

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

Testa den sedan med kommandot go run:

go run main.go 

som bör ge ut Hello Go Modules som förväntat.

Men jag har redan ett projekt som använder GOPATH, hur kan jag migrera det?

Processen är liknande:

  1. Förflytta projektets katalog till en plats utanför ~/go/
  2. Initialisera det som en Go-modul, t.ex.:
mv ~/go/src/github.com/myGithubName/myProject ~/anywhere_else/
cd ~/anywhere_else/myProject
go mod init github.com/myGithubName/myProject

Därefter kan du testa om allt fungerar med antingen go test ./... eller go run main.go , båda kommandona hämtar automatiskt sina beroenden och uppdaterar go.mod-filen.

Det är häftigt, så ska jag skapa moduler, submoduler och sub-submoduler? Nej.

Och även om det är möjligt att skapa flera moduler i ett enda projekt är detta nästan alltid onödigt. Om du vill ha en undermapp för att organisera din Go-kod letar du efter paket, inte moduler. Du bör bara köra kommandot go mod init en gång per projekt, inte mer.

Vad ska jag göra med filerna `go.mod` och `go.sum`?

Som med NPM:s package.json och package-lock.json skapar Go Modules-konceptet också några filer för att hålla reda på alla versioner av dina beroenden, nämligen filerna go.mod och go.sum.

Du bör inte behöva redigera någon av dessa två filer eftersom de hanteras automatiskt av vissa go-verktyg som go get och go test. Det är också en bra idé att lägga till dem i dina commits eftersom de behövs för att utföra reproducerbara byggen av ditt projekt, dvs. kompilera med alla samma versioner och paket som du har lokalt.

Slutsats

Du bör nu vara redo att använda Go Modules i dina egna projekt. Det är inte obligatoriskt att använda det, men om du har läst så här långt har du förmodligen märkt hur mycket enklare och mer intuitivt Go Modules är jämfört med GOPATH. Det finns också en funktion som bara Go Modules kan erbjuda dig:

Om du vill lära dig mer detaljer om Go Modules föreslår jag att du läser det här inlägget för en kortare version eller det här för en längre, båda är mycket kortfattade och lätta att läsa. Jag rekommenderar också starkt att du gör din egen forskning, det finns flera bra inlägg om detta ämne på webben. Lycka till med kodningen!

Lämna ett svar

Din e-postadress kommer inte publiceras.