Application 2024-01-19

Using Workspace Mode with Go's Multi-Module Structure

Learn how Go Workspace mode (Go 1.18+) simplifies multi-module development. Covers go work init, go.work file structure, and referencing local modules without editing go.mod.

Read in: ja
Using Workspace Mode with Go's Multi-Module Structure

I had never used the Workspace mode added in Go 1.18, so I decided to give it a try.

What is Workspace Mode?

A feature to facilitate Go's multi-module structure.

How to Use Workspace Mode

Prepare the following structure:

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

func Foo() string {
	return "foo"
}

// bar.go
package bar

func Bar() string {
	return "bar"
}

Execute the following command in the foo directory to set up go.mod.

go mod init example.com/foo

Similarly, execute the following command in the bar directory to set up go.mod.

go mod init example.com/bar

Next, create a cmd directory and create a main.go file as follows:

package main

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

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

Set up go.mod in the cmd directory as well.

go mod init example.com/cmd

At this point, the structure will be as follows:

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

In the root directory, execute the following command to configure the workspace.

go work init foo bar cmd

A file named go.work is created.

go 1.21.1

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

Verify that go run cmd/main.go can be executed.

// Execution result
foo
bar

Next, let's add a module called 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"
}

Execute go mod init example.com/baz to generate go.mod like the other modules.

Next, add baz to main.go.

package main

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

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

Return to the root and execute go work use baz to add the module, and baz will be added to go.work.

go 1.21.1

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

Execute go run cmd/main.go and confirm that baz is added to the output.

// Execution result
foo
bar
baz

Impressions

I thought the multi-module structure was cumbersome, so I'm glad it has become simpler.

References

Tags: Golang
Share: 𝕏 Post Facebook Hatena
✏️ View source / Discuss on GitHub
☕ Support

If you enjoy this blog, consider supporting it. Every bit helps keep it running!


Related Articles