LoginSignup
13
7

More than 1 year has passed since last update.

動かして覚えるGoのWorkspaceモードの使い方

Posted at

今までのモジュール管理方法はこちらをご覧ください。

実行環境

  • M1 Macbook Air
  • macOS Monterey 12.4
  • Go 1.18

WindowsでもGoがちゃんとインストールされていれば大丈夫です。

workspaceモードとは

複数のモジュールを一つのgo.workというファイルで管理し、モジュール間の行き来をスムーズにすると言うものです。

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を記述します。

hello/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を記述します。

main/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.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がこのようになっていると思います。

server/go.mod
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
)
server/go.sum
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を記述します。

server/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.work
go 1.18

use (
	./hello
	./main
	./server    // 追加
)

main.goに追記する

main.goにStartServerメソッドを記述します

main/main.go
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モードの使い方について、学びました。
みなさんもよかったら自分のパソコンで試してみてください!

こちらが今回作成したソースコードになります。

参考にしたサイト

13
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
7