GoLang: Dlaczego nie używać GOPATH

We wcześniejszych wersjach Go konfigurowanie go wymagało ustawienia pewnych zmiennych środowiskowych. Z czasem wymagania te zostały usunięte, ale wiele tutoriali online wciąż wspomina o tych zmiennych powodując zamieszanie.

Ostatnio pojawiła się nowa funkcja zwana Go Modules, która ostatecznie czyni GOPATH zbędnym. W tym poście wyjaśnię czym jest GOPATH, dlaczego preferowane są Go Moduły i jak skonfigurować projekt aby używał Go Modułów (co jest zaskakująco proste).

GOPATH jest zmienną środowiskową, która powie Go gdzie ma czytać i pobierać wszystkie pliki źródłowe, których użyje do kompilacji twojego projektu. Ta koncepcja wiąże się z pewnymi niezwykłymi ograniczeniami, których nie spotyka się w innych językach programowania:

  • Wymaga pisania projektów Go wewnątrz katalogu wskazanego przez zmienną GOPATH (domyślnie ~/go), nawet jeśli inne projekty rezydują gdzie indziej;
  • Hierarchia katalogów wewnątrz katalogu GOPATH musi odzwierciedlać URL twojego projektu. Na przykład, jeśli twój adres URL to github.com/foo/bar, musisz utworzyć katalog $GOPATH/src/github.com , a następnie utworzyć nowy katalog wewnątrz niego: foo/ i wewnątrz niego nowy katalog bar/ . Następnie, wewnątrz katalogu bar/ powinieneś umieścić swój rzeczywisty projekt git;
  • Nie ma wbudowanego sposobu na śledzenie wersji pakietów, których używasz.

Najgorszym problemem z tą konfiguracją jest to, że jest zupełnie inna od tego, do czego jesteśmy przyzwyczajeni w większości innych języków programowania. Ponadto, ponieważ GOPATH jest zmienną środowiskową, wymaga od użytkownika wiedzy na temat konfiguracji systemu operacyjnego, co jest podatne na błędy, szczególnie dla początkujących.

Dlaczego powinieneś używać Go Modules?

Go Modules nie jest zależne od żadnej z wyżej wymienionych zależności do ustawiania konkretnych zmiennych środowiskowych, ani wymagań do umieszczenia projektu w konkretnym katalogu, jak to jest z GOPATH.

Jest również retro-kompatybilny, bezpieczny i łatwy w użyciu:

  1. Wymaga jednego polecenia, aby zmigrować istniejący projekt do użycia Go Modules;
  2. Wpływa tylko na twoje środowisko programistyczne (tak jak GOPATH), więc nie wpłynie w żaden sposób na twoje wdrożenie produkcyjne;
  3. Jest retro-kompatybilny z GOPATH, co oznacza, że jeśli zaktualizujesz projekt, aby użyć Go Modules, a twoi współpracownicy nadal wolą używać GOPATH, mogą to zrobić bez żadnych problemów.

Innym powodem, aby nauczyć się używać Go Modules, jest to, że GOPATH prawdopodobnie przestanie być szeroko przyjęty w przyszłości, więc będziesz musiał się go nauczyć prędzej czy później.

Jest jednak kilka zastrzeżeń:

Caveat 1: GoLang w wersji 1.11 lub wyższej

Go Modules będą działać tylko z GoLang w wersji 1.11 lub wyższej. W czasie pisania tego postu, niektóre dystrybucje Linuksa, w tym Ubuntu, nadal używały GoLang 1.10.

Możesz przetestować aktualną wersję zainstalowanego pakietu Go za pomocą następującego polecenia:

go version

Powinno wyjść coś w stylu:

go version go1.11.2 linux/amd64

Jeśli wersja, którą widzisz jest poniżej 1.11.x, będziesz musiał ją odinstalować i wykonać poniższe kroki, aby zainstalować wymaganą wersję Go. Zauważ również, że poniższe instrukcje były przeznaczone do pracy na Ubuntu i pochodnych, jeśli używasz innego distro, będziesz musiał dostosować polecenia, aby działały dla Ciebie.

Najpierw otwórz terminal, a następnie możesz wykonać następujące polecenia:

# 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
  • Ściągnij pakiet Go 1.11 (lub nowszy) i rozpakuj go:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Zainstaluj go ręcznie w swoim katalogu /usr/local:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Potem zamknij swój terminal, otwórz nowy i przetestuj czy Go jest w poprawnej wersji:
    which go, powinno wyjść: /usr/local/go/bin/go
    go version, powinno wyjść: go version go1.11.x linux/amd64 lub podobne
  • Jeśli masz już zainstalowany pakiet Go usuń go:
    sudo apt-get remove --purge --auto-remove golang
  • Upewnij się, że twój system jest aktualny:
    sudo apt-get update
    sudo apt-get -y upgrade
  • Pobierz pakiet Go 1.11 i rozpakuj go:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Zainstaluj go ręcznie w swoim katalogu /usr/local:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Potem zamknij swój terminal, otwórz nowy i przetestuj, czy Go jest w poprawnej wersji:
    which go, powinno wyjść: /usr/local/go/bin/go
    go version, powinno wyjść: go version go1.11.x linux/amd64 lub podobne

Caveat 2: Cofnij zmiany w GOPATH i GOROOT

