Go Modules is a new feature in Golang 1.11. Now that 1.12 is out, it’s time to use it. Modules is officially defined as:

A module is a collection of related Go packages. Modules are units for source code exchange and version control. The go command directly supports using modules, including logging and resolving dependencies on other modules. Modules replaces the old GOPATH based approach to specifying which source files to use in a given build.

How to use Modules?

  1. Upgrade Golang to 1.11 (1.12 is now available, 1.12 is recommended)
  2. Set up theGO111MODULE

GO111MODULE

GO111MODULE has three values: off, on, and Auto (default).

  • GO111MODULE=offThe go command line will not support the Module function, and dependencies will be found through vendor or GOPATH mode as in older versions.
  • GO111MODULE=on, the go command line uses modules and doesn’t look in the GOPATH directory at all.
  • GO111MODULE=auto, the default, the go command line determines whether to enable module based on the current directory. This situation can be divided into two situations:
    • The current directory is outside GOPATH/ SRC and contains the go.mod file
    • The current file is under the directory containing the go.mod file.

When modules is enabled, dependencies change to $GOPATH/ PKG, allowing multiple versions of the same package to coexist, and multiple projects to share cached modules.

go mod

Golang provides the Go mod command to manage packages.

Go mod has the following command:

The command instructions
download Download Modules to local Cache
edit Edit go.mod from tools or scripts
graph Print module requirement graph
init Initialize new Module in current directory
tidy Add missing and remove unused modules
vendor Make vendored copy of dependencies
verify Verify dependencies have expected content
why Explain why packages or modules are needed

How to use it in a project

Example 1: Create a new project

  1. inOutside the GOPATH directoryCreate a new directory and usego mod initInitializing producesgo.modfile
➜  ~ mkdir hello
➜  ~ cdHello ➜ hello go mod init Hello go: Creating new go.mod: Module hello ➜ hello ls go.mod ➜ hello cat go.mod module Hello go 1.12Copy the code

Once the go.mod file is created, its contents are fully controlled by go Toolchain. Go Toolchain modifs and maintains the go.mod file when commands such as go get, go build, and go mod are executed.

Go. mod provides module, require, replace, and exclude commands

  • moduleStatement specifies the name (path) of the package
  • requireStatement
  • replaceStatements can replace dependency modules
  • excludeStatement can ignore dependency modules
  1. Add the dependent

Create a new server.go file and write the following code:

package main

import (
	"net/http"
	
	"github.com/labstack/echo"
)

func main(a) {
	e := echo.New()
	e.GET("/".func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, World!")
	})
	e.Logger.Fatal(e.Start(": 1323"))}Copy the code

Go Run server.go Run the code to find that the Go mod will automatically look for dependencies to automatically download:

$ go run server.go
go: finding github.com/labstack/echoV3.3.10 + incompatible go: downloading github.com/labstack/echoV3.3.10 + incompatible go: extracting github.com/labstack/echoV3.3.10 + incompatible go: finding github.com/labstack/gommon/color latest go: finding github.com/labstack/gommon/logThe latest go: finding github.com/labstack/gommon v0.2.8Many lines are omitted here. ____ __ / __ / ___ / ___ / __ / / __ / _ \ _ \ / ___ / \ __ / __ / / _ \ ___ / v3.3.10 - dev High performance, Minimalist Go web framework https://echo.labstack.com ____________________________________O /... O \ ⇨ HTTP server started on [::]:1323Copy the code

Now check out the contents of go.mod:

$ cat go.mod

module hello

go 1.12

require (
	github.com/labstack/echo v33.10.+incompatible // indirect
	github.com/labstack/gommon v02.8. // indirect
	github.com/mattn/go-colorable v01.1. // indirect
	github.com/mattn/go-isatty v0. 07. // indirect
	github.com/valyala/fasttemplate v1. 0. 0 // indirect
	golang.org/x/crypto v0. 0. 0- 20190313024323.-a1f597ede03a // indirect
)
Copy the code

The go Module installation principle is to pull the latest release tag first, if there is no tag, pull the latest commit, see the official introduction of Modules. Go will automatically generate a go.sum file for the dependency tree:

$ cat go.sum
github.com/labstack/echoV3.3.10 + incompatible h1: pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg = github.com/labstack/echoV3.3.10 + incompatible/go. Mod h1:0 ins7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s = github.com/labstack/gommon v0.2.8 H1: JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0 = github.com/labstack/gommon v0.2.8 / go mod H1: / tj9csK2iPSBvn + 3 nlm9e52usepmtrd5ilfya + wQNJ4 = github.com/mattn/go-colorable v0.1.1 H1: G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg = github.com/mattn/go-colorable v0.1.1 / go mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= ... Omit a lot of linesCopy the code
  1. Execute the script againgo run server.goDiscovered that the step of checking and installing dependencies has been skipped.
  2. You can use the commandgo list -m -u allTo check the package that can be upgraded, usego get -u need-upgrade-packageThe upgrade will update the new dependency version to go.mod *, which is also availablego get -uUpgrade all dependencies

