Go get cannot find local packages when using multiple modules in a repo
You can have local "sub" modules like you ask for by adding a require statement and a matching replace statement with a relative file path in go.mod.
In the "root" ./go.mod:
module example.com/localModule
require example.com/localModule/model v0.0.0
replace example.com/localModule/model v0.0.0 => ./model
Root problem
The reason you are getting this error is because you have defined two modules that do not know how to find each other on your local disk.
$ go build
main.go:4:8: unknown import path "example.com/localModule/model":
cannot find module providing package example.com/localModule/model
Solution 1: replace
You can add a replace
directive to the top module's go.mod
file, such as:
replace example.com/localModule/model v0.0.0 => ./model
which lets the top module find the other module on disk. This is covered in more detail in the replace FAQ and "Multi-module repositories" section on the Modules wiki.
However, this is a more complex solution, can be hard to get right, is usually more on-going work, and has some limitations like replace
is ignored for all modules except the current module. For most people, a multi-module repo is probably is not what they want. It is relatively rare at this point to really need to have multiple modules in a single repository.
Solution 2: one repo == one module
While it is possible to use a replace
directive, the more common and straightforward solution is:
- Have a single
go.mod
file in your repository, and - Place that single
go.mod
file in the root of your repository.
This is a very simple solution, and it means your two packages within the repository will be able to find each other automatically without needing any replace
, and which avoids the error message you reported.
replace
with multi-module repo, vs. single module repo?
Russ Cox commented in #26664:
For all but power users, you probably want to adopt the usual convention that one repo = one module. It's important for long-term evolution of code storage options that a repo can contain multiple modules, but it's almost certainly not something you want to do by default.
If you instead want to have multiple modules defined within a single repository, there is a fair amount of nuance about how to do so properly, and there is an entire section of the Modules wiki that should be read about how to manage the complexity associated with multiple modules in a single repository, including this advice:
Adding modules, removing modules, and versioning modules with multiple modules in a single repository requires considerable care and deliberation, so it is almost always easier and simpler to manage a single-module repository rather than multiple modules in an existing repository.