ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Go 언어 개발 환경 설정 - go mod init과 그 필요성
    Go 2024. 3. 3. 21:44

     

     

    안녕하세요?

     

    Go 언어에 푹 빠져서 요즘 계속 배우고 있는데요.

     

    Go 언어(일명 Golang)는 Google에서 개발한 정적 타입 언어로 빠르고 안전한 프로그램을 작성하는 데 많이 사용됩니다.

     

    그러나 처음 Go 언어를 접할 때 go mod init이라는 명령어를 만나면 이게 뭔지 혼란스러울 수 있는데요.

     

    이 글에서는 go mod init가 무엇이며 왜 필요한지 자세히 살펴 보겠습니다.

     

    ** 목차 **


    Go 모듈이란?

    Go 언어에서는 코드 패키지를 구성하고 버전 관리하기 위해 모듈이라는 개념이 도입되었습니다.

     

    모듈은 Go 코드의 집합으로 특정 디렉토리에 배치됩니다.

     

    각 모듈은 고유한 이름을 가지며 다른 모듈에서 참조됩니다.


    go mod init이란?

    go mod init은 새로운 Go 모듈을 초기화하는 명령어입니다.

     

    이 명령어를 실행하면 모듈 이름을 매개변수로 받아 해당 이름으로 새로운 모듈을 생성합니다.

     

    또한 이 명령어는 go.mod라는 특별한 파일을 생성합니다.

     

    이 파일에는 모듈 이름과 해당 모듈이 의존하는 다른 모듈의 정보가 포함됩니다.

     

    예를 들어 다음 명령어를 실행하면 github.com/cpro95/GoProject라는 이름의 새로운 모듈이 생성됩니다:

    $ go mod init github.com/cpro95/GoProject

    go mod init이 왜 필요한가요?

    Python과 비교할 때 Go 언어에서는 패키지(또는 모듈) 관리가 필요합니다.

     

    Python에서는 스크립트를 작성하고 실행하는 것만으로 충분하지만, Go 언어에서는 코드가 어떤 패키지에 속하는지 명시적으로 표시해야 합니다.

     

    이는 Go가 컴파일 언어이며 실행 파일을 생성할 때 의존성을 해결해야 하기 때문입니다.

     

    또한 Go 언어에서는 각 패키지가 독립적으로 테스트, 컴파일, 버전 관리되는 것이 필요합니다.

     

    이를 통해 대규모 프로젝트에서도 코드 관리가 용이해집니다.

     

    따라서 go mod init 명령어는 새로운 프로젝트를 시작할 때 첫 번째 단계로, 프로젝트의 기반이 되는 모듈을 생성합니다.


    Go 언어에서의 모듈 관리

    먼저 go mod init을 실행하여 새로운 Go 모듈을 초기화합니다.

     

    이전과 같이 github.com/cpro95/GoProject라는 이름의 모듈을 만들어 보겠습니다.

     

    $ go mod init github.com/cpro95/GoProject

     

    이 명령을 실행하면 현재 디렉토리에 go.mod라는 파일이 생성됩니다.

     

    이 go.mod 파일은 다음과 같은 내용을 담고 있습니다:

    $ go mod init github.com/cpro95/GoProject
    go: creating new go.mod: module github.com/cpro95/GoProject
    
    $ ls -l
    total 8
    -rw-r--r--@ 1 cpro95  staff    46B  3  3 21:31 go.mod
    
    $ cat go.mod
    module github.com/cpro95/GoProject
    
    go 1.21.6

     

    이 go.mod 파일은 프로젝트가 어떤 패키지에 의존하는지 Go 도구 체인에 알려줍니다.

     

    예를 들어, 프로젝트가 github.com/gin-gonic/gin이라는 외부 패키지에 의존한다고 가정해 보겠습니다.

     

    그렇다면 다음 명령을 실행하여 해당 패키지를 설치할 수 있습니다:

    $ go get github.com/gin-gonic/gin
    go: downloading github.com/gin-gonic/gin v1.9.1
    go: downloading github.com/gin-contrib/sse v0.1.0
    go: downloading github.com/mattn/go-isatty v0.0.19
    go: downloading golang.org/x/net v0.10.0
    go: downloading github.com/bytedance/sonic v1.9.1
    go: downloading github.com/goccy/go-json v0.10.2
    go: downloading github.com/json-iterator/go v1.1.12
    go: downloading github.com/go-playground/validator/v10 v10.14.0
    go: downloading github.com/pelletier/go-toml/v2 v2.0.8
    go: downloading github.com/ugorji/go/codec v1.2.11
    go: downloading google.golang.org/protobuf v1.30.0
    go: downloading gopkg.in/yaml.v3 v3.0.1
    go: downloading golang.org/x/sys v0.8.0
    go: downloading github.com/modern-go/reflect2 v1.0.2
    go: downloading github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
    go: downloading golang.org/x/text v0.9.0
    go: downloading github.com/gabriel-vasile/mimetype v1.4.2
    go: downloading github.com/go-playground/universal-translator v0.18.1
    go: downloading github.com/leodido/go-urn v1.2.4
    go: downloading golang.org/x/crypto v0.9.0
    go: downloading github.com/go-playground/locales v0.14.1
    go: downloading github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311
    go: downloading golang.org/x/arch v0.3.0
    go: downloading github.com/twitchyliquid64/golang-asm v0.15.1
    go: downloading github.com/klauspost/cpuid/v2 v2.2.4
    go: added github.com/bytedance/sonic v1.9.1
    go: added github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311
    go: added github.com/gabriel-vasile/mimetype v1.4.2
    go: added github.com/gin-contrib/sse v0.1.0
    go: added github.com/gin-gonic/gin v1.9.1
    go: added github.com/go-playground/locales v0.14.1
    go: added github.com/go-playground/universal-translator v0.18.1
    go: added github.com/go-playground/validator/v10 v10.14.0
    go: added github.com/goccy/go-json v0.10.2
    go: added github.com/json-iterator/go v1.1.12
    go: added github.com/klauspost/cpuid/v2 v2.2.4
    go: added github.com/leodido/go-urn v1.2.4
    go: added github.com/mattn/go-isatty v0.0.19
    go: added github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
    go: added github.com/modern-go/reflect2 v1.0.2
    go: added github.com/pelletier/go-toml/v2 v2.0.8
    go: added github.com/twitchyliquid64/golang-asm v0.15.1
    go: added github.com/ugorji/go/codec v1.2.11
    go: added golang.org/x/arch v0.3.0
    go: added golang.org/x/crypto v0.9.0
    go: added golang.org/x/net v0.10.0
    go: added golang.org/x/sys v0.8.0
    go: added golang.org/x/text v0.9.0
    go: added google.golang.org/protobuf v1.30.0
    go: added gopkg.in/yaml.v3 v3.0.1

     

    이 명령을 실행하면 Go는 해당 패키지를 다운로드하고 프로젝트에서 사용할 수 있도록 합니다.

     

    또한 go.mod 파일도 자동으로 업데이트되어 다음과 같이 보일 것입니다:

    $ cat go.mod
    module github.com/cpro95/GoProject
    
    go 1.21.6
    
    require (
        github.com/bytedance/sonic v1.9.1 // indirect
        github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
        github.com/gabriel-vasile/mimetype v1.4.2 // indirect
        github.com/gin-contrib/sse v0.1.0 // indirect
        github.com/gin-gonic/gin v1.9.1 // indirect
        github.com/go-playground/locales v0.14.1 // indirect
        github.com/go-playground/universal-translator v0.18.1 // indirect
        github.com/go-playground/validator/v10 v10.14.0 // indirect
        github.com/goccy/go-json v0.10.2 // indirect
        github.com/json-iterator/go v1.1.12 // indirect
        github.com/klauspost/cpuid/v2 v2.2.4 // indirect
        github.com/leodido/go-urn v1.2.4 // indirect
        github.com/mattn/go-isatty v0.0.19 // indirect
        github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
        github.com/modern-go/reflect2 v1.0.2 // indirect
        github.com/pelletier/go-toml/v2 v2.0.8 // indirect
        github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
        github.com/ugorji/go/codec v1.2.11 // indirect
        golang.org/x/arch v0.3.0 // indirect
        golang.org/x/crypto v0.9.0 // indirect
        golang.org/x/net v0.10.0 // indirect
        golang.org/x/sys v0.8.0 // indirect
        golang.org/x/text v0.9.0 // indirect
        google.golang.org/protobuf v1.30.0 // indirect
        gopkg.in/yaml.v3 v3.0.1 // indirect
    )

     

    위 require 줄은 프로젝트가 github.com/gin-gonic/gin 등 여러 패키지에 의존한다는 것을 나타냅니다.

     

    이와 같이 Go의 모듈 시스템은 프로젝트의 의존성을 명확하게 관리하는 데 도움이 됩니다.


    도구 체인이란?

    도구 체인은 일련의 프로그래밍 도구를 가리킵니다.

     

    이 도구들은 함께 작동하여 코드 편집부터 테스트, 빌드, 배포까지의 개발 프로세스를 지원합니다.

     

    Go 언어의 도구 체인에는 코드를 포맷하는 gofmt, 패키지 문서를 생성하는 godoc, 코드를 빌드하는 go build, 테스트를 실행하는 go test, 의존 패키지를 다운로드하는 go get 등이 포함됩니다.

     

    이 도구들은 함께 작동하여 Go 코드의 개발, 테스트, 배포를 원활하게 수행할 수 있도록 도와줍니다.


    외부 패키지 github.com/gin-gonic/gin에 대하여

    Go 언어에서는 코드의 재사용성을 높이기 위해 패키지 단위로 코드를 분할합니다.

     

    이를 통해 한 번 작성한 코드를 다른 프로그램에서도 사용할 수 있게 됩니다.

     

    github.com/gin-gonic/gin은 Go 언어에서 고성능 HTTP 웹 프레임워크를 제공하는 외부 패키지 중 하나입니다.

     

    gin은 라우팅, 미들웨어, JSON 유효성 검사, 테스트 코드 생성 등 웹 애플리케이션 개발에 필요한 다양한 기능을 제공합니다.

     

    Go 언어의 강력한 점 중 하나는 이러한 외부 패키지를 프로젝트에 쉽게 통합할 수 있다는 점입니다.

     

    예를 들어, 위의 gin 패키지를 프로젝트에 통합하려면 단순히 go get github.com/gin-gonic/gin 명령을 실행하면 됩니다.

     

    이를 통해 Go는 필요한 코드를 자동으로 다운로드하고 프로젝트에서 사용할 수 있게 됩니다.

     

    그렇다면 왜 이러한 모듈 관리가 필요한 걸까요?

     

    그 답은 "의존성 지옥"을 피하기 위해서입니다.

     

    "의존성 지옥"은 한 애플리케이션이 다수의 라이브러리에 의존하고, 각 라이브러리가 또 다른 라이브러리에 의존하는 경우 발생합니다.

    이러한 의존 관계가 복잡하게 얽혀있어 버전 관리가 어려워집니다.

     

    하지만 Go의 모듈 관리에서는 각 모듈이 어떤 버전의 패키지에 의존하는지 go.mod 파일에 명시적으로 기록되어 있습니다.

     

    이를 통해 프로젝트 전체에서 일관된 의존 관계를 유지할 수 있습니다.

     

    또한 go.mod 파일이 있는 디렉토리를 기준으로 Go 도구는 해당 디렉토리를 모듈의 루트로 간주하고 의존성을 해결합니다.

     

    이를 통해 모듈 내의 모든 Go 파일이 일관된 빌드 결과를 가지도록 보장됩니다.

     

    그럼 다음에는 Go 언어의 모듈관리를 Python과 Java의 비교를 살펴보겠습니다.


    Python의 의존성 관리와 모듈 관리

    Python에서는 패키지 관리를 주로 pip라는 도구를 사용하여 수행합니다.

     

    pip는 Python 패키지 관리 시스템으로, Python 라이브러리를 설치, 업그레이드 및 제거하는 명령 줄 도구입니다.

     

    또한, Python의 의존성 관리는 일반적으로 requirements.txt 또는 Pipfile과 같은 파일에 의존 패키지 목록을 기록하여 수행합니다.

     

    예를 들어, requirements.txt 파일에 다음과 같이 기록하면,

    numpy==1.18.1
    scipy==1.4.1

     

    이러한 패키지는 pip install -r requirements.txt 명령을 사용하여 일괄적으로 설치할 수 있습니다.

     

    또한, Python은 venv나 pipenv와 같은 도구를 사용하여 프로젝트별로 독립적인 환경을 만들 수 있으며, 이를 통해 각 프로젝트마다 다른 패키지 버전을 관리할 수 있습니다.


    Java의 의존성 관리와 모듈 관리

    Java에서는 의존성 관리는 주로 Maven이나 Gradle과 같은 빌드 도구를 사용하여 수행합니다.

     

    이러한 도구는 pom.xml이나 build.gradle과 같은 설정 파일에 의존 라이브러리 목록을 기록하여 필요한 라이브러리를 자동으로 다운로드하여 프로젝트에 통합하는 기능을 제공합니다.

     

    Java 9 이상에서는 모듈 시스템이 도입되어 대규모 프로젝트의 코드를 더 효율적으로 관리할 수 있는 기능이 제공됩니다.

     

    모듈은 관련된 패키지와 리소스의 집합으로, 모듈 간의 의존성을 명시적으로 지정할 수 있습니다.

     

    이와 같이 Python과 Java는 각각 고유한 방식으로 패키지 및 의존성 관리를 수행합니다.

     

    Go 언어도 이러한 개념을 가지고 있으며, 각각의 방법을 통해 대규모 프로젝트에서도 효율적으로 개발할 수 있습니다.


    결론

    Go 언어 개발에는 모듈 개념과 go mod init 명령을 사용하는 것이 필수입니다.

     

    이는 Go가 컴파일 언어이며 패키지 의존성 관리가 중요하기 때문입니다.

     

    Python과 달리 Go는 코드 구성과 관리를 언어 자체에 내장하고 있습니다.

     

    이를 통해 대규모 프로젝트에서도 효율적으로 개발할 수 있습니다.

Designed by Tistory.