Go Modules

web comdori·2021년 3월 14일
0

write-in-go

목록 보기
1/4

참고 : https://golangbyexample.com/package-vs-module-golang/

개요

  • 모듈이란?
    - 버전이 붙은 패키지들의 묶음.
    - 루트에 go.mod 가 존재함.
  • 모듈이 제공하는 것
    - 의존성관리
    • 모듈로 작업하면 더이상 $GOPATH/src에 project를 놓을 필요가 없음.

go.mod 파일 외에서 go는 모든 프로젝트의 의존 모듈의 비트 암호화 해시를 포함하는 go.sum 파일도 유지한다. 이를 통해 의존 모듈이 변경되지 않았는지 확인한다.

모듈 내부의 패키지 동작은 이전과 동일하다. 그러나 별도로 버전을 지정해야하는 경우 패키지 모음을 모듈로 호출할 수 있다.

Module 이 있기 전에는...

  • Go Version 1.11 이전 - Module이 없었음
  • Go Version 1.11 - Module이 소개가 됨
  • Go Version 1.13 - Module이 default가 됨

Go Version 1.11 이전

module이 나오기 전에는 go는 package만 가지고 있었다. $GOPATH 위치에는 아래와 같이 3가지 디렉토리가 있었다.

  • src, pkg, bin

이때 존재했던 문제

  • 모든 go project는 $GOPATH/src 디렉토리에 있었다.
  • native 의존성 관리 지원이 없었다.
  • 모든 의존성은 $GOPATH/src 디렉토리로 versioning 없이 다운로드 되었다.

한가지씩 문제를 살펴보자

  • 모든 go project는 $GOPATH/src 디렉토리에 있었다.

이 것은 당신의 프로젝트를 유지하는데 큰 제한이 되었다.

  • native 의존성 관리 지원이 없었다.

프로젝트의 의존성을 지정할 수 없었다. 대안으로는 dep, glide가 가능했으나 native solution은 없었다.

go get을 했을 때, 이것은 $GOPATH/src 디렉토리에 필요한 package를 다운로드 했다. 예를 들어, 아래의 커맨드를 수행하면...

go get github.com/pborman/uuid

그 package를 아래 위치에 다운로드 했다.

$GOPATH/src/github.com/pborman/uuid

Go Version 1.11

Go 1.11에서 module 개념이 소개가 되었으나, 완성되지 않았다. 만약 이 버전을 사용하고 있다면 최신 버전으로 업데이트 하세요.

Go Version 1.13 이후

module이 나오면서 위의 문제가 해결되었다.

  • 모든 go project는 $GOPATH/src 디렉토리에 있었다.
    - 디렉토리의 제한이 없다.
  • native 의존성 관리 지원이 없었다.
    - Module은 go 내에서 네이트브 종속성 관리를 도입했다.
    • 모듈을 통해 두 개의 새로운 파일을 제공한다.
      • go.mod / go.sum
        • go.mod와 go.sum 파일이 있다면, 다른 곳에 영향을 미치지 않고 정확한 버전의 설치가 가능하다.
  • 모든 의존성은 GOPATH/src디렉토리로versioning없이다운로드되었다.다른버전의같은라이브러리를다운로드한다면GOPATH/src 디렉토리로 versioning 없이 다운로드 되었다. - 다른 버전의 같은 라이브러리를 다운로드 한다면 **GOPATH/pkg/mod에 다른 디렉토리로 overriding 없이 다운로드 될 것이다. $GOPATH/pkg/mod**는 내부에 두 가지를 가진다.
    1. cache : 모든 의존성이 압축된 코드와 함께 다룬로드되는 폴더
    2. 다운로드 된 모든 종속성의 압축 코드는 캐시 디렉토리에서 복사된다.

module을 한 번 만들어보자.

Module 생성하기

아래의 커맨드는 Module을 생성한다.

$ go mod init {module_import_path}

module을 한 번 만들어보자

$ cd ~/Workspace
$ mkdir learn
$ cd learn
$ go mod init learn
$ ls
go.mod

이 커맨드는 go.mod 파일을 동일 폴더에 생성한다. 이제 go.mod 파일이 무엇인지 보자.

$ cat go.mod
module learn

go 1.16

이것은 module import path와 module이 생성될 때의 go version을 포함한다.

empty module이기 때문에 아직 특별한 것은 없다. uuid.go라는 파일을 동일 폴더에 만들고...

$ vi uuid.go

아래 내용을 작성한다.

package main

import (
	"fmt"
	"strings"

	"github.com/pborman/uuid"
)

func main() {
	uuidWithHyphen := uuid.NewRandom()
	uuid := strings.Replace(uuidWithHyphen.String(), "-", "", -1)
	fmt.Println(uuid)
}

uuid.go에 dependency를 import 했다는 것에 주목하자.

"github.com/pborman/uuid"

그리고 아래의 커맨드를 수행한다.

$ go mod tidy
go: finding module for package github.com/pborman/uuid
go: downloading github.com/pborman/uuid v1.2.1
go: found github.com/pborman/uuid in github.com/pborman/uuid v1.2.1
go: downloading github.com/google/uuid v1.0.0

이 커맨드는 소스파일에 필요한 모든 dependencies를 다운로드하고 go.mod 파일을 업데이트한다. 이 커맨드를 수행한 이후 go.mod 파일을 보아라.

$ cat go.mod
module learn

go 1.16

require github.com/pborman/uuid v1.2.1

이것은 uuid 파일에 지정된 direct dependency와 정확한 version을 list합니다. 이제 go.sum file도 확인해보겠습니다.

$ cat go.sum
github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=

go.sum 파일은 direct/indirect dependency 체크섬을 리스트화 합니다. github.com/google/uid는 내부적으로 github.com/pborman/uuid를 사용합니다. 이것이 dl module의 indirect dependencyㅇ며, go.sum 파일에 저장됩니다.

profile
(wanna be a) Full-Stack Engineer

0개의 댓글