多 Target 工程配置
本教程将介绍如何在 Tuist 中创建和管理多 Target 工程,包括:
- 创建 App、Framework 和 Tests target
- 配置 Target 之间的依赖关系
- 使用
tuist graph生成依赖关系图
什么是 Target?
Section titled “什么是 Target?”在 Xcode 中,Target 表示一个将被构建的产品。每个 target 定义了一个产品(App、Framework、Library 等)以及构建该产品所需的源代码和资源文件。
多 Target 项目的典型结构:
- App Target: 主应用程序
- Framework Target: 业务模块或共享代码
- Tests Target: 单元测试或 UI 测试
配置多 Target 项目
Section titled “配置多 Target 项目”Project.swift 配置
Section titled “Project.swift 配置”在 Project.swift 文件中定义多个 target:
import ProjectDescription
let project = Project( name: "ProjMeta", targets: [ // Framework Target - 业务模块 .target( name: "CoreModule", destinations: .macOS, product: .framework, bundleId: "dev.tuist.CoreModule", infoPlist: .default, buildableFolders: [ "CoreModule/Sources", ], dependencies: [] ), // App Target - 主应用程序 .target( name: "ProjMeta", destinations: .macOS, product: .app, bundleId: "dev.tuist.ProjMeta", infoPlist: .default, buildableFolders: [ "ProjMeta/Sources", "ProjMeta/Resources", ], dependencies: [.target(name: "CoreModule")] ), // Tests Target - 单元测试 .target( name: "ProjMetaTests", destinations: .macOS, product: .unitTests, bundleId: "dev.tuist.ProjMetaTests", infoPlist: .default, buildableFolders: [ "ProjMeta/Tests" ], dependencies: [ .target(name: "ProjMeta"), .target(name: "CoreModule") ] ), ])Target 配置属性
Section titled “Target 配置属性”| 属性 | 说明 | 示例值 |
|---|---|---|
name | Target 名称 | "CoreModule" |
destinations | 目标平台 | .macOS, .iOS, .iOSAndmacOS |
product | 产品类型 | .app, .framework, .staticFramework, .unitTests |
bundleId | Bundle 标识符 | "dev.tuist.CoreModule" |
buildableFolders | 源代码文件夹 | ["CoreModule/Sources"] |
dependencies | 依赖列表 | [.target(name: "CoreModule")] |
Tuist 支持多种依赖配置方式:
// 同一项目内的 target.target(name: "MyFramework")
// 不同项目的 target.project(target: "MyFramework", path: "../FrameworkProject")
// 二进制框架.framework(path: "path/to/Framework.framework")
// 系统 SDK.sdk(name: "Foundation")
// Swift Package Manager 外部包.external(name: "PackageName").framework 与 .staticFramework 的区别
Section titled “.framework 与 .staticFramework 的区别”在 Tuist 中配置 Framework 类型的 Target 时,可以使用 .framework 或 .staticFramework 两种产品类型。它们的主要区别在于链接方式:
| 特性 | .framework (动态) | .staticFramework (静态) |
|---|---|---|
| 链接方式 | 动态链接,运行时加载 | 静态链接,编译时合并 |
| 链接时机 | 运行时链接 | 编译时链接 |
| App 体积 | 较小(共享 Framework) | 较大(代码复制到 App) |
| 编译速度 | 较快(无需重新链接) | 较慢(每次编译都重新链接) |
| 资源文件 | 可以包含 | 不包含(需单独处理) |
| 嵌入 App | 需要嵌入 Frameworks 目录 | 无需嵌入 |
| 冷启动 | 稍慢(需加载 Framework) | 较快(代码已打包) |
| 版本控制 | 可多 App 共享同一版本 | 每个 App 独立副本 |
选择 .framework (动态 Framework) 的场景:
- 多个 App 共用同一个 Framework(如 SDK)
- Framework 需要包含资源文件(图片、Storyboard 等)
- 减少最终 App 包体积
- 希望 Framework 可以独立更新
选择 .staticFramework 的场景:
- 对启动性能要求极高的场景
- 不需要包含资源文件
- 希望简化分发(无需嵌入 Framework)
- 避免动态链接带来的兼容性问题
// 动态 Framework.target( name: "CoreModule", product: .framework, // 动态链接 // ...)
// 静态 Framework.target( name: "CoreModule", product: .staticFramework, // 静态链接 // ...)生成项目并查看关系图
Section titled “生成项目并查看关系图”步骤 1: 生成 Xcode 项目
Section titled “步骤 1: 生成 Xcode 项目”cd demo/ProjMetatuist generate步骤 2: 生成依赖关系图
Section titled “步骤 2: 生成依赖关系图”# 生成 PNG 格式的依赖图(默认)tuist graph
# 跳过测试目标tuist graph -t
# 指定平台过滤tuist graph -l macos
# 指定输出格式tuist graph -f pngtuist graph -f svgtuist graph -f dottuist graph -f json生成的关系图
Section titled “生成的关系图”运行上述命令后,Tuist 会生成一个 PNG 文件,显示 Target 之间的依赖关系:

从图中可以清晰看到:
- CoreModule (.framework) - 基础框架,无依赖
- ProjMeta (App) - 依赖于 CoreModule
- ProjMetaTests (Unit Tests) - 依赖于 ProjMeta 和 CoreModule
在代码中使用 Target 依赖
Section titled “在代码中使用 Target 依赖”在 App 中引用 Framework
Section titled “在 App 中引用 Framework”在 SwiftUI 视图中使用 Framework:
import SwiftUIimport CoreModule
public struct ContentView: View { public init() {}
private let coreModule = CoreModule(name: "CoreModule")
public var body: some View { Text(coreModule.greet()) .padding() }}Framework 代码示例
Section titled “Framework 代码示例”import Foundation
public struct CoreModule { public let name: String
public init(name: String = "CoreModule") { self.name = name }
public func greet() -> String { return "Hello from \(name)" }}Q: 如何添加新的 Target?
Section titled “Q: 如何添加新的 Target?”在 Project.swift 的 targets 数组中添加新的 .target() 配置,并确保在 dependencies 中正确配置依赖关系。
Q: 如何查看所有 Target 的依赖?
Section titled “Q: 如何查看所有 Target 的依赖?”运行 tuist graph 命令,它会自动生成可视化的依赖关系图。
Q: 测试 Target 应该依赖哪些 Target?
Section titled “Q: 测试 Target 应该依赖哪些 Target?”测试 Target 通常依赖:
- 被测试的产品 Target(如 App 或 Framework)
- 任何被测试代码直接依赖的模块
Q: 如何处理 Target 之间的循环依赖?
Section titled “Q: 如何处理 Target 之间的循环依赖?”避免创建循环依赖。正确的依赖方向应该是:
- App → Framework → 更底层的 Framework
- Tests → App/Framework
本教程介绍了:
- 多 Target 配置: 在
Project.swift中定义 App、Framework 和 Tests target - 依赖关系配置: 使用
.target()配置 Target 之间的依赖 - 关系图生成: 使用
tuist graph可视化项目结构
这种多 Target 架构有助于:
- 代码复用:将共享代码提取到 Framework 中
- 模块化:保持代码结构清晰
- 测试:便于编写和运行单元测试