今までのモジュール管理方法はこちらをご覧ください。
実行環境
- M1 Macbook Air
- macOS Monterey 12.4
- Go 1.18
WindowsでもGoがちゃんとインストールされていれば大丈夫です。
workspaceモードとは
複数のモジュールを一つのgo.workというファイルで管理し、モジュール間の行き来をスムーズにすると言うものです。
go 1.18
use (
./module1
./module2
)
このような感じでmoduleを複数管理することができます。
workspaceのコマンド
いくつかコマンドがあるのですが、よく使うinitとuseコマンドを紹介します。
init
go.workファイルを初期化する時に使います。
% go work init
initの後ろに既に作成しているモジュールを追加することができます。
go work init モジュール名
use
既にgo.workファイルを作成しており新たにモジュールを追加したい時に使います。
% go work use モジュール名
複数のモジュールを追加したい時は、スペースを空けて書きます。
% go work use モジュール1 モジュール2
実際にやってみよう
まずはディレクトリを作成しましょう。
今回はworkspaceという名前でディレクトリを作成して、workspaceディレクトリに移動します。
% mkdir workspace && cd workspace
workspaceディレクトリでhelloディレクトリを作成して、helloディレクトリに移動します。
workspace % mkdir hello && cd hello
helloディレクトリ
helloディレクトリでhello.goを作成します。
hello % touch hello.go
hello.goを記述します。
package hello
import "fmt"
func Hello(name string) {
fmt.Printf("Hello, %s!", name)
}
helloディレクトリでgo.modを作成します。
hello % go mod init example.com/hello
go: creating new go.mod: module example.com/hello
go: to add module requirements and sums:
go mod tidy
mainディレクトリ
workspaceに戻ってhelloディレクトリと同じ手順でmainディレクトリを作成して、mainディレクトリに移動します。
hello % cd ../
workspace % mkdir main && cd main
mainディレクトリでmain.goを作成します。
main % touch main.go
main.goを記述します。
package main
import "example.com/hello"
func main() {
hello.Hello("Yuuki")
}
mainディレクトリでgo.modを作成します。
main % go mod init example.com/main
go: creating new go.mod: module example.com/main
go: to add module requirements and sums:
go mod tidy
このままでは、main.goを実行してもエラーになってしまいます。
main % go run main.go
main.go:3:8: no required module provides package example.com/hello; to add it:
go get example.com/hello
go.workを作成する
では、workspaceディレクトリに戻ってgo.workを作成してみましょう。
main % cd ../
workspace % go work init main hello
workspaceディレクトリにこのようなgo.workファイルが作成されました。
go 1.18
use (
./hello
./main
)
実行してみる
mainディレクトリに移動してmain.goを実行してみましょう。
workspace % cd main
main % go run main.go
Hello, Yuuki!
ちゃんと動きました!
今までのように、必要なところにいちいちreplace文を書く必要がなく、このようにgo.work作成するだけで簡単に他のモジュールのメソッドを使えますね!
ディレクトリ構造はこのようになっています。
workspace % tree
.
├── go.work
├── hello
│ ├── go.mod
│ └── hello.go
└── main
├── go.mod
└── main.go
新しいモジュールを追加してみる
今回はフレームワークのechoを利用してサーバーの起動のモジュールを作成します。
workspaceディレクトリに新しくserverファイルを作成して移動します。
workspace % mkdir server && cd server
serverディレクトリでgo.modファイルを作成します。
server % go mod init example.com/server
go: creating new go.mod: module example.com/server
serverディレクトリでechoをインストールします。
server % go get github.com/labstack/echo/v4
go: added github.com/labstack/echo/v4 v4.7.2
go: added github.com/labstack/gommon v0.3.1
go: added github.com/mattn/go-colorable v0.1.11
go: added github.com/mattn/go-isatty v0.0.14
go: added github.com/valyala/bytebufferpool v1.0.0
go: added github.com/valyala/fasttemplate v1.2.1
go: added golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
go: added golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f
go: added golang.org/x/sys v0.0.0-20211103235746-7861aae1554b
go: added golang.org/x/text v0.3.7
serverディレクトリにgo.sumが作成され、go.modとgo.sumがこのようになっていると思います。
module example.com/server
go 1.18
require (
github.com/labstack/echo/v4 v4.7.2 // indirect
github.com/labstack/gommon v0.3.1 // indirect
github.com/mattn/go-colorable v0.1.11 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect
golang.org/x/text v0.3.7 // indirect
)
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI=
github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
serverディレクトリでserver.goを作成します。
touch server.go
server.goを記述します。
package server
import (
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"net/http"
)
func StartServer() {
// Echo instance
e := echo.New()
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
// Routes
e.GET("/", helloHandler)
// Start server
e.Logger.Fatal(e.Start(":1234"))
}
func helloHandler(c echo.Context) error {
return c.String(http.StatusOK, "Hello World!")
}
go.workに追記する
このままだとエラーが出てしまうので、workspaceディレクトリに移動してuseコマンドを使います。
server % cd ../
workspace % go work use server
「./server」が追加されていればOKです。
go 1.18
use (
./hello
./main
./server // 追加
)
main.goに追記する
main.goにStartServerメソッドを記述します
package main
import (
"example.com/hello"
"example.com/server" // 追加
)
func main() {
hello.Hello("Yuuki")
server.StartServer() // 追加
}
実行してみる
mainディレクトリに移動してmain.goを実行してみましょう。
workspace % cd main
main % go run main.go
Hello, Yuuki!
____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.7.2
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:1234
こちらのURLに移動して「Hello World!」と表示されていればOKです。
最終的なディレクトリ構造はこちらになります。
.
├── go.work
├── go.work.sum
├── hello
│ ├── go.mod
│ └── hello.go
├── main
│ ├── go.mod
│ └── main.go
└── server
├── go.mod
├── go.sum
└── server.go
まとめ
実際に書きながらworkspaceモードの使い方について、学びました。
みなさんもよかったら自分のパソコンで試してみてください!
こちらが今回作成したソースコードになります。
参考にしたサイト