laitimes

选择正确的Go Module Path

author:Not bald programmer
选择正确的Go Module Path

Recently, when I was looking at the project code, I noticed that someone wrote the module path as com.example.foo in the go.mod file. Based on this approach, I believe that the reader in front of the screen can also deduce that the developer may have moved from the Java camp to Go. In practice, there may be many developers who use similar content as a module path, but this is obviously not the recommended or idiomatic way to write Go.

In this short article, I'm going to talk about the impact of the module path on Go source code builds, package import paths, and development collaboration, and what a conventionally modular path should look like.

Let's first review what a Go module path is.

1. 什么是module path

In Go, a module path is a unique string used in Go development to identify and locate a module, specifying where to store the module code in a remote repository or local file system.

The module path is defined in the go.mod file, as shown in the following example:

// go.mod
module github.com/user/module

go 1.21.1           

We see that a typical module path is a URL format string, which may be similar to a github.com/user/module, where the github.com/user/module is the module path.

In Go, a module is a way of organizing and managing code, and it is also the basic unit of Go code versioning.

// go.mod
module github.com/user/module/v2

go 1.21.1           

This indicates that the module is a v2 version, and the previous github.com/user/module are not backwards compatible with the two modules. Users of modules can import packages under these two incompatible modules at the same time, for example:

import (
 "github.com/user/module/foo"
 foov2 "github.com/user/module/v2/foo"
)           

So what is the impact of the selection and use of module paths on Go development?

2. module path的影响

2.1 Indicates the Go module network location

As mentioned earlier, in Go, we usually use the repository address of the module as the basis for the module path. The advantage of this is that the Go compiler can determine the location of the module on the network directly from the module path and download the required code from the specified location. This makes it very convenient when using third-party modules, as developers only need to specify the path to the module, and the Go toolchain will automatically handle dependencies, download and compile the required module code.

For example, if the path to a module is github.com/user/module, then the Go toolchain (especially the Go compiler) will assume that the module's code is stored in the module repository under the user user on GitHub. When the Go toolchain needs to introduce the module, it will download the corresponding code through goproxy or directly on GitHub according to this path.

This repository address-based module path design simplifies module management and dependency handling, making it easier and more reliable to use third-party modules in Go projects.

2.2 Impact on Go packet paths

The import path of the package in the Go module module is the module path + the relative path to the directory where the package is located, for example, the package in the pkg/foo directory of the module with the module path in the github.com/user/module is the import path of the foo package is github.com/user/module/pkg/foo.

If, as at the beginning of this article, com.example.foo is used as the module path, the import path of the foo package becomes com.example.foo/pkg/foo, which is obviously difficult to understand, and a Java string such as com.example.foo does not indicate the network location of the go module.

2.3 Impact on Compilation

The effect of the module path on compilation is reflected in two ways:

First, Go compiles to find dependent modules through the module path. If the Go module path is incorrect or incomplete, then the compilation may fail. A non-idiomatic Go module path can cause compilation errors or problems that are difficult to diagnose.

For example, if a module path is github.com/user/mymodule, then go build is executed under the module (without using the -o command line flag), and the default binary file is mymodule.

But if the module path is com.example.foo, then the resulting binary file name is com.example.foo, which is obviously not what we want.

2.4 Impact on Developer Collaboration

The naming of the Go module path also has an important impact on the collaboration between developers, which is mainly reflected in two aspects:

  • Uniqueness and namespace

Module paths should be unique to avoid conflicts with other modules. Typically, using a domain name as part of a module path ensures global uniqueness. Within a team, module paths can also be named based on the name of the company or organization to ensure the uniqueness of the modules.

  • Dependency management

Using clear, meaningful module paths that indicate location and version can help developers better manage dependencies. When other developers are ingesting your modules, they can use the module path to determine the correct dependency version and how to integrate with your module.

3. How to choose a good module path

With the above number of seconds, we can actually sketch a good picture of the module path. Of course, this is also a best practice for the Go community.

In general, the module path should be based on the repository address of the module and use a short, easy-to-understand path.

As mentioned earlier, if your module is stored on GitHub and is publicly available, then the module path is generally github.com/user/module.

If your module is internal and not public, you can use a private repository address, e.g. company.com/dept/go/module.

Whether it's public or private, you can customize the module path, and you can refer to the pull scheme I wrote earlier about customizing Go modules[1].

If it is a daily practice project that is only used locally, then the use of Go module path can be more relaxed, you can not care about its impact on the network location of the go module module and developer collaboration, you can use a single word module path like demo, and only pay attention to its impact on the package path and compilation results.

4. Summary

In summary, we can see that the Go module path has an important impact on the Go module network location, package path, compilation, and developer collaboration. Following the best practices of the Go community, choosing a good Go module path can improve code readability and maintainability, simplify multi-person collaboration, and help Go developers better use the Go module system.

Resources

[1] Custom Go module pull scheme: https://tonybai.com/2021/09/03/the-approach-to-go-get-private-go-module-in-house

[2] Gopher部落知识星球: https://public.zsxq.com/groups/51284458844544

[3] Link: https://m.do.co/c/bff6eed92687