精通 Salesforce Scratch Orgs:SFDX 开发人员终极指南

背景与应用场景

作为一名 Salesforce 开发人员,我的日常工作不仅仅是编写 Apex 代码或构建 Lightning Web Components。更重要的是,如何在一个高效、可靠且可预测的环境中完成这些工作。在 Salesforce DX (SFDX) 和 Scratch Orgs 出现之前,我们的开发流程充满了挑战。我们通常依赖于共享的 Developer Sandbox 或 Developer Pro Sandbox,这导致了一系列问题:

・元数据冲突 (Metadata Conflicts): 多个开发人员在同一个沙盒中工作,很容易覆盖彼此的更改,导致“代码覆盖”或“配置丢失”的噩梦。

・环境不一致 (Environment Inconsistency): 每个沙盒都可能因为长时间的累积修改而变得独一无二,这导致了“在我的沙盒里能用,到你那就坏了”的典型问题。这使得持续集成 (Continuous Integration, CI) 的实施变得异常困难。

・漫长的设置周期 (Long Setup Cycles): 创建或刷新一个沙盒需要数小时甚至数天,这严重拖慢了新项目启动或修复关键 Bug 的速度。

・难以进行代码审查 (Difficult Code Reviews): 审查代码时,评审者无法轻松地在一个干净的环境中部署和测试提交的功能分支,只能依赖于静态的代码分析。

为了解决这些痛点,Salesforce 推出了 Scratch Org(临时组织)。Scratch Org 是一种临时的、可配置的、可随时销毁的 Salesforce 环境,它是 Salesforce DX 开发模式的核心。它彻底改变了我们的开发、测试和协作方式。

对于开发人员而言,Scratch Orgs 的主要应用场景包括:

1. 功能隔离开发

为每个新功能、用户故事或 Bug修复创建一个全新的 Scratch Org。这确保了开发工作在一个完全隔离的、干净的环境中进行,不受其他正在进行的工作的干扰。开发完成后,这个环境可以直接销毁,不会留下任何垃圾。

2. 自动化测试

在 CI/CD 流水线中,可以为每次代码提交自动创建一个 Scratch Org,在其中部署代码、运行所有 Apex 单元测试、LWC 测试,甚至端到端测试。测试通过后,环境自动销毁,确保了每次构建都是在一个纯净的环境中验证的。

3. 可靠的代码审查

当一个功能分支被提交并创建 Pull Request 时,审查者或自动化流程可以基于该分支创建一个 Scratch Org。这使得审查者不仅能阅读代码,还能实际操作和测试新功能,从而提供更高质量的反馈。

4. 探索与原型验证

想要尝试一个新的 Salesforce 功能、评估一个 AppExchange 应用或验证一个技术方案?创建一个 Scratch Org 是最理想的选择。你可以在里面尽情“破坏”,而不必担心会影响任何持久化的开发或测试环境。验证结束后,直接删除即可。


原理说明

Scratch Org 的魔力在于其“源驱动 (Source-driven)”的创建和管理机制。它的核心是围绕着两样东西:Dev Hub(开发中心)和 Scratch Org Definition File(Scratch Org 定义文件)。

Dev Hub (开发中心)

Dev Hub 是一个你授权用来创建和管理 Scratch Orgs 的生产或商业版 Salesforce Org。你可以将你的 Production Org 或一个独立的 Developer Edition Org 启用为 Dev Hub。它就像一个“母体”,记录着所有由它创建的 Scratch Orgs 的信息,包括它们的创建时间、过期日期、状态等。我们通过 Salesforce CLI (命令行工具) 向 Dev Hub 发出指令来管理 Scratch Org 的整个生命周期。

Scratch Org Definition File (Scratch Org 定义文件)

这是一个名为 `project-scratch-def.json` 的配置文件,它位于你的 SFDX 项目的 `config` 目录下。这个 JSON 文件是 Scratch Org 的“蓝图”,它精确定义了你想要的 Salesforce 环境是什么样的。通过这个文件,你可以控制:

・版本 (Edition): 如 `Developer`, `Enterprise`, `Professional` 等。

・特性 (Features): 你需要启用的特定功能,例如 `PersonAccounts` (个人客户)、`Communities` (社区)、`MultiCurrency` (多币种) 等。

・设置 (Settings): 更精细化的组织设置,例如 `SecuritySettings` (安全设置) 中的密码策略,或者 `OrgPreferenceSettings` 中的 Chatter 开关等。

当我们执行创建命令时,SFDX CLI 会读取这个定义文件,并向 Dev Hub 发送请求。Dev Hub 会根据这个“蓝图”在 Salesforce 的服务器上动态地构建出一个全新的、符合规范的 Scratch Org。

