深度解析 tuist init 生成的目录结构
当你运行 tuist init 命令创建新项目时,Tuist 会自动生成一套完整的项目结构。本文将以实际生成的项目为例,详细解析每个目录和文件的作用,帮助你深入理解 Tuist 的设计理念。
项目整体结构概览
Section titled “项目整体结构概览”运行 tuist init 后,生成的项目结构如下:
ProjMeta/├── .gitignore├── mise.toml├── Project.swift├── Tuist.swift├── Tuist/│ └── Package.swift└── ProjMeta/ ├── Resources/ │ ├── Assets.xcassets/ │ │ ├── AccentColor.colorset/ │ │ │ └── Contents.json │ ├── AppIcon.appiconset/ │ │ └── Contents.json │ └── Contents.json ├── Sources/ │ ├── ProjMetaApp.swift │ └── ContentView.swift └── Tests/ └── ProjMetaTests.swift根目录核心文件
Section titled “根目录核心文件”Project.swift
Section titled “Project.swift”Project.swift 是 Tuist 项目中最核心的清单文件,它定义了 Xcode 项目的结构:
import ProjectDescription
let project = Project( name: "ProjMeta", targets: [ .target( name: "ProjMeta", destinations: .macOS, product: .app, bundleId: "dev.tuist.ProjMeta", infoPlist: .default, buildableFolders: [ "ProjMeta/Sources", "ProjMeta/Resources", ], dependencies: [] ), .target( name: "ProjMetaTests", destinations: .macOS, product: .unitTests, bundleId: "dev.tuist.ProjMetaTests", infoPlist: .default, buildableFolders: [ "ProjMeta/Tests" ], dependencies: [.target(name: "ProjMeta")] ), ])这个文件告诉 Tuist:
- 项目名称为
ProjMeta - 包含两个 targets:主应用和单元测试
- 目标平台是 macOS
- bundle identifier 为
dev.tuist.ProjMeta - 源代码和资源文件分别来自
Sources和Resources目录 - 测试 target 依赖主 target
Tuist.swift
Section titled “Tuist.swift”Tuist.swift 是项目根目录的标识文件,同时可以包含项目级别的配置:
import ProjectDescription
let tuist = Tuist()虽然这个文件在简单项目中内容简洁,但它有两个重要作用:
- 标识项目根目录:Tuist 通过查找
Tuist/目录来确定项目根位置 - 全局配置:可以在此配置生成选项、部署目标等
mise.toml
Section titled “mise.toml”mise.toml 是 Mise 工具管理器的配置文件:
[tools]tuist = "4.153.0"这确保项目使用特定版本的 Tuist,实现团队成员间的版本一致性。
.gitignore
Section titled “.gitignore”Tuist 生成的 .gitignore 文件针对 macOS、Xcode 和 Tuist 做了优化:
### macOS ###.DS_Store.AppleDouble# ... 其他 macOS 系统文件
### Xcode ###xcuserdata/build/DerivedData/*.xcodeproj*.xcworkspace
### Tuist derived files ###graph.dotDerived/
### Tuist managed dependencies ###Tuist/.build关键点:
- 忽略 Xcode 用户数据,避免团队协作冲突
- 忽略 build 产物和 DerivedData
- 忽略 Tuist 的
.build目录(包含缓存的依赖) - 注意:不忽略
Project.swift和Tuist.swift,这些需要提交到版本控制
Tuist 目录
Section titled “Tuist 目录”Tuist/ 目录是 Tuist 项目的标志性目录,它的存在告诉 Tuist 当前目录是项目根。
Tuist/Package.swift
Section titled “Tuist/Package.swift”这个文件用于声明 Swift Package Manager 依赖:
import PackageDescription
#if TUIST import struct ProjectDescription.PackageSettings
let packageSettings = PackageSettings( productTypes: [:] )#endif
let package = Package( name: "ProjMeta", dependencies: [ // 在此添加你的依赖 ])特点:
- 使用
#if TUIST条件编译,让这个文件同时被 Tuist 和 Swift PM 使用 - Tuist 会自动将这里的依赖集成到生成的 Xcode 项目中
- 你可以在这里添加任何 SPM 包,如 Alamofire、Kingfisher 等
ProjMeta 源代码目录
Section titled “ProjMeta 源代码目录”ProjMeta/Sources/
Section titled “ProjMeta/Sources/”这是应用的主要源代码目录。
ProjMetaApp.swift
Section titled “ProjMetaApp.swift”应用入口点,使用 SwiftUI:
import SwiftUI
@mainstruct ProjMetaApp: App { var body: some Scene { WindowGroup { ContentView() } }}@main属性标记应用入口WindowGroup是 macOS 应用的标准场景类型- 自动创建包含
ContentView的主窗口
ContentView.swift
Section titled “ContentView.swift”主视图文件:
import SwiftUI
public struct ContentView: View { public init() {}
public var body: some View { Text("Hello, World!") .padding() }}
struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() }}包含:
- 公开的
ContentView结构体 - Xcode 预览支持(SwiftUI Preview Provider)
ProjMeta/Resources/
Section titled “ProjMeta/Resources/”资源目录存放应用的非代码资源。
Assets.xcassets/
Section titled “Assets.xcassets/”Assets.xcassets 是 Xcode 的资产目录,用于集中管理图片、颜色等资源。
Contents.json - 资产目录的根清单:
{ "info" : { "author" : "xcode", "version" : 1 }}AppIcon.appiconset/ - 应用图标集:
{ "images" : [ { "idiom": "mac", "scale": "1x", "size": "16x16" }, { "idiom": "mac", "scale": "2x", "size": "16x16" }, // ... 其他尺寸:32x32, 128x128, 256x256, 512x512 ], "info" : { "author": "xcode", "version": 1 }}macOS 应用需要 16x16、32x32、128x128、256x256、512x512 多种尺寸的图标,每个尺寸有 1x 和 2x 两种分辨率。
AccentColor.colorset/ - 强调色配置:
{ "colors" : [{ "idiom": "universal" }], "info" : { "author": "xcode", "version": 1 }}使用 universal 表示适配所有平台的自适应强调色。
ProjMeta/Tests/
Section titled “ProjMeta/Tests/”测试目录,包含单元测试文件。
ProjMetaTests.swift
Section titled “ProjMetaTests.swift”import XCTest@testable import ProjMeta
final class ProjMetaTests: XCTestCase { func testExample() throws { // 测试用例 }}关键设计理念
Section titled “关键设计理念”通过分析 tuist init 生成的项目结构,我们可以看到 Tuist 的几个核心设计理念:
1. 约定优于配置
Section titled “1. 约定优于配置”Tuist 提供了合理的默认值:
- 源代码目录默认为
Sources或Source - 资源目录默认为
Resources或Resource - 测试目录默认为
Tests
你只需要在 Project.swift 中声明性地描述项目结构,Tuist 会自动处理生成细节。
2. 声明式配置
Section titled “2. 声明式配置”与 Xcode 的 pbxproj 文件相比,Project.swift 使用 Swift 进行声明式配置:
- 可读性强,易于理解
- 利用 Swift 编译器进行类型检查
- 可以使用 Swift 的所有特性(函数、扩展等)来组织代码
3. 关注点分离
Section titled “3. 关注点分离”- Project.swift:项目结构和 target 定义
- Tuist.swift:全局配置
- Tuist/Package.swift:依赖声明
- Sources/:应用代码
- Resources/:资源文件
每个目录和文件都有明确的职责。
4. 可预测性
Section titled “4. 可预测性”所有生成的文件都有明确的规则:
- 生成的 Xcode 项目结构可预测
- 依赖解析过程透明
- 可以使用
tuist graph可视化项目结构
理解了这个基础项目结构后,你可以:
- 运行项目:使用
tuist generate生成 Xcode 项目,然后用 Xcode 打开 - 添加依赖:编辑
Tuist/Package.swift添加 SPM 依赖 - 自定义配置:修改
Project.swift调整 target 设置 - 深入学习:阅读
清单文件 文档了解更多配置选项
tuist edit 在 Xcode 中编辑项目。