Go单体仓库:代码组织实践指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Go 单体仓库:代码组织的实践指南



单体仓库 (monorepo) 是一种代码管理方法,将所有项目、库和服务存储在一个仓库中。在 Go 社区中,这种方法因其简单性和高效性而越来越受欢迎。本文将深入探讨如何在实际中组织 Go 单体仓库项目:从结构选择到 CI/CD 配置。



为什么选择 Go 单体仓库?



Go 最初就是为大型代码库设计的语言。像 go mod 和 go work 这样的工具使得单体仓库的使用变得自然。主要优势包括:



  • 简化依赖管理:所有模块使用统一版本的包,不存在版本冲突。
  • 统一的 CI/CD:所有服务共享一个配置文件,更易于维护。
  • 重构便利:库中 API 的更改会立即反映在仓库中的所有使用者身上。
  • 统一标准:代码检查工具、格式化工具和代码审查适用于所有代码。


单体仓库结构:经过验证的方案



我们来看一个非常适合中型 Go 项目的结构。假设我们有两个服务:auth-service 和 api-gateway,以及一些公共库。



my-project/├── apps/                    # 可执行应用程序│   ├── auth-service/│   │   ├── cmd/│   │   │   └── main.go│   │   ├── internal/│   │   │   ├── handler/│   │   │   ├── service/│   │   │   └── repository/│   │   ├── go.mod│   │   └── go.sum│   └── api-gateway/│       ├── cmd/│       │   └── main.go│       ├── internal/│       │   ├── middleware/│       │   └── routes/│       ├── go.mod│       └── go.sum├── libs/                    # 公共库│   ├── config/│   │   ├── config.go│   │   ├── go.mod│   │   └── go.sum│   ├── logger/│   │   ├── logger.go│   │   ├── go.mod│   │   └── go.sum│   └── db/│       ├── postgres.go│       ├── go.mod│       └── go.sum├── scripts/                 # CI/CD 和工具脚本│   ├── build.sh│   └── test.sh├── go.work                  # Go Workspace (可选)├── .golangci.yml            # 代码检查工具配置├── Makefile                 # 通用命令└── README.md


结构的关键元素



  • apps/ — 所有可执行应用程序。每个应用程序都有自己的入口点 (cmd/main.go) 和独立的 go.mod。
  • libs/ — 通用库。每个库都是一个独立的 Go 模块。
  • scripts/ — 用于构建、测试和部署的辅助脚本。
  • go.work — Go Workspace 文件,用于简化本地开发。


配置 Go Workspace 用于本地开发



Go 1.18+ 通过 go.work 文件支持 Workspace。这允许在本地引用 libs/ 中的库,而无需发布到远程仓库。



在项目根目录创建 go.work:



go 1.22

use ( ./apps/auth-service ./apps/api-gateway ./libs/config ./libs/logger ./libs/db)


现在,在开发过程中,您可以直接导入库:



// apps/auth-service/cmd/main.gopackage main

import ( "my-project/libs/config" "my-project/libs/logger")

func main() { cfg := config.Load() log := logger.New(cfg.LogLevel) log.Info("Auth service started")}


重要提示:在每个应用程序的 go.mod 中,对库的依赖必须通过 replace 指向本地路径:



// apps/auth-service/go.modmodule github.com/company/my-project/a

博客

书籍推荐