Go’s dependency management, or Go Module, has been around for some years now, and has been the subject of much criticism and refinement.
Go 1.18 will introduce a new feature, Multi-Module Workspaces, to support multiple workspaces for modules, which will solve a number of problems.
Background
When working with Go projects on a daily basis, there are 2 classic problems that are particularly tedious.
They are as follows.
- relying on a local replace module.
- relying on a local unpublished module.
replace module
The first scenario: For example, in a Go project, we would use replace to resolve some local dependencies or to customize the code. We will use replace in the go.mod file to do this.
The following code.
|
|
This allows for accuracy when linking local development.
Here’s the problem.
- Local paths: the replace set up essentially converts to a local path, which means that everyone is different.
- Repository Dependencies: the file changes are uploaded to the Git repository, so if you accidentally upload a file, it affects other developers, or you have to change it back every time you upload it.
This is a very poor user experience and a pain in the ass.
Unpublished modules
The second scenario: when you are working on a local Go project, you may be working on multiple libraries (project libraries, tool libraries, third-party libraries) at the same time.
The following code.
If you run go run
or go mod tidy
at this point, it will not work and will fail.
An error like the following will be thrown.
|
|
This exception is because the library github.com/eddycjy/pkgutil
is not available on GitHub, and therefore cannot be pulled.
Solution: Prior to Go 1.18, we would either replace, or upload directly to Github, and the dependencies would be pulled by the Go toolchain.
Many users have questioned this: do all Go dependencies have to be uploaded to GitHub, with strong bindings?
It’s very unfriendly and damaging to newcomers.
Workspace model
After many rounds of feedback from the community, Michael Matloob made the proposal Proposal: Multi-Module Workspaces in cmd/go which has been discussed and implemented extensively and was officially implemented in Go 1.18.
One of the core concepts of the new proposal is the addition of the go work
workspace concept, which targets the Go Module dependency management model.
It is possible to set a series of dependent module local paths in the local project’s go.work file, and then compose the modules under the path into a workspace for the current Go project, i.e. N Go Modules into 1 Go Work, with the workspace having the highest read priority.
We can see this with go help
as follows.
|
|
Simply execute go work init
to initialise a new workspace, followed by the argument to the specific submodule mod to be generated.
The command is as follows.
|
|
The project catalogue is as follows.
The contents of the generated go.work file.
The new go.work has the same syntax as go.mod and can also be used with the replace syntax.
A total of three directives are supported within the go.work file.
- go: declares the go version number, mainly for subsequent version control of new semantics.
- use: declares the specific file path of a module on which the application depends. The path can be either absolute or relative, and can be outside the application’s destiny directory.
- replace: Declares that the import path of a module dependency is replaced, with priority over the replace directive in go.mod.
If you want to disable workspace mode, you can specify it with the -workfile=off
command.
That is, execute the following command at runtime.
The go.work file doesn’t need to be committed to a Git repository, otherwise it’s a bit of a toss-up.
As long as you have go.work set up in your Go project, you will be in workspace mode at runtime and compile time, and the workspace configuration will be given highest priority to suit your local development needs.
This concludes the core knowledge of the workspace.
Summary
Today we have introduced a new feature of Go 1.18: the Multi-Module workspace model. It is still essentially a solution to the need for local development.
Since go.mod files are strongly associated with projects, they are basically uploaded to a Git repository, so it’s hard to do anything about it. So we just built go.work to be purely local and easy to use.
With the new go.work, you can work on completely local files without affecting other members of the development team.
What do you think? What do you think?)