原则
本页描述了 Tuist 设计和开发的支柱原则。它们随着项目发展而演进,旨在确保与项目基础高度一致、可持续的增长。
默认采用约定
Section titled “默认采用约定”Tuist 存在的原因之一是 Xcode 在约定方面很弱,这导致项目复杂难以扩展和维护。因此,Tuist 采取了不同的方法,默认采用简单且经过精心设计的约定。开发者可以选择不遵循约定,但这是一个不自然的自觉决定。
例如,有一个通过使用提供的公共接口来定义 target 之间依赖关系的约定。通过这样做,Tuist 确保生成的项目具有正确配置以使链接正常工作。开发者可以选择通过构建设置定义依赖关系,但他们这样做是隐式的,因此会破坏依赖某些约定才能工作的 Tuist 功能,如 tuist graph 或 tuist cache。
我们默认采用约定的原因是,我们能为开发者做的决策越多,他们就能更专注于为应用编写功能。当我们像许多项目中那样没有任何约定时,我们必须做出最终不会与其他决策保持一致的决策,结果就会产生难以管理的偶然复杂性。
清单文件是事实的来源
Section titled “清单文件是事实的来源”在多个配置层及其之间的契约会导致难以推理和维护的项目设置。想一想一个普通项目。项目定义存在于 .xcodeproj 目录中,CLI 在脚本中(如 Fastfiles),CI 逻辑在管道中。这三层之间有我们需要维护的契约。你有多少次遇到过这样的情况:你在项目中更改了某些内容,一周后才意识到发布脚本坏了?
我们可以通过拥有一个单一的事实来源(清单文件)来简化这个问题。这些文件为 Tuist 提供生成开发者可用于编辑文件的 Xcode 项目所需的信息。此外,它允许从本地或 CI 环境使用标准命令构建项目。
Tuist 应该拥有复杂性,并向他们公开一个尽可能明确描述项目的简单、安全和愉快的接口。
将隐式变为显式
Section titled “将隐式变为显式”Xcode 支持隐式配置。一个很好的例子是推断隐式定义的依赖关系。虽然隐式对于配置简单的小型项目来说没问题,但随着项目变大,可能会导致缓慢或奇怪的行为。
Tuist 应为隐式 Xcode 行为提供显式 API。它还应支持定义 Xcode 隐式配置,但实现方式应鼓励开发者选择显式方法。支持 Xcode 隐式配置和复杂性有助于 Tuist 的采用,之后团队可以花时间消除隐式配置。
依赖关系的定义就是一个很好的例子。虽然开发者可以通过构建设置和阶段定义依赖关系,但 Tuist 提供了一个漂亮的 API 来鼓励采用它。
设计显式 API 允许 Tuist 在项目上运行一些检查和优化,否则这些将不可能实现。 此外,它启用了 tuist graph 等功能,该功能导出依赖图的表示,或 tuist cache,将所有 target 缓存为二进制文件。
扩展 Xcode 项目时面临的主要挑战之一是 Xcode 向用户暴露了大量复杂性。 因此,团队拥有很高的公交车因子系数,只有团队中少数人理解项目和构建系统抛出的错误。这是一个糟糕的情况,因为团队依赖少数人。
Xcode 是一个很棒的工具,但多年的改进、新平台和编程语言都反映在它的表面上,它在努力保持简单。
Tuist 应该抓住机会保持事物的简单性,因为处理简单的事情很有趣而且激励我们。没有人愿意花时间尝试调试在编译过程最后发生的错误,或者理解为什么无法在设备上运行应用。Xcode 将任务委托给其底层构建系统,在某些情况下,它在将错误翻译成可操作项目方面做得非常糟糕。你有没有遇到过 “framework X not found” 错误却不知道该怎么办?想象一下如果给我们一个潜在根本原因列表会怎样。
从开发者体验出发
Section titled “从开发者体验出发”Xcode 周围缺乏创新的部分原因,或者换句话说,不像其他编程环境那样有那么多创新,是因为 我们经常从现有解决方案开始分析问题。 因此,我们现在找到的大多数解决方案都围绕相同的想法和工作流。虽然在方程式中包含现有解决方案是好的,但我们不应该让它们限制我们的创造力。
我们喜欢像 Tom Preston 在这个播客中所说的那样:“大多数事情都可以实现,无论你脑子里有什么,只要你做的在宇宙的约束范围内是可能的,你可能都可以用代码实现。” 如果 我们想象开发者体验会是什么样子,实现它只是时间问题——通过从开发者体验开始分析问题给我们一个独特的视角,这将引导我们找到用户会喜欢使用的解决方案。
我们可能会忍不住跟随每个人的做法,即使这意味着延续每个人继续抱怨的不便。让我们不要那样做。我想象如何归档我的应用?我希望代码签名如何?有什么流程我可以帮助 Tuist 简化?例如,添加对 Fastlane 的支持是一个我们需要首先理解的问题的解决方案。我们可以通过问”为什么”来深入了解问题的根源。一旦我们缩小了动机的来源,我们就可以思考 Tuist 如何最好地帮助他们。也许解决方案是集成 Fastlane,但我们必须在我们做出权衡之前不要忽视桌上其他同样有效的解决方案,这一点很重要。
错误可能且将会发生
Section titled “错误可能且将会发生”我们开发者有一种固有的倾向,忽视错误可能发生。因此,我们设计和测试软件时只考虑理想情况。
Swift、其类型系统和良好架构的代码可能有助于防止某些错误,但不是所有错误,因为有些超出我们的控制范围。我们不能假设用户总是有互联网连接,或者系统命令会成功返回。Tuist 运行的环境不是我们控制的沙箱,因此我们需要努力了解它们可能如何变化并影响 Tuist。
处理不当的错误会导致糟糕的用户体验,用户可能会对项目失去信任。我们希望用户享受 Tuist 的每一部分,包括我们向他们呈现错误的方式。
我们应该站在用户的角度,想象我们期望错误告诉我们什么。如果编程语言是错误传播的通信渠道,而用户是错误的目的地,它们应该用目标用户所说的相同语言编写。它们应包含足够的信息来了解发生了什么,并隐藏不相关的信息。此外,它们应该具有可操作性,告诉用户可以采取哪些步骤来从中恢复。
最后但同样重要的是,我们的测试用例应该考虑失败场景。它们不仅确保我们按预期处理错误,还能防止未来的开发者破坏该逻辑。