01 Go项目初始化
📝 主旨内容
- 项目初始化的几种方式
- 初始化项目仓库
- 使用 Air 工具热加载 go 应用
- 添加版权声明文件 license
- 编写 Makefile 脚本
1. 项目初始化的几种方式
Go 项目开发的第一步是初始化一个 Go 项目仓库。根据开发能力、项目类别、项目需求等,可以选择不同的项目初始化方式。一般而言有以下几种项目初始化方式,具体如下表所示。
| 初始化方式 | 方式描述 |
| 生成工具 | 借助项目开发脚手架自动生成项目模版,例如 kratos、nirvana、kubebuilder、osctl 等工具 |
| 复制已有项目 | 复制一个可以满足功能需求的现有项目,然后重命名项目目录并修改 Go 包导入路径,最后基于修改后的源代码进行开发 |
| 从零初始化 | 从头初始化一个 Go 项目,包括设计目录结构、代码结构以及进行源代码开发 |
1.1 生成工具
初始化 Go 项目最简单的方法是使用工具进行初始化。通过这些脚手架工具,可以快速生成一个 Go 项目模板,并基于该模板进行开发。目前业界有许多项目生成工具,如 osctl、kratos、nirvana、sponge 等。使用这些工具初始化 Go 项目的最大优点是方便、快捷,且能生成相对高质量的项目模板。然而,缺点也很明显:生成的项目模板的代码质量、目录结构、代码架构、功能列表及构建方式均依赖于工具本身的实现。
本课程介绍的 miniblog 项目也有其匹配的项目生成工具 osctl。该工具可以生成与 miniblog 项目一致的代码,从代码质量、目录结构、简洁架构、设计思路到可选的功能列表,都与 miniblog 保持一致。
1.2 复制已有项目
除了使用脚手架工具快速生成 Go 模板项目外,还可以直接复制一个已有的 Go 项目,然后修改项目的仓库名和 Go 包导入路径,替换与原项目名相关的字符串等方式来初始化一个 Go 项目。这种方式的缺点是改造工作量较大。优点是非常灵活,可以根据需求选择喜欢的 Go 项目,魔改之后,形成自己的 Go 项目。
后面如果在开发一个新单体项目时,可以选择直接通过魔改 miniblog 来进行二开。
如果项目复杂度过高,可以选择魔改 onex 项目来进行二开。
魔改已有项目为一个新项目时,可以使用 Linux 命令批量修改,修改命令通常如下:
1 | |
注: 代码中 myproj 需要替换为新项目名
1.3 从零开发
还可以选择从零初始化一个 Go 项目。这种方式最大的缺点是工作量很大,项目目录结构、项目源码、项目代码结构等都需要从零设计并开发。但优点也很明显,可以完全根据自己的需求来设计和开发。
[!important]
选择合适的项目初始化方法
在实际开发中,可以根据需要选择合适的项目初始化方法。如果脚手架工具生成的代码,在目录结构设计、开发风格、代码质量、架构设计、功能列表等方面能够满足你的需求,则可以优先考虑使用工具来快速初始化 Go 项目。如果工具不能满足需求,建议基于一个优秀的 Go 项目进行魔改,例如,可以魔改 https://github.com/onexstack/miniblog 项目为一个新的项目。
2. 初始化项目仓库
2.1 创建项目目录并添加 README 文件
在开始初始化项目之前,需先设计好项目的名称。一个简洁、易懂且合适的项目名是开发高质量 Go 项目的第一步。通常,需要提前确认以下名称:
- **项目名称:**项目名要具有一定语义,说明该项目的功能,建议的格式为==纯小写的精短名字==。如果项目名字过长,可以按单词用中杠线(-)分割,但最好不要使用。以下是一些合格的名字:api、controllermanager、controller-manager。不建议命名为:controller_manager;
- **项目名称大小写:**还需确认项目名在代码中的大小写格式。统一大小写格式可以使整个代码命名格式保持统一。例如:controller-manager/controllermanager 项目的小写格式为 controllermanager,大写格式为 ControllerManager;
- **项目名简写格式:**有些项目名出于易读性考虑,可能会较长。在编写代码时,如果引用了项目名,可能会导致代码行过长,为了使代码行简短易读,通常会采用简写模式。带中杠线分割的项目名的简短模式一般为每个单词的首字母,例如:controller-manager 为 cm。不带中杠线分割的项目名简写模式需要根据具体名字确定,且没有统一的命名规则,例如:controller 可以简写为 ctrl。
通过执行以下命令来创建目录,并在项目目录中添加一个 README.md 文件:
1 | |
提示:
可以使用 https://readme.so 工具来协助生成 README 文件,通常 README 文件需要包含以下部分:Features、Installation、Usage/Examples、Documentation、Feedback、Contributing、Authors、License、Related。
2.2 初始化目录为 Go 模块
miniblog 是一个 Go 项目,根据 Go 语法要求,还需要将该项目初始化为一个 Go 模块,并添加到 Go 工作区中。初始化命令如下:
1 | |
2.3 初始化目录为 Git 仓库
当前项目开发基本上都是使用 Git 来管理项目源码,因此,还需要将项目仓库初始化为一个 Git 仓库。
在提交代码时,有些文件,例如备份文件、临时文件和日志文件不需要提交到项目仓库中,可以通过在项目目录下添加 .gitignore 文件来忽略这些文件。如果你不知道如何配置 .gitignore 文件中的内容,可以借助 .gitignore 文件生成工具来自动生成一个可用的 .gitignore 文件,例如 gitignore.io 就是一个很好用的 .gitignore 文件生成工具。miniblog 项目使用的 .gitignore 文件如下述代码所示。
可以执行以下命令将 Go 项目仓库初始化为一个 Git 仓库:
1 | |
2.4 创建需要的目录
初始化代码仓库后,我们可以根据前面设计的目录规范创建一些空目录,例如:
1 | |