Scratch Org 的生命周期

作为开发人员,我们与 Scratch Org 的典型交互流程如下:

1. 授权 Dev Hub: 首先,使用 CLI 登录并授权你的 Dev Hub。

2. 创建 Scratch Org: 使用定义文件创建一个新的 Scratch Org,并为其设置一个别名以便于后续引用。

3. 推送元数据: 将本地 SFDX 项目中的所有元数据(Apex 类、LWC、对象、字段等)推送到这个新创建的空环境中。

4. 分配权限: 为默认用户分配必要的权限集 (Permission Set),以便访问应用和功能。

5. 导入数据: 推送预定义的样本数据,以便于开发和测试。

6. 开发与测试: 打开 Scratch Org 进行开发、调试和测试。在本地修改代码后,可以再次推送;在远端通过 UI 做的修改,可以通过拉取 (pull) 命令同步回本地。

7. 删除 Scratch Org: 功能开发完成并合并到主分支后,删除这个 Scratch Org。即使不手动删除,它也会在 1-30 天后自动过期(默认为 7 天)。

这个短暂而自动化的生命周期,强制我们养成将所有重要变更都保存在版本控制系统(如 Git)中的好习惯,因为 Scratch Org 本身是“一次性”的。


示例代码

以下示例展示了创建和管理一个 Scratch Org 的典型过程,所有代码均遵循 Salesforce 官方文档。

1. Scratch Org 定义文件 (`config/project-scratch-def.json`)

这是一个相对复杂的定义文件示例,它创建了一个企业版的 Scratch Org,并启用了个人客户、知识库和一些特定的设置。

{
  "orgName": "DreamHouse Realty",
  "edition": "Enterprise",
  "features": ["PersonAccounts", "Knowledge"],
  "settings": {
    "lightningExperienceSettings": {
      "enableS1DesktopEnabled": true
    },
    "securitySettings": {
      "passwordPolicies": {
        "enableSetPasswordInApi": true
      }
    },
    "mobileSettings": {
      "enableS1EncryptedStoragePref2": false
    },
    "knowledgeSettings": {
        "enableKnowledge": true
    }
  }
}

注释:

  • orgName: 定义了在 Salesforce UI 中显示的公司名称。
  • edition: 指定 Org 的版本,这里是 `Enterprise`。这将影响可用功能和限制。
  • features: 一个数组,用于启用标准 Salesforce 中默认不开启的功能。这里我们启用了 `PersonAccounts` 和 `Knowledge`。
  • settings: 一个对象,用于配置更详细的组织设置。例如,我们启用了 Lightning Experience,并修改了密码策略以允许通过 API 设置密码,这在自动化脚本中非常有用。

2. Salesforce CLI 命令序列

以下是在命令行终端中执行的一系列 SFDX 命令,用于完整地管理一个 Scratch Org 的生命周期。

# 步骤 1: 授权你的 Dev Hub Org (只需要执行一次)
# -d: 设置为默认的 Dev Hub
# -a: 为这个 Org 设置一个别名,例如 'MyDevHub'
sfdx auth:web:login -d -a MyDevHub

# 步骤 2: 基于定义文件创建一个新的 Scratch Org
# -f: 指定 Scratch Org 定义文件的路径
# -a: 为新的 Scratch Org 设置一个别名,例如 'FeatureBranchOrg'
# -d: 将此 Scratch Org 设置为默认的 org,后续命令将自动对它执行
# --durationdays: 设置其生命周期,最大为30
sfdx force:org:create -f config/project-scratch-def.json -a FeatureBranchOrg -d --durationdays 10

# 步骤 3: 将本地项目中的所有元数据推送到 Scratch Org
sfdx force:source:push

# 步骤 4: 为用户分配一个名为 'MyAppAdmin' 的权限集
sfdx force:user:permset:assign -n MyAppAdmin

# 步骤 5: 导入样本数据以进行测试
# -p: 指定数据计划文件的路径
sfdx force:data:tree:import -p ./data/sample-data-plan.json

# 步骤 6: 运行所有的 Apex 测试
sfdx force:apex:test:run --synchronous

# 步骤 7: 在浏览器中打开你的 Scratch Org
sfdx force:org:open

# ... 在此进行开发和调试 ...

# 步骤 8: 从 Scratch Org 拉取通过 UI 进行的变更到本地
sfdx force:source:pull

# 步骤 9: 当工作完成后,删除 Scratch Org
# -u: 指定要删除的 Org 的别名
# -p: 无需确认提示,直接删除 (在自动化脚本中很有用)
sfdx force:org:delete -u FeatureBranchOrg -p

注释:

