DEV Community

Cover image for Using Workspace Mode with Go's Multi-Module Structure
Kenta Takeuchi
Kenta Takeuchi

Posted on • Originally published at bmf-tech.com

Using Workspace Mode with Go's Multi-Module Structure

#go

This article was originally published on bmf-tech.com.

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
Enter fullscreen mode Exit fullscreen mode
// foo.go
package foo

func Foo() string {
    return "foo"
}

Enter fullscreen mode Exit fullscreen mode
// bar.go
package bar

func Bar() string {
    return "bar"
}
Enter fullscreen mode Exit fullscreen mode

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

go mod init example.com/foo
Enter fullscreen mode Exit fullscreen mode

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

go mod init example.com/bar
Enter fullscreen mode Exit fullscreen mode

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())
}
Enter fullscreen mode Exit fullscreen mode

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

go mod init example.com/cmd
Enter fullscreen mode Exit fullscreen mode

At this point, the structure will be as follows:

.
├── bar
│   ├── bar.go
│   └── go.mod
├── cmd
│   ├── go.mod
│   └── main.go
└── foo
    ├── foo.go
    └── go.mod
Enter fullscreen mode Exit fullscreen mode

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

go work init foo bar cmd
Enter fullscreen mode Exit fullscreen mode

A file named go.work is created.

go 1.21.1

use (
    ./bar
    ./cmd
    ./foo
)
Enter fullscreen mode Exit fullscreen mode

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

// Execution result
foo
bar
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
// baz.go
package baz

func Baz() string {
    return "baz"
}
Enter fullscreen mode Exit fullscreen mode

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())
}
Enter fullscreen mode Exit fullscreen mode

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
)
Enter fullscreen mode Exit fullscreen mode

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

// Execution result
foo
bar
baz
Enter fullscreen mode Exit fullscreen mode

Impressions

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

References

Top comments (0)