4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Goプログラム開発におけるモジュール管理

Posted at

Goプログラムでのパッケージ探索方法やモジュール管理についてざっくりと調べてみたので解説する。


GOPATHモードとモジュールモード

Goには、GOPATHモードとモジュールモードが存在しており、go.modが存在するか否かでGoが自動的に判断する。

  • go.modが有る:モジュールモード
  • go.modが無い:GOPATHモード

モジュールモードは、Go 1.16以降で利用可能になったモードで、GOPATH変数を使用しないように設計されている。
GOPATH変数の代わりにGoモジュールという仕組みを使用して依存関係を管理している。
GOPATHモードでは、GoパッケージはGOPATHディレクトリ以下に配置され、importパスの一部として指定していたが、モジュールモードではモジュールごとにgo.mod(モジュールファイル)が配置されることで管理している。



パッケージの探索手順

モジュールモードにおける、パッケージの探索は以下の手順で実行される。

  1. カレントディレクトリのvendorディレクトリ内
  2. モジュールキャッシュ
  3. モジュールのダウンロード先

まず現在のディレクトリにvendorディレクトリがある場合、その中にパッケージが存在するかを探索する。
次に、モジュールキャッシュ内にパッケージがあるかを確認して、それでもなければモジュールのダウンロード先にあるかを探索する。
モジュールキャッシュとは、モジュールをダウンロードしてビルドした結果を保存する場所で、デフォルトで$GOPATH/pkg/modに保存される。


GOPATHモードの場合のパッケージの探索は以下の通り

  1. カレントディレクトリのvendorディレクトリ内
  2. $GOPATH/srcディレクトリ内
  3. $GOROOT/srcディレクトリ内

GOROOT/srcはGoのインストールディレクトリを指定する環境変数のこと。GOROOTにGoの標準パッケージやコンパイラ、開発ツールが含まれる。



「パッケージ」について

Goコンパイラの処理単位を表している。ディレクトリ内の複数のGoファイルをパッケージとして処理している。
パッケージはそれぞれimportすることができ、絶対パスや相対パスを指定する。

import "github.com/myuser/mypackage"

go getまたはgo mod tidy コマンドを使って外部パッケージをダウンロードすることで参照可能となる。
また、Goの標準ライブラリには、fmt、os、io、netなどのパッケージが含まれており、それらのパッケージをimportして使用可能。



「モジュール」について

モジュールモードでは、標準ライブラリを除くパッケージを「モジュール」として管理している。Go1.11 以降はモジュールという考え方が導入され、Go1.10以前のGOPATHによるコードの一元管理から移行が進み、プロジェクト単位でディレクトリを自由な場所に置けるようになっている。
パッケージが一つのディレクトリを指しているのに対して、モジュールはgo.modファイルのあるディレクトリ以下の全てのパッケージがモジュール配下となる。



GOPATHが担う役割

GOPATHとはGoプログラムをビルドする際に、必要なパッケージやライブラリを保存する場所を指定する環境変数のこと。
goコマンドによってパッケージのソースコードをGOPATH/src配下から探し出し、パッケージをビルドして、バイナリをGOPATH/bin配下にインストールする。
このGOPATH配下には以下のようなディレクトリが存在する。

ディレクトリ構造

$GOPATH/
  |-src/
  |-pkg/
  |-bin/

・$GOPATH/src:
Goのソースコードが格納されるディレクトリ。Go modulesを無効としている場合は、importされたpackageの探索先として使用される。このディレクトリはGo modulesを使用することで不要になる。
    
・$GOPATH/pkg:
Goプログラムをビルドした際にソースコードからコンパイルされたオブジェクトが生成され、そのバイナリファイルが格納されるディレクトリ。
    
    
・$GOPATH/bin:
Goコマンドによりインストールしたパッケージのバイナリが格納されるディレクトリ。

Go modulesについて

Go Modulesを使って依存関係管理が可能。
このGo Modulesを利用する為には、環境変数のGO111MODULEを設定する必要がある。

Go Modules 役割
auto Goモジュールが有効になっている場合、モジュールモードでビルドが行われる。無効な場合は、GOPATHモードでビルドが行われる。
on 常にモジュールモードでビルドが行われる。
off 常にGOPATHモードでビルドが行われる。

Go modulesを有効化しておくことで、packageの探索先として GOPATH/srcを使用する必要がなくどこでも開発が可能となる。

go modulesを有効にする為には.zshrcファイルを開いて、GO111MODULE=onにすれば設定可能。

open ~/.zshrc
export GO111MODULE=on 

export GO111MODULE=on



go.modについて

既に何度も登場しているgo.modについて解説する。
go.modはモジュールを追跡し、依存関係を管理するためのもの。

That module is defined by a go.mod file that tracks the modules that provide those packages. That go.mod file stays with your code, including in your source code repository.
Tutorial: Get started with Go


go.modの作成

go.mod init コマンドを使用してgo.modファイルを作成する。

go mod init example/hello
go: creating new go.mod: module example/hello

go mod tidy

モジュール管理を行う中で使用しなくなったパッケージを削除するためのコマンド。

go mod tidy ensures that the go.mod file matches the source code in the module. It adds any missing module requirements necessary to build the current module’s packages and dependencies, and it removes requirements on modules that don’t provide any relevant packages. It also adds any missing entries to go.sum and removes unnecessary entries.
Tutorial: Get started with Go

go mod tidy
go: finding module for package rsc.io/quote
go: found rsc.io/quote in rsc.io/quote v1.5.2

go mod tidy -vで削除されたパッケージの情報が表示される。

go mod tidy -v
unused rsc.io/quote



モジュールモードで外部パッケージをimportする場合

モジュールモードの場合、go.modファイルが置かれる。

├── go.mod
└── main.go
main.go
package main

import (
    "os"
    "fmt"
    "gopkg.in/ini.v1" // 外部パッケージをインポート
)

goは$GOPATH/pkg/mod内にパッケージがあるかどうかを確認しにいく。


go.mod
module go-sample

go 1.19
require gopkg.in/ini.v1 v1.67.0 // indirect



モジュールモードで内部パッケージをimportする場合

内部パッケージをimportは以下の通り

├── go.mod
└── main.go
└── config.ini // 内部ライブラリ
└── utils
      └── logging.go // 内部ライブラリ
package main

import (
	"fmt"
	"./config"
	"./utils"
)

func main() {
	utils.LoggingSettings(config.Config.LogFile)
	fmt.Println(config.Config.ApiKey)
}




■ 参考文献

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?