Go module 介绍

新依赖管理工具

Posted by John Mactavish on September 10, 2019

简介

module是Go 1.11 中增加的重要的feature,用于更好地管理依赖。通过它, 你现在可以在GOPATH之外创建新的项目了。全部命令如下:

download download modules to local cache (下载依赖的module到本地cache) edit edit go.mod from tools or scripts (编辑go.mod文件) graph print module requirement graph (打印模块依赖图) init initialize new module in current directory (再当前文件夹下初始化一个新的module, 创建go.mod文件) tidy add missing and remove unused modules (增加丢失的module,去掉未用的module) vendor make vendored copy of dependencies (将依赖复制到vendor下) verify verify dependencies have expected content (校验依赖) why explain why packages or modules are needed (解释为什么需要依赖)

Quick Start

作为一个试验特性,Go提供了开关。设置环境变量 GO111MODULE 的值可以开启或关闭模块支持, 它有三个可选值:off、on、auto,默认值是 auto。

GO111MODULE=off 无模块支持,go 会从 GOPATH 和 vendor 文件夹寻找包。 GO111MODULE=on 模块支持,go 会忽略 GOPATH 和 vendor 文件夹,只根据 go.mod 下载依赖。 GO111MODULE=auto 在 $GOPATH/src 外面同时根目录有 go.mod 文件时,开启模块支持。

开启模块支持后,使用

go mod init packagename

可以在当前目录创建一个go.mod文件,文件第一行定义了模块名,有了这一行才算作是一个模块。 一般来说,我会把模块名命名为”github.com/username/modulename”,这样可以保证模块名的规范,防止重名。 然后go.mod文件所在的目录就是模块根路径,在子文件夹中相对于模块根路径写包名。

比如说:模块名为”github.com/gonearewe/hello”,文件夹结构为

|
| _ api
|   |
|   | _ api_access.go
|   | _ api_push.go
|
| _ log
    |
    | _ log.go

那么,如果在log.go 文件类import api包就写作

import "github.com/gonearewe/hello/api"

注意,下面这个使用Unix路径的点操作符的写法是不被允许的,会在文件头的package 声明上报错cannot find module

import "../api"

go mod download

命令用于将依赖包缓存到本地Cache起来,直接执行go build也可以下载依赖。 依赖会安装在$GOPATH/pkg/mod目录下,每个依赖模块又有一个单独的文件夹,里面存放着不同版本 的模块压缩包。

GOPROXY

现在的module和以前不同,是分版本的,所以像GOPATH那样自己手动维护是很困难的。但是我们现在还有了 GOPROXY。它是用来设置代理的,一般设置为

https://goproxy.io

现在模块的下载速度甚至比原来从github.com下载还快了。

现有的问题及解决方案

  • gocode和gopkg等重要的ide插件性质的工具对go module 的支持还不够好,容易给编程造成问题。 但是可以通过复制一份gocode然后把它重命名为gocode-gomod来欺骗VS Code
  • 有一次报错missing dot in first path element ,意义不明,实际错误为少写了一层目录导致包路径错误,
// import . "github.com/gonearewe/lua-compiler/api" // missing a folder
import . "github.com/gonearewe/lua-compiler/go/api" // correct