はじめに
バックエンドは Ruby, TypeScript 等を触ってきて、「Go やるか!」と思って手を出してみたものの、みごとにハマりました。(悪い意味で)
他言語から来た人がGoを使い始めてすぐハマったこととその答え
こちらの記事を読ませていただいて、そこでやっと色々と解決できました…
ここには、上記の記事を読むだけでは解決できなかった課題に立ち向かった記録を残しておきます。
使用環境
- macOS Catalina 10.15.4
Docker で環境構築
Docker コンテナ内で動かしたいので、golang の公式イメージを使って環境を作ります。
テキストエディタの補完だったりに必要そうであればローカルにもインストールしておきます。
Go には「GOPATH
以下に作業環境を作る」という特徴があるようで、ここが第一つまづきポイントでした。
Docker で作業する場合でも、これに従った構成にします。
docker-compose
version: "3.8"
services:
go:
image: golang:1.13.10
working_dir: /go/src/github.com/{ユーザー名}/{リポジトリ名}
volumes:
- .:/go/src/github.com/{ユーザー名}/{リポジトリ名}
GOPATH
$ docker-compose run go /bin/bash -c "go env"
...
GOPATH="/go"
ディレクトリ構成
/go
└── src
└── github.com
└── {ユーザー名}
└── {リポジトリ名}
├── docker-compose.yml
└── main.go
モジュール管理
プロジェクト内に使用するモジュールの一覧を保持して、git で管理して、というようなことをやりたかったのですが、手順がよくわからずまた少し詰まっていました。
以降の操作はすべて、dockerコンテナ 内での実行を前提としています。
go1.13 未満
go のバージョンが 1.13 未満の場合、後述する go mod init
等のコマンドをそのまま実行しようとすると、下記のエラーが出て実行できません。
go: modules disabled inside GOPATH/src by GO111MODULE=auto; see 'go help modules'
環境変数を設定してから実行することで正常に実行できます。
$ export GO111MODULE=on
go.mod の作成
プロジェクトで go mod
系のコマンドを初めて実行する場合、まず init
で初期化します。
$ go mod init
すると、 go.mod
のファイルが作成されます。
vendor でモジュール管理
$ go mod vendor
このコマンドで、必要なモジュールを vendor
ディレクトリに保持します。
未ダウンロードのモジュールがあった場合は、モジュールのダウンロードプロセスが先に走ります。
vendor
フォルダと go.sum
ファイルが作成されれば成功しているはず。
これで各種モジュールが使えるようになります。
vendor を作成したくない場合は go mod download
等のコマンドだけ使えば良さそうです。
go mod download
のあとに go mod vendor
すると、download で引っ張ってきたモジュールが既にローカルにあるので、ダウンロード処理は走らず、ささっと vendor のみが作成されます。
他言語に置き換えると?
使用モジュールの管理 | 依存性管理 | 本体 | |
---|---|---|---|
Go | go.mod | go.sum | vendor |
Node.js | package.json | package-lock.json | node_modules |
Ruby | Gemfile | Gemfile.loc | vendor/bundle |
こんな感じの関係性になるのかなと思っています。
ディレクトリ構成
/go
└── src
└── github.com
└── {ユーザー名}
└── {リポジトリ名}
├── docker-compose.yml
├── go.mod
├── go.sum
├── main.go
└── vendor
├── 各種モジュール
└── modules.txt
さいごに
なにぶん初学者ゆえ、『ちげぇよコノヤロー!』な箇所があればやさしくご指摘お願いしたいですm(_ _)m