😿

Go modules について

2020/10/20に公開

(作成2020.10.20 / 補足2021.03.04)

Go modules とは

以前の記事「Go言語 Hello World」で作業ファイルは「go/src」以下に置くとよいと書きましたが、実はこれバージョン1.11までの話。もちろんこのままでOKだし、私自身今のところこのままでコーディングしているのもありますが、実はこの縛りはすでに対応されていてもっとたくさんのプロジェクトを抱えた人にとってはコードがあちこちに散らからないように整理する仕組みが設けられています。それがGo modulesです。

もう少しこれまでの仕様の話をさせて

引用するパッケージ(ライブラリ)もgo/src以下に保存されるので自分のプロジェクトと紛れ込むことになり(まぁ自分で把握してないわけはないので問題ないといえばないのだが。)、特にプロジェクトごとにライブラリのバージョンを変えたい(例えば、昔に作ったプロジェクトが新しいライブラリだと動かないとか、動くかどうか確認するのが面倒とかで)というようなことができませんでした。それで、プロジェクトの中に「vendor」という名前でディレクトリを作成し、その中に適用するライブラリを保存することでバージョン管理をすることを可能にしてました。govendorというサードパーティーツールを使って

$ govendor add +e

とすると自動的に保存してくれます。

Go modules ができました

バージョン1.12以降はGo modulesを使います。ちなみにバージョン1.11は移行期バージョンなのでgo envを次のように設定することで使用可能になります。

go env -w GO111MODULE=on

Go modulesの使い方

とりあえずは次のコマンドを打ち込んでみましょう。

$ mkdir testprj
$ cd testprj
$ go mod init testprj // 初期化 package名(ディレクトリ名)を指定
$ cat go.mod // 初期化して作成されたファイルを見てみる
$ touch main.go // goコード用ファイルを新規作成する
$ code main.go // visual studio code でgoコードを作成する
$ go build // build(コンパイル)する
$ cat go.mod // go.modeを見てみると、依存するパッケージが追加されている
$ go get ライブラリ // ライブラリ(外部パッケージ)を取得する
$ cat go.mod // 取得したライブラリが追加されている(ただし、ここではコードで使っていないので注釈がつく)
$ go mod tidy // ライブラリを整理する(コードで使っていないライブラリが削除される)

main.goは引用するライブラリ(外部パッケージ)を含めて作成します。
上記を実行してみれば、動きはなんとなく掴めるのではないでしょうか。

既存プロジェクトへの適用

これもいろいろ書くとごちゃごちゃするので要点だけ。

$ cd oldprj
$ go mod init oldprj
$ go build

要するに初期化してbuildするだけで、コードをsrcディレクトリ下におかなくてもライブラリが参照可能になるよという話。go.modファイルの中身とかgo mod tidyで整理するとか取得したライブラリはどこに保存されたとかは最初のうちは意味不明で放っておいてよく、そのうちに暇なときにでも眺めてみれば理解できるようになるのではないかなと思います。
ちなみに、取得したライブラリはGOPATHのgoディレクトリ下に保存・一括管理され、go mod initで初期化したpackageごとにgo.modで参照する仕組みになっています。

Discussion