# go workspace简单使用
# 为什么会有go workspace
基于Go Module的开发,代码组织有以下两种方式:
- 整个项目为一个Module,Module下再拆分为多个功能包
- 根据不同功能将项目拆分为多个Module
两种方式各有优缺点,其中:
- 整个项目为一个Module,各个功能包都在一个Module下,代码变更是实时生效的。但是其中业务代码和功能代码等放在一起,高度耦合。多个项目之间的公共代码不方便共享。
- 根据不同功能将项目拆分为多个Module,优点是代码之前低耦合,Module之间根据需要相互依赖。缺点是项目依赖的Module改动后,如果用到的改动后的功能就需要先发布依赖Module到代码仓库,然后在项目中更新依赖Module。
针对上面所说的将项目拆分成多个Module,依赖Module需要先发布再更新的问题,有以下两个解决方案:
- 使用Go Module中的replace指令,在项目中将依赖替换为本地Module
- 使用go workspace工作区模式,使用统一的go.work来维护依赖映射
module github.com/xxxxxxx/gin-framework-layout
go 1.19
require (
github.com/xxxxxxx/gin-framework-core v0.0.1
github.com/xxxxxxx/go-utils v0.0.0-20221028065316-8abebfd58706
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/gin-gonic/gin v1.8.1
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a
github.com/swaggo/gin-swagger v1.5.3
github.com/swaggo/swag v1.8.7
)
replace github.com/xxxxxxx/gin-framework-core => ../gin-framework-core v0.0.1
- replace在开发项目的go.mod文件中将依赖Module使用replace指令替换为本地项目。优点是不需要每次都发布和更新Module,缺点是在每次发布的时候都需要注释掉本地的replace指令。
- go workspace工作区模式,是在项目的同级目录创建go.work文件,来使用go.work文件来统一维护当前目录下所有Module之间的依赖,同时也不需要将go.work纳入版本管理,也不需要每次都去删掉或者注释掉相关内容。具体如何使用go workspace,请参照下面示例。
# go workspace的用法
我们以的xxxxxxx框架为例,为了代码之间低耦合,我们将框架拆封为三个Module。
- gin-framework-core (opens new window) Module, 基于gin封装的web框架核心,包括加载配置服务、日志服务、数据库操作和redis换成操作等,依赖于函数库go-utils。
- go-utils (opens new window) Module, go公共函数库,公共函数都放在这个Module下面,包括md5、http request、nodelog等封装。
- gin-framework-layout (opens new window) Module, 基于gin框架封装的业务开发模版,其内部实现了mvc+router服务,依赖于gin-framework-core和go-utils Module。
我们在开发过程中需要同时改到上面三个Module,同时我们希望改动能够实时生效、发布代码到gitea时也不改动任何配置。具体可以这样做:
# 新建go代码目录
root@huge-elk:~# mkdir ~/webdata/go -p
root@huge-elk:~# cd ~/webdata/go/
root@huge-elk:~/webdata/go#
# 拉取gin-framework-core,gin-framework-layout,go-utils三个仓库
root@huge-elk:~/webdata/go# git clone git@github.com:xxxxxxx/gin-framework-core.git
Cloning into 'gin-framework-core'...
The authenticity of host 'github.com (192.168.74.97)' can't be established.
RSA key fingerprint is SHA256:oltXuIRprs+uMUAwCCYY3qiLjQDmE0lP4eINNqxB1sw.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
remote: Enumerating objects: 40, done.
remote: Counting objects: 100% (40/40), done.
remote: Compressing objects: 100% (40/40), done.
remote: Total 40 (delta 14), reused 0 (delta 0)
Receiving objects: 100% (40/40), 34.46 KiB | 1.08 MiB/s, done.
Resolving deltas: 100% (14/14), done.
root@huge-elk:~/webdata/go# git clone git@github.com:xxxxxxx/gin-framework-layout.git
Cloning into 'gin-framework-layout'...
remote: Enumerating objects: 35, done.
remote: Counting objects: 100% (35/35), done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 35 (delta 8), reused 0 (delta 0)
Receiving objects: 100% (35/35), 32.98 KiB | 2.20 MiB/s, done.
Resolving deltas: 100% (8/8), done.
root@huge-elk:~/webdata/go# git clone git@github.com:xxxxxxx/go-utils.git
Cloning into 'go-utils'...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (16/16), done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 16 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (16/16), 4.27 KiB | 874.00 KiB/s, done.
root@huge-elk:~/webdata/go# ll
total 20
drwxr-xr-x 5 root root 4096 Nov 2 10:19 ./
drwxr-xr-x 3 root root 4096 Nov 2 10:15 ../
drwxr-xr-x 5 root root 4096 Nov 2 10:19 gin-framework-core/
drwxr-xr-x 7 root root 4096 Nov 2 10:19 gin-framework-layout/
drwxr-xr-x 7 root root 4096 Nov 2 10:19 go-utils/
root@huge-elk:~/webdata/go#
# 使用go work init来创建workspace
# moddirs是Go Module所在的本地目录。如果有多个Go Module,就用空格分开。如果go work init后面没有参数,会创建一个空的workspace。
go work init [moddirs]
## 初始化workspace
root@huge-elk:~/webdata/go# go work init ./gin-framework-layout
root@huge-elk:~/webdata/go# ll
total 24
drwxr-xr-x 5 root root 4096 Nov 2 10:22 ./
drwxr-xr-x 3 root root 4096 Nov 2 10:15 ../
drwxr-xr-x 5 root root 4096 Nov 2 10:19 gin-framework-core/
drwxr-xr-x 7 root root 4096 Nov 2 10:19 gin-framework-layout/
drwxr-xr-x 7 root root 4096 Nov 2 10:19 go-utils/
-rw-r--r-- 1 root root 36 Nov 2 10:22 go.work
root@huge-elk:~/webdata/go#
## 查看workspace内容
root@huge-elk:~/webdata/go# cat go.work
go 1.18
use ./gin-framework-layout
root@huge-elk:~/webdata/go#
# 使用go work use来添加依赖
# 如果要给workspace新增Go Module,可以使用如下命令.或者手动编辑go work文件。如果带有-r参数,会递归查找-r后面的路径参数下的所有子目录,把所有包含go.mod文件的子目录都添加到go work文件中。
go work use [-r] moddir
### 注意: 如果某个Go Module的目录已经被加到go.work里了,后面该目录没有go.mod文件了或者该目录被删除了,那对该目录再次执行go work use命令,该目录的use指令会从go.work文件里自动移除。(注意:自动移除要从Go 1.18正式版本才会生效,Go 1.18beta1版本有bug,自动删除不会生效)
# 添加gin-framework-core,go-utils依赖
root@huge-elk:~/webdata/go# go work use ./gin-framework-core ./go-utils/
root@huge-elk:~/webdata/go# cat go.work
go 1.18
use (
./gin-framework-core
./gin-framework-layout
./go-utils
)
这样我们就可以修改go目录下的三个module中的任意一个,代码是实时生效的。而且对于代码发布流程不会有任何影响。