Go get upgrade

  • Run go get -u to upgrade to the latest minor version or revision (X.Y.Z, z is the revision number, y is the minor version number)
  • Run go get -u=patch to upgrade to the latest revision
  • Run go get package@version to upgrade to the specified version number
  • If there are version changes, the go.mod file will also change

Example 2: Transforming an existing project (HelloWord)

The project directory is:

$tree. ├── API │ ├── apis. Go ├─ server.go 1 directory, 2 filesCopy the code

Server. Go source code:

package main

import (
    api "./api"  // The relative path is used
    "github.com/labstack/echo"
)

func main(a) {
    e := echo.New()
    e.GET("/", api.HelloWorld)
    e.Logger.Fatal(e.Start(": 1323"))}Copy the code

API /apis. Go

package api

import (
    "net/http"

    "github.com/labstack/echo"
)

func HelloWorld(c echo.Context) error {
    return c.JSON(http.StatusOK, "hello world")}Copy the code
  1. usego mod init ***Initialize the go. The mod
$ go mod init helloworld
go: creating new go.mod: module helloworld
Copy the code
  1. rungo run server.go
go: finding github.com/labstack/gommon/color latest
go: finding github.com/labstack/gommon/log latest
go: finding golang.org/x/crypto/acme/autocert latest
go: finding golang.org/x/crypto/acme latest
go: finding golang.org/x/crypto latest
build command-line-arguments: cannot find module for path _/home/gs/helloworld/api
Copy the code

First, it will find, download and install the dependencies, and then run the script server.go, which will throw an error:

build command-line-arguments: cannot find module for path _/home/gs/helloworld/api
Copy the code

But go.mod has been updated:

$cat go.mod module helloworld go 1.12 require (github.com/labstack/echoV3.3.10 + incompatible / / indirect github.com/labstack/gommon v0.2.8 / / indirect github.com/mattn/go-colorable v0.1.1 / / An indirect github.com/mattn/go-isatty v0.0.7 / / indirect github.com/valyala/fasttemplate v1.0.0 / / indirect golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a // indirect)Copy the code
So why was the error thrown?

This is because the use of internal packages in server.go is different from the previous method. Since go.mod scans all packages in the same working directory and changes the import method, it must use helloWorld as the prefix of the path. Import helloWorld/API is no longer allowed in GOPATH/dep mode. See this issue for more details.

  1. Update the old package import method

So server.go needs to be rewritten as:

package main

import (
    api "helloworld/api"  // This is the updated import method
    "github.com/labstack/echo"
)

func main(a) {
    e := echo.New()
    e.GET("/", api.HelloWorld)
    e.Logger.Fatal(e.Start(": 1323"))}Copy the code

A small pit: start in golang1.11 go mod met go build github.com/valyala/fasttemplate: Module requires go 1.12. If you have a problem like this, which requires you to upgrade to 1.12, just upgrade golang1.12. Fortunately, the Go mod 🤷♂️ was tried after 1.12 was released

  1. It’s no different than creating a new project, right

Use replace to replace packages that cannot be obtained directly

For some known reason, not all packages can be downloaded successfully, such as those under golang.org.

Modules can be replaced with github libraries by using the replace directive in the go.mod file, for example:

Replace (golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto V0.0.0-20190313024323 - a1f597ede03a)Copy the code

or

Replace golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto - a1f597ede03a v0.0.0-20190313024323Copy the code

Refer to the link

  • Modules Official Introduction
  • Golang 1.11 New features – Modules
  • What are Go modules and how do I use them?
  • go mod doesn’t work for github.com/gomarkdown/markdown/html
  • Look again at Go Modules: Usage and details
  • First look Go module

References

[1] Modules [2] issue: github.com/golang/go/i… [3] This error: github.com/golang/go/i… [4] Modules… 1.11 new features introduced – [5] Golang Modules: www.lightblue.asia/golang-1-11… [6] What are Go modules and how do I use them? : talks.godoc.org/github.com/… [7] go mod doesn ‘t work for github.com/gomarkdown/markdown/html: github.com/golang/go/i… [8] will go modules: use and details: www.cnblogs.com/apocelipes/… [9] Go Module: tonybai.com/2018/07/15/…


Finally, thank my girlfriend for her support and tolerance, more than ❤️

Can also be in 【 in 】 (hiiiapril) enter the following keywords for historical article: male number & small program | | concurrent design mode & coroutines