깃헙 트렌드에 올라온 레포들을 구경하는데 GO111MODULE=on
같은게 종종 보여 궁금해서 찾아봤다. 이 글을 주로 참고했다.
Go가 2009년에 처음 나왔을땐 패키지 관리하는게 따로 없어서 go get
을 하면 소스코드를 전부 $GOPATH/src에 fetch했고 버전 관리도 따로 없어서 그냥 master 브랜치를 stable 이라 생각했다. 그러다 Go 1.11 부터 Module이 지원되면서 GOPATH에 다 때려넣는대신 Module에서 버전 관리, 의존성 관리까지 해줄 수 있게 되었다. 그때 부터 GOPATH 방식과 Module 방식으로 나뉘어졌다. 이를 제어하는 단 하나의 환경변수가 GO111MODULE 이다.
주의할 것은, Go 버전마다 조금씩 작동 방식이 달라진다는 것이다.
GOPATH 경로에서, Module이 필요한 작업(e.g. 특정 버전의 바이너리를 받는)을 하려면
GO111MODULE=on go get github.com/golang/mock/tree/master/mockgen@v1.3.1
하면 된다.
GO111MODULE=auto 일때의 작동 방식이 달라졌다.
현재 프로젝트의 go.mod를 망치고 싶지 않으면 여전히 cd && GO111MODULE=on go get
를 해야했다.
Go 1.16부터, GO111MODULE=on이 default가 됐다. 따라서 기존의 GOPATH 방식을 계속 사용하고 싶다면 GO111MODULE=off를 명시해주어야 한다.
그리고 go install
명령도 지원되서 기존의
(cd && go get golang.org/x/tools/gopls@latest)
와 같은 방식 대신
go install golang.org/x/tools/gopls@latest
을 사용할 수 있게 되었다.
2021/8/16 Go 1.17이 릴리즈되고 이제 GO111MODULE=auto도 GO111MODULE=on과 동일하게 작동한다. 여전히 GOPATH 방식을 고수하고 싶다면 GO111MODULE=off를 명시해주어야 한다.
그리고 module graph pruning 같은 기능이 지원되고 go get
이 deprecated 되었으니 대신 go install
을 쓰라고 한다.
GO111MODULE 환경변수는 Module 방식을 사용하기 위해 필요했다. 덕분에 특정 버전의 패키지들을 받을 수 있게 되었다. 만약 Module 방식이 아닌 GOPATH 방식을 쓴다면 go get
은 master 브랜치의 최신 커밋을 받아오게 된다.