Jeśli dokonałeś zmian w domyślnych wartościach swojego GOPATH lub GOROOT, może być mądrze usunąć te zmiany. Nie są one konieczne, a mieszanie konfiguracji GOPATH z modułami Go jest sposobem na spowodowanie zamieszania. Dokładniej:

  1. Domyślną wartością dla GOPATH (gdy nie jest ustawiona) jest ~/go , więc gdy wspominam o katalogu ~/go, mam na myśli domyślny katalog używany przez Go. Jeśli dokonałeś zmian w swoim GOPATH, ten katalog może być gdzie indziej, więc sugeruję cofnąć te zmiany, aby uniknąć zamieszania.
  2. Nie powinieneś mieć potrzeby zmiany zmiennej środowiskowej GOROOT, ponieważ zainstalowaliśmy Go w domyślnym katalogu: /usr/local. Jeśli jednak zmieniłeś tę zmienną środowiskową, sugeruję ją cofnąć, aby uniknąć zamieszania.

Caveat 3: Nie musisz modyfikować katalogu ~/go

Jak wspomniano wcześniej ~/go jest domyślnym katalogiem, w którym Go spodziewa się czytać twoje pliki, gdy GOPATH nie jest ustawione. Jednak ma to znaczenie tylko wtedy, gdy planujesz tworzyć swoje projekty używając GOPATH.

Jeśli chcesz używać modułów Go, nie musisz tworzyć, edytować ani nawet czytać katalogu ~/go. Jeśli jeszcze nie istnieje, zostanie utworzony dla ciebie automatycznie, a jeśli istnieje, nie powinieneś musieć nic w nim zmieniać.

Możesz więc zignorować wszystkie kroki samouczka, które proszą o dokonanie zmian w tym katalogu, ponieważ prawdopodobnie odnoszą się one do wymagań GOPATH.

Jeśli masz projekt Go obecnie w tym katalogu i chcesz, aby działał z modułami Go, powinieneś przenieść go na zewnątrz, ponieważ starsze wersje Go wyłączyłyby go mod wewnątrz GOPATH, nawet jeśli miał plik go.mod.

Używanie modułów Go

Używanie modułów Go polega zasadniczo na użyciu następujących poleceń:

go mod init <your_projects_import_path>

Aby utworzyć nowy projekt, musisz po prostu utworzyć nowy katalog (gdziekolwiek poza ~/go/), a następnie zainicjować go jako moduł, czyli:

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

Polecenie go mod init utworzy nowy plik o nazwie go.mod w katalogu twojego projektu. Ten plik będzie zawierał ścieżkę importu twojego projektu (zwykle adres URL twojego repo) i listę wszystkich pakietów, których obecnie używasz w tym projekcie.

Nie powinieneś potrzebować edytować tego pliku, ponieważ jest on zarządzany automatycznie przez większość poleceń go, takich jak go run i go get . Tak więc, po uruchomieniu tych 3 poleceń zakończyłeś konfigurację tego katalogu jako modułu Go.

Aby to przetestować, utwórz nowy plik main.go wewnątrz tego katalogu z tymi liniami kodu:

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

Potem przetestuj go używając polecenia go run:

go run main.go 

Które powinno wypisać Hello Go Modules zgodnie z oczekiwaniami.

Ale ja już mam projekt, który używa GOPATH, jak dokonać migracji?

Proces jest podobny:

  1. Przenieś katalog swojego projektu do dowolnego miejsca poza ~/go/
  2. Zainicjuj go jako moduł Go, np.:
mv ~/go/src/github.com/myGithubName/myProject ~/anywhere_else/
cd ~/anywhere_else/myProject
go mod init github.com/myGithubName/myProject

Potem możesz sprawdzić, czy wszystko działa za pomocą go test ./... lub go run main.go , oba polecenia automatycznie pobiorą swoje zależności i zaktualizują plik go.mod.

To fajnie, więc czy powinienem tworzyć moduły, submoduły i podmoduły? Nope.

Aczkolwiek możliwe jest utworzenie kilku modułów w jednym projekcie, jest to prawie zawsze niepotrzebne. Jeśli chcesz mieć podfolder, aby uporządkować swój kod Go, szukasz pakietów, nie modułów. Powinieneś uruchomić komendę go mod init tylko raz na projekt, nie więcej.

Co powinienem zrobić z plikami `go.mod` i `go.sum`?

Tak jak w przypadku package.json i package-lock.json NPM, koncepcja modułów Go również tworzy kilka plików do śledzenia wszystkich wersji twoich zależności, mianowicie pliki go.mod i go.sum.

Nie powinieneś potrzebować edytować żadnego z tych 2 plików, ponieważ są one zarządzane automatycznie przez niektóre narzędzia go, takie jak go get i go test. Dobrym pomysłem jest również dodanie ich do swoich commitów, ponieważ są one potrzebne do wykonywania powtarzalnych buildów twojego projektu, tj. kompilacji z tymi samymi wersjami i pakietami, które masz lokalnie.

Wnioski

Powinieneś być teraz gotowy do używania modułów Go w swoich własnych projektach. Używanie go nie jest obowiązkowe, ale jeśli przeczytałeś tak daleko, to prawdopodobnie zauważyłeś jak dużo łatwiejsze i bardziej intuicyjne są Go Modules w porównaniu z GOPATH. Jest też jedna cecha, którą tylko Go Moduły mogą Ci zaoferować: Reproducible builds.

Jeśli chcesz dowiedzieć się więcej szczegółów na temat Go Modules sugeruję przeczytanie tego postu dla krótszej wersji lub tego dla dłuższej, oba są bardzo zwięzłe i łatwe do przeczytania. Gorąco polecam również przeprowadzenie własnych badań, w sieci można znaleźć kilka świetnych postów na ten temat. Szczęśliwego kodowania!

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.