提前创建符合目录规范的空目录,可以带来以下好处:
- 提前规划目录相当于提前规划未来的功能,将未来要实现的功能以目录形式固化在项目仓库中,起到记录作用;
- 有利于后续文件按照功能存放在预先规划好的目录中,使项目更加规范。否则,不同开发者可能会根据各自的开发习惯,创建各种各样的目录结构和命名。
例如,可以将之前设计好的规范存放在 docs/devel/zh-CN/conversions 目录中。由于 Git 不追踪空目录,为了让 Git 追踪空目录,我们可以在空目录下创建一个空文件 .keep,并在适当的时候执行以下命令删除这些临时文件:
1 | |
[!important]
命令拆解与作用
**find . -name .keep**:
find是用于查找文件和目录的命令,.表示从当前目录开始搜索(也可替换为具体路径,如/home/user/project)。name .keep是按名称筛选,只找名为.keep的文件 / 目录(这类文件常作为占位符,让 Git 等版本控制保留空目录 )。**xargs -i rm {}**:
xargs把前一个命令(find)的输出,转成后续命令(rm)的参数。i是xargs的选项,让{}作为占位符,指代find找到的每个.keep文件路径。rm {}就是删除这些.keep文件,{}会被实际路径替换,实现逐个删除。
miniblog 项目的完整目录结构说明见 docs/devel/zh-CN/directory.md 文件。
2.5 创建 Hello World 程序并编译二进制文件
一个全新的项目,需要先编写一个最简单的 Hello World 程序,以检查开发和编译环境是否就绪。根据目录规范,需要在 cmd/mb-apiserver 目录下创建 main.go 文件,内容如下:
1 | |
执行以下命令编译并运行此 Hello World 程序:
1 | |

