go module is the official version management tool introduced after Go 1.11, and since Go 1.13, go module has been the default dependency management tool for the Go language. Since Go 1.14, the go modules feature has been officially recommended for use in production environments.

Here is a detailed description of how to use the go module to import local packages.

Prerequisites

Suppose we now have two packages, moduledemo and mypackage, where the moduledemo package will import the mypackage package and use its New method.

mypackage/mypackage.go reads as follows.

1
2
3
4
5
6
7
package mypackage

import "fmt"

func New(){
	fmt.Println("mypackage.New")
}

We now discuss this in two scenarios.

Under the same project

Note: We are allowed to define multiple packages under a project

Catalog Structure

What happens now is that we call the package mypackage in moduledemo/main.go.

1
2
3
4
5
moduledemo
├── go.mod
├── main.go
└── mypackage
    └── mypackage.go

Import Package

At this point, we need to define it in moduledemo/go.mod as follows.

1
2
3
module moduledemo

go 1.14

Then import the mypackage in moduledemo/main.go as follows

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package main

import (
	"fmt"
	"moduledemo/mypackage"  // Importing mypackage packages under the same project
)
func main() {
	mypackage.New()
	fmt.Println("main")
}

As an example

Suppose we now have the following file directory structure.

1
2
3
4
5
└── bubble
    ├── dao
    │   └── mysql.go
    ├── go.mod
    └── main.go

where bubble/go.mod reads as follows.

1
2
3
module github.com/q1mi/bubble

go 1.14

bubble/dao/mysql.go reads as follows.

1
2
3
4
5
6
7
package dao

import "fmt"

func New(){
	fmt.Println("mypackage.New")
}

bubble/main.go reads as follows.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package main

import (
	"fmt"
	"github.com/q1mi/bubble/dao"
)
func main() {
	dao.New()
	fmt.Println("main")
}

Not under the same project

Catalog Structure

1
2
3
4
5
6
├── moduledemo
│   ├── go.mod
│   └── main.go
└── mypackage
    ├── go.mod
    └── mypackage.go

Import Package

At this point, mypackage also needs to be initialized with a module, i.e., have a go.mod file of its own, with the following content.

1
2
3
module mypackage

go 1.14

Then we import in moduledemo/main.go as follows.

1
2
3
4
5
6
7
8
import (
	"fmt"
	"mypackage"
)
func main() {
	mypackage.New()
	fmt.Println("main")
}

Because the two packages are not in the same project path, you want to import the local packages and they are not published to a remote github or other code repository address. At this point we need to use the replace directive in the go.mod file.

In the caller, which is moduledemo/go.mod, specify the relative path to use to find the package mypackage as follows.

1
2
3
4
5
6
7
module moduledemo

go 1.14


require "mypackage" v0.0.0
replace "mypackage" => "../mypackage"

As an example

Finally, let’s consolidate the above with an example.

We now have the following file directory structure.

1
2
3
4
5
6
├── p1
│   ├── go.mod
│   └── main.go
└── p2
    ├── go.mod
    └── p2.go

The function defined in p1/main.go that you want to import in p2.go.

The contents of p2/go.mod are as follows.

1
2
3
module www.sobyte.net/q1mi/p2

go 1.14

import in p1/main.go as follows

1
2
3
4
5
6
7
8
import (
	"fmt"
	"www.sobyte.net/q1mi/p2"
)
func main() {
	p2.New()
	fmt.Println("main")
}

Because I didn’t upload the package www.sobyte.netq1mi/p2 to the site www.sobyte.net, we just want to import the local package, and this time we need to use the replace command.

p1/go.mod reads as follows.

1
2
3
4
5
6
7
module github.com/q1mi/p1

go 1.14


require "www.sobyte.net/q1mi/p2" v0.0.0
replace "www.sobyte.net/q1mi/p2" => "../p2"

At this point, we can compile the p1 project normally.


Reference https://www.liwenzhou.com/posts/Go/import_local_package_in_go_module/