Go Modules: The Best of Both Worlds
We recently started using go modules at work to handle dependencies. The experience has been mostly great, but unfortunately a lot of tooling hasn’t added support for modules. Most of the team uses vscode, which depends on module support in open-source tooling, some of which is incomplete. At the time of writing, refactoring/rename tools don’t work, and many of the other tools are very slow when modules are enabled. I wanted to find a way to use modules for dependency management, but use GOPATH
for development. It turns out that it’s fairly easy to get the best of both worlds if you follow a few simple rules:
- Put your project in
GOPATH
in the correct location defined by thego.mod
file. If yourmodule
line specifiesfoo.com/bar/baz
, you need to put your project in$GOPATH/src/foo.com/bar/baz
. It’s themodule
line that matters, not the URL to the actual project. - Use
GOMODULE111=on
when you’re dealing with dependencies. By default, when you’re inside ofGOPATH
, modules will be disabled. You need to manually enable them in order to add and update dependencies withgo mod ...
subcommands, orgo get
. These dependencies are what our builds use, and will be deterministic. - One catch: when you alter dependencies with modules, you must run
go mod vendor
, still withGOMODULE111=on
. This will save your dependencies to./vendor
, which will allow non-module-aware tooling to function.
A good test to see if things are working correctly: you should be able to open a module-enabled project in vscode and use gorename
to change a symbol name.
PS - We’re hiring go folks!