https://velog.io/@kimmachinegun/Go-Go-Modules-살펴보기-7cjn4soifk

Go += Package Versioning

Go는 초기 패키지를 관리하기 위한 마땅한 도구가 없었습니다. 하지만 의존성 관리는 프로젝트를 진행하며 꼭 필요한 기능인지라, 시간이 지나며 의존성 관리를 위한 다양한 써드파티 라이브러리들이 등장하기 시작했습니다. 그리고 마침내 Go에서 의존성 관리를 위한 툴인 dep을 발표하였고, dep은 의존성 관리를 위한 공식 툴로 자리잡게 되었습니다.

dep은 강력하고, 유용하게 사용되긴 했지만 패키지 버저닝을 위한 궁극적인 커맨드 툴은 아니었습니다. 조금 더 Go-ish하고 넓은 범위에서 패키지를 관리할 툴이 필요했습니다. 그리고 마침내 Russ Cox의 제안으로 vgo 프로젝트가 패키지 버저닝을 위한 Go의 공식 프로젝트로 채택되었고, go 1.11 버전에서는 Go modules가 도입되어 시험적으로 사용할 수 있게 되었습니다.

vgo는 잠시 안녕...

go 1.10 상위 버전에서 vgo를 설치하여 Go modules을 사용할 수도 있지만, 이 글에선 go 1.11 버전의 go mod 커맨드를 통하여 Go modules을 사용할 예정입니다. vgo의 설치는 go get -u golang.org/x/vgo을 통해 하실 수 있습니다. 더 자세한 내용은 Go & Versioning에서 살펴보실 수 있습니다.

GO111MODULE

go 1.11 버전에서 Go modules가 등장하며 기존 GOPATHvendor/에 따라 동작하던 go 커맨드와의 공존을 위한 GO111MODULE이라는 임시 환경변수가 생겼습니다. 이 환경변수에는 세 가지 값이 올 수 있습니다.

GO111MODULE의 값이 on인 경우 go 커맨드는 GOPATH에 전혀 관계없이 Go modules의 방식대로 동작합니다. off인 경우에는 반대로, Go modules는 전혀 사용되지 않고 기존에 사용되던 방식대로 GOPATHverdor/를 통해 go 커맨드가 동작합니다.

만약 값을 설정하지 않았거나 auto로 설정한 경우, GOPATH/src 내부에서의 go 커맨드는 기존의 방식대로, 외부에서의 go 커맨드는 Go modules의 방식대로 동작합니다.

이 글에선 별도로 환경변수의 값을 설정하지 않고 진행하도록 하겠습니다.

시작하기

일단 프로젝트가 위치할 디렉터리를 만들도록 하겠습니다. 환경변수를 설정하지 않았으므로, Go modules을 사용하기 위해 프로젝트 디렉터리가 GOPATH/src 밖에 위치하도록 하겠습니다.

test/

이제 내부에 코드를 추가하도록 하겠습니다. 저는 echo를 사용한 간단한 서버 코드를 넣었습니다.

// main.go
package main // import "github.com/KimMachineGun/hello"

import (
	"net/http"
	
	"github.com/labstack/echo"
)

func main() {
	e := echo.New()

	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, World!")
	})

	e.Logger.Fatal(e.Start(":1323"))
}

위에서 주목해서 보셔야 할 곳은 첫 줄의 // import "github.com/KimMachineGun/hello" 입니다. 이는 모듈이 위치한 경로를 나타냅니다. 일반적으론 // import "github.com/<user-name>/<repo-name>"형태의 경로를 많이 사용합니다. 물론 이를 추가하지 않고 go mod init <module-name>을 사용하여 모듈을 생성할 수도 있습니다.

위 코드에선 모듈 경로를 소스 코드에 추가하였기 때문에 그냥 go mod init 커맨드를 실행하면 됩니다. 커맨드가 정상적으로 실행되었다면, 프로젝트 디렉터리의 내부 모습은 다음과 같을 것입니다.

test/
    go.mod
    main.go

go.mod 파일에는 현재 모듈에 대한 정보와 코드에서 사용하고 있는 외부 패키지에 대한 의존성 정보가 담기게 됩니다. 위 파일에는 아직 프로젝트 초기화 외의 다른 작업은 하지 않았기 때문에, 현재 모듈의 정보만 담겨있을 것입니다.