Goのマルチモジュール構成でWorkspace modeを使ってみる

アプリケーション

Go1.18から追加されたWorkspace modeを使ったことがなかったので、使ってみた。

Workspace modeとは

Goのマルチモジュール構成を便利するための機能。

Workspace modeの使い方

次のような構成を用意する。

.
├── bar
│   └── bar.go
└── foo
    └── foo.go
// foo.go
package foo

func Foo() string {
    return "foo"
}
// bar.go
package bar

func Bar() string {
    return "bar"
}

fooディレクトリで次のコマンドを実行して、go.modをセットアップする。

go mod init example.com/foo

同じく、barディレクトリで次のコマンドを実行して、go.modをセットアップする。

go mod init example.com/bar

次に、cmdディレクトリを作成して、main.goファイルを次のように作成する。

package main

import (
    "example.com/bar"
    "example.com/foo"
)

func main() {
    println(foo.Foo())
    println(bar.Bar())
}

cmdディレクトリでも同様にgo.modをセットアップする。

go mod init example.com/cmd

ここまでで、次のような構成になる。

.
├── bar
│   ├── bar.go
│   └── go.mod
├── cmd
│   ├── go.mod
│   └── main.go
└── foo
    ├── foo.go
    └── go.mod

ルートのディレクトリにて、次のコマンドを実行し、workspaceの設定を行う。

go work init foo bar cmd

go.workというファイルが作成される。

go 1.21.1

use (
    ./bar
    ./cmd
    ./foo
)

go run cmd/main.goが実行できることを確認。

// 実行結果
foo
bar

続いて、bazというモジュールを追加してみる。

.
├── bar
│   ├── bar.go
│   └── go.mod
├── baz
│   ├── baz.go
│   └── go.mod
├── cmd
│   ├── go.mod
│   └── main.go
├── foo
│   ├── foo.go
│   └── go.mod
└── go.work
// baz.go
package baz

func Baz() string {
    return "baz"
}

go mod init example.com/bazを実行して他のモジュールと同じようにgo.modを生成する。

続いて、main.goにbazを追加する。

package main

import (
    "example.com/bar"
    "example.com/baz"
    "example.com/foo"
)

func main() {
    println(foo.Foo())
    println(bar.Bar())
    println(baz.Baz())
}

ルートに戻り、go work use bazを実行し、モジュールを追加すると、go.workにbazが追加される。

go 1.21.1

use (
    ./bar
    ./baz
    ./cmd
    ./foo
)

go run cmd/main.goを実行して、出力にbazが追加されていることを確認する。

// 実行結果
foo
bar
baz

所感

マルチモジュール構成が手間だなぁと思っていたので簡単になって良いなと思った。

参考


関連書籍