这些命令共同构成了一个完整且可重复的开发流程。将这些命令脚本化是实现持续集成和持续交付 (CI/CD) 的基础。


注意事项

虽然 Scratch Orgs 非常强大,但在使用时也需要注意一些限制和关键点。

・Dev Hub 和 Scratch Org 的限制: 你的 Salesforce 版本决定了可用的 Dev Hub 功能以及 Scratch Org 的数量限制。例如,企业版每天可以创建 50 个 Scratch Org,最多同时激活 100 个。在使用前,请务必在 Salesforce 官方文档中查询你的版本对应的具体限制,以避免达到上限。

・并非所有功能都可配置: 虽然定义文件可以控制很多特性和设置,但并非所有 Salesforce 功能都可以通过它来启用。某些功能可能需要手动在 Scratch Org 中开启,或者根本不支持在 Scratch Org 中使用。在项目开始前,请务必验证你的核心依赖功能是否受支持。

・源码跟踪 (Source Tracking): `force:source:push` 和 `force:source:pull` 命令依赖于源码跟踪来同步本地和远端 Scratch Org 的变更。这个机制非常高效,但有时可能会出现冲突。开发人员需要理解其工作原理,并在发生冲突时知道如何解决。例如,使用 `sfdx force:source:status` 命令来查看本地与远端的差异。

・数据管理策略: Scratch Orgs 默认是空的,不包含任何业务数据。你需要制定一套有效的数据策略。`sfdx force:data:tree:import/export` 是一个强大的工具,可以处理有主从关系的数据,但对于复杂的数据模型,可能需要编写 Apex 脚本或使用更专业的数据加载工具来生成测试数据。

・凭证和敏感信息管理: 绝对不要将任何密码、API 密钥等敏感信息硬编码在你的元数据中并提交到版本控制系统。应该使用命名凭证 (Named Credentials) 来处理集成的端点和认证,并结合使用自定义元数据类型或环境变量在 CI/CD 流程中动态注入机密信息。

・权限模型: 在 SFDX 项目中,最佳实践是使用权限集 (Permission Sets)权限集组 (Permission Set Groups) 来管理用户权限,而不是简档 (Profiles)。因为权限集更容易在不同环境中进行部署和版本控制,而简档中包含了太多与环境相关的设置(如 IP 范围),不适合在源码中管理。


总结与最佳实践

Scratch Orgs 是 Salesforce 平台开发的游戏规则改变者。它们通过提供临时的、可预测的、源驱动的环境,使开发人员能够专注于构建高质量的应用,而不是浪费时间在环境配置和冲突解决上。它们是实现真正 DevOps 文化和 CI/CD 流程的基石。

作为一名 Salesforce 开发人员,我总结了以下几条最佳实践:

1. 拥抱版本控制作为唯一真相来源 (Source of Truth): 你的 Git 仓库应该是你所有元数据和配置的权威来源。Scratch Org 只是一个临时的、一次性的工作台。永远不要依赖一个 Scratch Org 来保存你的工作。

2. 自动化你的环境搭建: 将创建 Scratch Org、推送元数据、分配权限、导入数据的完整流程编写成一个脚本。这不仅可以节省你的时间,更能保证每个开发人员和 CI/CD 服务器使用的都是完全一致的环境。

3. 保持定义文件最小化: 只在你的 `project-scratch-def.json` 文件中包含当前功能开发所必需的特性和设置。一个轻量级的 Scratch Org 创建速度更快,也能让你更清楚地了解功能的依赖。

4. 制定清晰的别名命名规范: 为你的 Scratch Org 别名制定一套规范,例如 `[story_number]-[feature_name]-[initials]`。这能帮助你和你的团队在 Dev Hub 中快速识别每个 Org 的用途。

5. 及时清理不再使用的 Scratch Orgs: 虽然它们会自动过期,但主动删除不再需要的 Scratch Org 是一个好习惯。这有助于保持你的 Dev Hub 干净,并确保团队不会意外地达到激活数量的上限。

6. 深入理解 SFDX 项目结构: 熟悉标准的 SFDX 项目结构(`force-app/main/default/...`),并学习如何组织你的代码和元数据。这对于团队协作和可维护性至关重要。

总而言之,熟练掌握 Scratch Orgs 的使用是每一位现代 Salesforce 开发人员的必备技能。它不仅仅是一个工具,更是一种推动开发流程现代化、提升团队协作效率和保障交付质量的思维方式。

评论

此博客中的热门博文

Salesforce 登录取证:深入解析用户访问监控与安全

Salesforce Experience Cloud 技术深度解析:构建社区站点 (Community Sites)

Salesforce Einstein AI 编程实践:开发者视角下的智能预测