编译 success ~~~
main 文件所在的目录 mb-apiserver 也是 miniblog APIServer 的组件名。在 Go 项目开发中,通常在组件名中包含项目的简写前缀 mb-,通过 mb- 前缀,可以很容易地辨别该组件是 miniblog 的 APIServer 组件。此外,通过 mb- 前缀,也可以有效避免组件名与其他项目的组件名发生冲突。
3. 使用 Air 工具热加载 go 应用
- 在 Go 项目开发过程中,经常需要修改代码、编译代码、重新启动程序,然后测试程序。若每次都手动操作,则效率较低。此时,可以借助程序热加载工具来自动编译并重启程序。在 Go 生态中,有许多此类工具,其中较为流行的是 Air 工具。你可以直接参考 Air 官方文档了解如何使用 Air 工具。
以下是安装和配置 Air 工具的步骤:
- 安装 Air 工具
安装命令如下:
1 | |
- 配置 Air 工具
这里我们使用 Air 官方仓库中给出的示例配置:air_example.toml。air_example.toml 中的示例配置基本能满足绝大部分项目需求,一般只需再配置 cmd、bin、args_bin 三个参数即可。
在 miniblog 项目根目录下创建 .air.toml 文件,文件内容见 miniblog 仓库 feature/s01 分支下的 .air.toml 文件。.air.toml 基于 air_example.toml 文件修改了以下参数配置:
1 | |
- 启动 Air 工具
配置完成后,在项目根目录下运行 air 命令:
1 | |
4. 添加版权声明文件 LICENSE 和版本声明
如果项目是一个开源项目或计划在未来开源,则需要为项目添加版权声明,主要包括以下内容:
- 存放在项目根目录下的 LICENSE 文件,用于声明项目所遵循的开源协议;
- 项目源文件中的版权头信息,用于说明文件所遵循的开源协议。
业界当前有上百种开源协议可供选择,常用的有六种,按从严格到宽松的顺序依次为:GPL、MPL、LGPL、Apache、BSD、MIT。
miniblog 项目使用了最宽松的 MIT 协议。
4.1 miniblog 添加 LICENSE 文件
一般项目的根目录下会存放一个 LICENSE 文件,用于声明开源项目所遵循的协议,因此我们也需要为 miniblog 初始化一个 LICENSE 文件。我们可以使用 license 工具来生成 LICENSE 文件,具体操作命令如下:
1 | |
上述命令将在当前目录下生成一个名为 LICENSE 的文件,该文件包含 MIT 开源协议声明。
4.2 给源文件添加版本声明
除了添加整个项目的开源协议声明,还可以为每个源文件添加版权头信息,以声明文件所遵循的开源协议。miniblog 的版权头信息保存在 scripts/boilerplate.txt 文件中。
提示:
版权头信息保存的文件名,通常命名为 boilerplate。
有了版权头信息,在新建文件时需要将这些信息放在文件头中。如果手动添加,不仅容易出错,还容易遗漏文件。最好的方法是通过自动化手段追加版权头信息。追加方法如下。
- 安装 addlicense 工具
1 | |
- 运行 addlicense 工具添加版权头信息
运行以下命令添加版权头信息。
1 | |
可以看到 main.go 文件已经添加了版权头信息,内容如下:
1 | |
5. 编写 Makefile 脚本
- 学习 Makefile 基本语法,可参考 docs/book/makefile.md 文件
- 学习 Makefile 高级语法(如果有时间或感兴趣):陈皓老师编写的《跟我一起写 Makefile(PDF 重制版)》
miniblog 项目的 Makefile 文件位于项目根目录下,内容如下:
1 | |
在编写 Makefile 规则之后,可以执行 make
项目支持了 Makefile 之后,未来所有的编译、单元测试等项目管理操作,都建议通过执行 Makefile 规则来完成。添加了 Makefile 之后,还需要更新 .air.toml 文件,将其中的 cmd 改成cmd = “make build”。
上述 Makefile 文件中的 Makefile 规则如下表所示:

📎 参考文章
- [05 | 项目初始化(上):如何初始化一个 Go 项目仓库?(https://articles.zsxq.com/id_x2tuum620z3a.html)
- 06 | 项目初始化(下):给新项目添加初始文件