🐷

VSCode + Remote ContainerでGoの開発環境を作ったけどimportできなくて悩んだ話

2021/10/21に公開

概要

前回の記事で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をいじって、workspaceMountworkspaceFolderを変更してみたが、コンテナのビルド時にエラー・・・
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つ。

  1. go.modを使う場合は、importするときに「相対パス」を指定する必要がある
  2. モジュール名がローカルフォルダを指す場合は、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さんのおかげでした。ありがとうございます。

GitHubで編集を提案

Discussion