开发项目的时候,我们通常会有一个公共的仓库,比如lib-go。所有的开发组同学都会在自己负责的项目中去 引用需要的公共包。或者去lib-go修改公共包。
举个例子lib-go下有个pzip包
func Zip(files []File, target string) error{
}
那我去自己的项目比如A项目去使用的pzip包中Zip()方法,那就需要引入这个包(这个包下的所有文件之前已经提交)。
A项目中引入该包
import "github.com/echo-music/lib-go/pzip"
func main(){
var files []File
var target string
pzip.Zip(files,target)
}
那这样调用没啥问题,如果后面我修改了Zip方法,此时我再次运行A项目main方法,和之前运行的结果一样,并没有打印修改后的结果!
那该怎么办呢。我这里有两种方法可以搞定:
1、先提交lib-go仓库,并把修改后的代码推送到远程仓库,然后到A项目中
go get github.com/echo-music/lib-go/pzip@master
就会把lib-go最新的代码拉下来了,运行代码会打印修改后的结果。
2、在go.mod文件中通过 replace 指令,将旧的库地址,替换为新的库地址来实现这一操作。
replace (
github.com/echo-music/lib-go/pzip latest => /usr/fangting/workspace/lib-go
)
这样不需要将lib-go代码提交到远程了,本地A项目就可以使用lib-go修改的方法了
好了,上面两种方式说完了,大家想想有什么弊端呢?
第一种方式,每次修lib-go项目都要提交代码并提交到远程,很麻烦。
第二种方式,我草修改go.mod文件了,上线的时候还要注释掉,或者删除掉。开发的时候再打开?这个文件频繁操作,会导致冲突。
也不是一个好的解决办法
那么有没有一种既不需要提交代码也不需要修改go.mod文件方式呢?我偷偷的告诉你有的,他就是1.18版本出现的新功能,go work (工作空间)。就是一个目录(文件夹),里边有一个go.work 文件。你看下面的目录树
├── csrf
│ ├── README.MD
│ ├── csrf.go
│ ├── example_test.go
│ ├── go.mod
│ └── go.sum
├── go.work
├── go.work.sum
├── lib-go
│ ├── go.mod
│ └── pzip
│ └── pzip.go
└── qmall
├── go.mod
└── main.go
go.work 对应的内容如下
go 1.18
use (
./csrf
./lib-go
./qmall
)
项目一旦放在工作空间下,那么,项目下的go.mod寻找就会通过go.work来实现,
而不能像之前在项目下运行go run或者go build 就能自动寻找到go.mod,
所以必须在work目录下运行go work use 项目,把"./项目" 添加到go.work中,
这样你才能在项目项目里引用项目模块中的包。
工作空间这一层一般都不会进行git提交,提交的都是工作空间下的各个项目。
go.work是整个工作空间的基本配置文件,go.work文件主要用于本地开发使用,不进行git提交。
那么怎么初始化一个工作空间呢?
1、创建一个workspace目录
makedir $HOME/workspace
cd $HOME/workspace
2、运行以下命令
go work init
那么就可以创建一个工作空间了,后面使用go work use lib-go, 把"./lib-go" 添加到go.work中,
这样你才能在lib-go项目里引用lib-go模块中的包。
注意lib-go 是和go.work 文件是在同一个目录下,并且平级。