跳转到内容

深度解析 tuist init 生成的目录结构

当你运行 tuist init 命令创建新项目时,Tuist 会自动生成一套完整的项目结构。本文将以实际生成的项目为例,详细解析每个目录和文件的作用,帮助你深入理解 Tuist 的设计理念。

运行 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

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
  • 源代码和资源文件分别来自 SourcesResources 目录
  • 测试 target 依赖主 target

Tuist.swift 是项目根目录的标识文件,同时可以包含项目级别的配置:

import ProjectDescription
let tuist = Tuist()

虽然这个文件在简单项目中内容简洁,但它有两个重要作用:

  1. 标识项目根目录:Tuist 通过查找 Tuist/ 目录来确定项目根位置
  2. 全局配置:可以在此配置生成选项、部署目标等

mise.tomlMise 工具管理器的配置文件:

[tools]
tuist = "4.153.0"

这确保项目使用特定版本的 Tuist,实现团队成员间的版本一致性。

Tuist 生成的 .gitignore 文件针对 macOS、Xcode 和 Tuist 做了优化:

### macOS ###
.DS_Store
.AppleDouble
# ... 其他 macOS 系统文件
### Xcode ###
xcuserdata/
build/
DerivedData/
*.xcodeproj
*.xcworkspace
### Tuist derived files ###
graph.dot
Derived/
### Tuist managed dependencies ###
Tuist/.build

关键点:

  • 忽略 Xcode 用户数据,避免团队协作冲突
  • 忽略 build 产物和 DerivedData
  • 忽略 Tuist 的 .build 目录(包含缓存的依赖)
  • 注意:不忽略 Project.swiftTuist.swift,这些需要提交到版本控制

Tuist/ 目录是 Tuist 项目的标志性目录,它的存在告诉 Tuist 当前目录是项目根。

这个文件用于声明 Swift Package Manager 依赖:

6.0
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 等

这是应用的主要源代码目录。

应用入口点,使用 SwiftUI:

import SwiftUI
@main
struct ProjMetaApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
  • @main 属性标记应用入口
  • WindowGroup 是 macOS 应用的标准场景类型
  • 自动创建包含 ContentView 的主窗口

主视图文件:

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)

资源目录存放应用的非代码资源。

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 表示适配所有平台的自适应强调色。

测试目录,包含单元测试文件。

import XCTest
@testable import ProjMeta
final class ProjMetaTests: XCTestCase {
func testExample() throws {
// 测试用例
}
}

通过分析 tuist init 生成的项目结构,我们可以看到 Tuist 的几个核心设计理念:

Tuist 提供了合理的默认值:

  • 源代码目录默认为 SourcesSource
  • 资源目录默认为 ResourcesResource
  • 测试目录默认为 Tests

你只需要在 Project.swift 中声明性地描述项目结构,Tuist 会自动处理生成细节。

与 Xcode 的 pbxproj 文件相比,Project.swift 使用 Swift 进行声明式配置:

  • 可读性强,易于理解
  • 利用 Swift 编译器进行类型检查
  • 可以使用 Swift 的所有特性(函数、扩展等)来组织代码
  • Project.swift:项目结构和 target 定义
  • Tuist.swift:全局配置
  • Tuist/Package.swift:依赖声明
  • Sources/:应用代码
  • Resources/:资源文件

每个目录和文件都有明确的职责。

所有生成的文件都有明确的规则:

  • 生成的 Xcode 项目结构可预测
  • 依赖解析过程透明
  • 可以使用 tuist graph 可视化项目结构

理解了这个基础项目结构后,你可以:

  1. 运行项目:使用 tuist generate 生成 Xcode 项目,然后用 Xcode 打开
  2. 添加依赖:编辑 Tuist/Package.swift 添加 SPM 依赖
  3. 自定义配置:修改 Project.swift 调整 target 设置
  4. 深入学习:阅读 清单文件 文档了解更多配置选项

编辑项目 了解更多关于如何使用 tuist edit 在 Xcode 中编辑项目。