Swift Package Manager 系列 02|如何创建自己的第一个 Swift Package
真正重要的不是把命令跑通,而是第一次按模块边界而不是按文件夹思维组织代码
很多教程在讲“创建第一个 Swift Package”时,都会把重点放在命令或 Xcode 操作上。
当然,这些步骤需要知道。但如果只是会点“New Package”,你其实只学会了“生成一个模版”,还没有真正理解创建 Package 这件事的工程意义。
因为你第一次创建自己的 Swift Package,真正开始发生变化的不是目录结构,而是你的思考方式:
- 这段代码是不是值得独立成一个模块
- 这个模块应该暴露什么接口
- 哪些实现细节应该藏起来
- 它依赖谁,又该被谁依赖
所以这篇文章我更想讲的不是按钮怎么点,而是第一次创建 Package 时应该带着什么判断。
一、先别急着建 Package,先问这段代码为什么不该继续留在主工程里
这是我最在意的一步。
很多人一上来就说:“我们来模块化一下。”
但真正值得问的是:
这段代码为什么要脱离当前工程上下文,变成一个独立模块?
常见的合理理由包括:
- 它会被多个目标或多个业务模块复用
- 它本身已经形成相对稳定的领域能力
- 它不应该再依赖页面或宿主工程细节
- 它值得有单独的测试边界
如果这些理由一个都说不出来,只是“感觉文件太多了”,那很可能还没到该建 Package 的时候。
Package 不是用来收纳文件的,它是用来表达边界的。
二、第一次最适合抽出去的,通常不是业务大模块,而是边界清楚的小能力
如果团队刚开始接触 SPM,我通常不建议第一刀就去拆:
- 整个首页
- 整个账号系统
- 整个支付模块
因为这些模块经常和宿主工程、页面层、路由层、状态层深度耦合,一旦边界没设计清楚,第一次拆分就容易挫败。
更适合当第一批 Package 的,通常是这些能力:
- 网络层基础能力
- 日志、监控、埋点封装
- 图片处理或缓存工具
- 某个明确的领域模型库
- 一组相对稳定的 UI 基础组件
这些模块共同特点是:
- 依赖少
- 职责单一
- 边界相对清楚
它们更适合帮助团队建立“什么叫独立模块”的感觉。
三、第一次创建 Package 时,最关键的不是目录,而是公开接口
很多人建完第一个 Package 后,马上会把注意力放在目录怎么摆。
但从工程角度看,真正更重要的是:
- 模块对外公开什么
- 模块内部保留什么
你可以把创建 Package 这件事理解成一次自我约束:
- 哪些类型真的值得暴露成
public - 哪些工具函数应该只留在内部
- 哪些依赖不应该让调用方知道
如果你只是把原来主工程里的所有东西原样搬进一个 Package,再一股脑改成 public,那它其实没有真正形成边界。
所以第一次做 Package,最值得练习的不是“搬代码”,而是“定义接口”。
四、一个最常见的误区:先建 Package,再想模块职责
这个顺序很容易出问题。
正确顺序通常应该是:
- 先明确这段能力的职责边界
- 再看它是否值得独立成模块
- 最后用 Package 形式承载它
如果顺序反过来,常见后果是:
- 一个 Package 什么都想管
- 内部依赖混乱
- 对外接口过大
- 宿主工程还是得知道很多实现细节
也就是说,SPM 不能替你做模块设计,它只是更适合承载已经想清楚的模块。
五、第一次创建 Package 时,我最在意的四个问题
如果我在 review 一个团队的第一个 Package,我最常问的是这四个问题:
1. 这个模块有没有清晰的单一职责
如果一个模块同时处理网络、缓存、页面状态、埋点,那多半还没想清楚。
2. 它的依赖是否足够少
第一次做 Package 时,依赖越少越容易成功。
依赖一多,边界就容易糊。
3. 它的公开接口是不是比内部实现小得多
如果模块内部十个类型,结果八个都要暴露出去,说明边界控制得不够好。
4. 它值不值得拥有独立测试
值得独立测试的模块,通常也更值得独立存在。
如果你根本想不到该怎么单测它,那它很可能仍然和宿主上下文缠得太紧。
六、第一次成功的标准,不是“拆得多”,而是“拆得稳”
很多团队第一次做模块化时,最容易追求“成果感”,比如:
- 一口气拆 10 个模块
- 所有公共代码都进 Package
- 主工程立刻瘦了一大圈
但真实项目里,第一次成功更重要的标准通常是:
- 有一个模块边界清楚
- 外部依赖关系是健康的
- 团队理解了为什么这样拆
- 它在接下来几次迭代里没有迅速反噬
因为模块化最怕的不是慢,而是第一步就把大家对这件事的信心做没了。
七、结论:第一个 Swift Package 真正教会你的,是怎么按边界组织代码
如果只用一句话总结,我会说:
创建第一个 Swift Package 的真正意义,不是学会一个新工具,而是第一次被迫认真回答“这段代码为什么值得成为一个独立模块”。
一旦你开始从这个角度看问题,SPM 就不再只是“我会不会用”,而是你开始真正进入模块化工程思维的入口。