Swift 单体仓库:面向初学者的代码组织指南
当您开始使用 Swift 为 iOS 或 macOS 开发应用程序时,迟早会面临一个问题:如何组织代码,使其不会变得混乱?特别是当您有多个项目时(例如,iOS 应用、watchOS 扩展和基于 Vapor 的后端)。其中一种现代方法是单体仓库(monorepo)。在本文中,我们将探讨什么是单体仓库,为什么它在 Swift 开发中很有用,以及如何在实际中组织它。
什么是单体仓库,为什么需要它?
单体仓库(monorepo)是一种代码管理方法,其中所有项目、库和模块都存储在一个仓库中(例如,Git)。与每个项目都存放在自己独立存储库中的多仓库方法不同,单体仓库将所有内容整合在一个地方。
对于 Swift 开发者来说,这带来了几个优势:
- 统一的依赖版本 — 您确切知道所有项目中使用的库版本。
- 简化的重构 — 在一个库中更改 API 会立即在所有依赖项目中体现。
- 共享配置 — 一个 SwiftLint,一个 CI/CD 配置,一套格式化规则。
- 易于搜索 — 所有内容都在一个地方,无需在仓库之间切换。
然而,也有一些注意事项:单体仓库需要纪律和正确的结构,否则它会变成一个“垃圾场”。但对于初学者来说,这是学习组织代码的绝佳方式。
Swift 项目的单体仓库结构
假设您正在创建一个包含共享模块的 iOS 应用。一个典型的 Swift 单体仓库结构可能如下所示:
MyMonorepo/├── Apps/│ ├── iOSApp/ # 主 iOS 应用│ │ ├── Sources/│ │ ├── Resources/│ │ └── Package.swift│ └── macOSApp/ # macOS 版本│ ├── Sources/│ └── Package.swift├── Packages/│ ├── Core/ # 通用工具(网络、日志记录)│ │ ├── Sources/│ │ └── Package.swift│ ├── UIComponents/ # 可复用的 UI 组件│ │ ├── Sources/│ │ └── Package.swift│ └── Analytics/ # 分析模块│ ├── Sources/│ └── Package.swift├── Scripts/ # 辅助脚本├── .swiftlint.yml # 统一的 linter 配置├── Package.swift # 根清单(可选)└── README.md请注意:这里使用了Swift Package Manager (SPM)——Swift 中管理依赖关系的标准工具。每个模块都是一个独立的 Swift Package,可以连接到应用程序。
如何创建 Swift 单体仓库:分步指南
让我们创建一个包含两个模块和一个应用程序的简单单体仓库。在终端中执行以下步骤:
步骤 1:创建根目录并初始化 Git
mkdir MyMonorepocd MyMonorepogit init步骤 2:创建文件夹结构
mkdir -p Apps/iOSApp/Sourcesmkdir -p Packages/Core/Sourcesmkdir -p Packages/UIComponents/Sources步骤 3:为 Core 模块创建 Package.swift
创建文件 Packages/Core/Package.swift:
// swift-tools-version:5.9import PackageDescription
let package = Package( name: "Core", platforms: [ .iOS(.v16), .macOS(.v13) ], products: [ .library( name: "Core", targets: ["Core"]) ], targets: [ .target( name: "Core", path: "Sources") ])步骤 4:在 Core 模块中编写简单代码
创建 Packages/Core/Source