VSCode + Remote ContainerでGoの開発環境を作ったけどimportできなくて悩んだ話
概要
前回の記事でVSCodeでDockerのDevContainerをサクッと起動して、OS環境を汚さない快適開発環境を作れるようになったけど、Goでサンプル実装しようとすると、どうにもうまく行かない。
具体的には、自分の作ったpackageをimportできない。
情報を色々検索したところ、Goの推奨する標準構成が色々変わったことに、インターネッツの記事が追いついていなく、新旧の情報が錯綜しているためだった。
結果的に解決できたので、その備忘録を書いておく。
結論
結論から書くと、こちらのサイトを最初から参考にして環境作っておけばよかった・・・という話・・・
Go 脱初心者への道
- GOPATHは今はもう使わず、go modを活用しましょう
- srcフォルダは使わず、cmdを使いましょう
やったこと
失敗の歴史
前回のように構築したあと、main.goのみの実行は問題なく出来、よしよしと思い、入門編をやり始めた。
gihyo.jpのこちらを参考に、少し古いけど大まか変わらないだろう、と考えて、[こちら]をやり始めたところ、importがうまく行かない・・・
gosampleモジュールをvscode上でも認識してくれないし、実際にビルドもできない。
よくある、コンテナ内でのパスの問題かなと思い、GOPATHやGOROOTの設定を変えようとしてみた。
こちらとかに書いてあるように
devcontainer.jsonをいじって、workspaceMount
やworkspaceFolder
を変更してみたが、コンテナのビルド時にエラー・・・
GOPATHを変更しようとしても、うまく行かない・・・ということで色々調べていると、こちらのサイトにたどり着く。
go mod完全に理解した
go mod周辺を理解してないとGo言語使った開発辛いと思うんですが、ネットの日本語情報少なくないすか?
最近はGOPATH使わないと思うんですが、古い情報が引っかかってきて、検索するのが辛いです。GOPATH使う時とgo mod使うときの比較情報も、あたらしくGo言語やる人的にはいらないと思うし。変更点は良いから、最新版の体系的な情報をくれよ、ってなってました。
ほんこれ・・・
つまるところ、プロジェクトルートにgo.modを起きましょうという話のよう。
喜び勇んでプロジェクトのルートフォルダでgo mod init [プロジェクト名]
としてみた・・・が、変わらず。
最終的には、冒頭で紹介したこちらにたどり着いたことで、無事解決・・・
解答編
まず、上記ブログにあるように、フォルダ構成はsrcを使わないようになってきているよう。
(ただ、今回の問題とは根本的には関係ない)
こちらのGithubリポジトリにフォルダ構成の有志によるオススメ例があるので、参考にさせてもらう。
日本語READMEもあるし、参考になるリポジトリが紹介されているのも◎。
上記フォルダ構成をベースに、gihyo.jpのサンプルコードを実装すると、図のような感じ。
main.goの中でgosampleが相変わらず解決できずエラーになっている。
そこで、ワークフォルダルートで以下を実行。
vscode ➜ /workspaces/test3 $ pwd
/workspaces/test3
vscode ➜ /workspaces/test3 $ go mod init test3
go: creating new go.mod: module test3
go: to add module requirements and sums:
go mod tidy
vscode ➜ /workspaces/test3 $
以下のようなgo.modができる。
ただ、相変わらずgosampleは見つからない。
この理由は2つ。
- go.modを使う場合は、importするときに「相対パス」を指定する必要がある
- モジュール名がローカルフォルダを指す場合は、
replace
を指定する必要がある
replace
についてはこちら。
go.modはこうなる
module test3
go 1.17
replace (
test3 v0.0.0 => ./
)
main.goはこう
package main
import (
"fmt"
"test3/internal/gosample" //"test3/internal"を追記
)
func main() {
fmt.Println(gosample.Message)
}
無事、エラーが消えた!!
補足
ちなみに、上記でtest3
とした部分は、公開リポジトリの場合は例えばGithubのパスを指定するが、非公開であれば何でも良い。
何でもいい理由は、replace
で読み替えちゃうから、ということでした。
この辺がマジでわかりにくかった・・・
ちなみに、公開リポジトリを指定すると、ビルド時に$GOPATH/pkg/mod
にインストールされるらしいよ。
(やってないし、あとでまた苦労しそうな予感・・・)
あとたぶん、DevContainerでGoの環境作っただけだと関連ツールがインストールされていないぽいので、こちらもやっておいたほうが良さそうですね。
まとめ
Goは言語の名称のググラビリティが低いだけじゃなくて、挙動や最新情報のググラビリティも低い・・・
動けばええやんじゃなくて、解決にたどり着けてよかったよかった。
というか、ほぼ全て@shellylnさんのおかげでした。ありがとうございます。
Discussion