关于 experience-lds-best-practices-apply
此技能指导 Lightning Web Component 遵循 Lightning Data Service 最佳实践,适用于审查或实现 Salesforce 数据操作。重点涵盖 UI API、缓存一致性和 schema 引用,并提供检查与修复流程。
主要功能
- 01审查 LDS 数据层合规性
- 02优先使用 LDS/UI API 处理 CRUD
- 03用 schema 导入替代硬编码名称
- 04确保变更后数据缓存刷新
- 05指导 Apex 与 LDS 的取舍
适用场景
- 01审查组件中的手写表单和 Apex 使用
- 02实现标准对象或自定义对象的 CRUD
- 03修复记录变更后的过期数据显示
- 04为字段和对象添加 schema 导入
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill experience-lds-best-practices-apply安装后在 Claude Code 中输入/experience-lds-best-practices-apply确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/adapter-apis.mdlds-data-consistency.mdlds-expert.mdlds-referential-integrity.mdwire-adapter-types.md详细介绍
应用 LDS 最佳实践
将 Lightning Data Service 指南应用于 Lightning Web Component。三大支柱:数据一致性、引用完整性和 UIAPI 与 Apex。聚焦 UI API 路径——GraphQL 和上游数据需求分析在此流程之外处理。
适用场景
- 检查组件的数据层是否符合 LDS 规范(手工构建的表单、以字符串表示的字段名、Apex 与 LDS 不同步、过度使用 Apex)。
- 为标准对象或自定义对象实现 CRUD。
- 在
getRecord、getRecords、createRecord、updateRecord、deleteRecord、基础记录表单组件或 Apex 之间进行选择。 - 修复记录变更后的数据过期问题。
- 添加架构导入(
@salesforce/schema/...),以替换硬编码的字段名或对象名。
请勿在以下场景使用此技能:
- 生成 GraphQL 查询/变更——目前在此流程之外处理。
- 上游数据需求发现——目前在此流程之外处理。
- SLDS 类/设计令牌相关工作(请使用
design-systems-slds-apply)。 - 无障碍、安全或 RTL 审查——这些是独立的审查环节,使用各自的工具运行。
前提条件
- 组件路径。
- 了解组件的数据操作(读取/写入/两者皆有),以及是否已涉及 Apex。
- 可访问组织架构以导入
@salesforce/schema(Setup → Object Manager →<Object>→ Details → API Name;或者在 GraphQL 负责读取时,使用从目标组织获取的 SDL)。
知识库
- references/lds-expert.md — 权威 LDS 知识(模式、适配器、缓存、变更流程)。
- references/lds-data-consistency.md — 缓存失效、
refreshApex、notifyRecordUpdateAvailable、wire 结果传播。 - references/lds-referential-integrity.md —
@salesforce/schema导入、字段常量、对象名解析,以及这些内容在重构中的传播。
按适配器分类的 API 参考 — references/adapter-apis.md 包含每个 UI API 适配器的语法/参数/返回值/用法,并按系列分组(uiRecordApis、uiListsApis、uiRelatedListApis、uiObjectInfoApis)。每个适配器都有一个 # `<name>` 区块;搜索反引号括起的名称(例如 # `getRecord`)即可跳转到对应条目。连接适配器前请先阅读此文档;不要凭记忆转述。
类型目录 — references/wire-adapter-types.md 收录适配器返回的所有类型(Record、ObjectInfo、FieldValue 等),按类别分组,并使用旧版 MCP 工具所用的同一格式渲染。搜索 ## <TypeName> 即可跳转到具体条目。
编辑代码前,请阅读适用的参考资料。
核心原则
- 对标准对象和自定义对象执行 CRUD 时,优先使用 LDS/UIAPI。只有当业务逻辑或批量操作超出 LDS 能力范围时,才使用 Apex。
- 每次变更后,始终使用
refreshApex(wiredResult)或notifyRecordUpdateAvailable([{ recordId }])保持渲染数据最新。 - 从
@salesforce/schema导入对象和字段引用,而非使用字符串字面量。这可以保护组件免受元数据重命名的影响。 - 对于单记录 UI,优先使用基础记录表单组件(
lightning-record-form、lightning-record-edit-form、lightning-record-view-form)。这些组件内置验证、SLDS 样式、无障碍支持和字段级安全。
审查清单
对每项回答 是/否。任何一项回答 是,都需要重构。
1. 手工构建表单,而非使用基础组件
- 组件是否为单记录 CRUD 实现了自定义表单,而
lightning-record-form、lightning-record-edit-form或lightning-record-view-form已足以满足需求? - 验证逻辑是否重复实现了基础记录表单组件原生提供的功能?
- 是否手动重建了标准 SLDS 样式,而未使用基础组件内置的样式?
2. 未导入引用
- 是否将对象或字段 API 名称作为硬编码字符串引用?
- 在模板中,是否通过
record.data.fields.Name.value之类的表达式直接访问字段值,而未导入架构? - JS 文件是否未导入任何
@salesforce/schema,但仍与 Salesforce 字段交互?
3. 混用 Apex 和 LDS,但未进行同步
- 组件是否通过 LDS 读取记录,又通过 Apex 修改同一记录,却未在之后刷新缓存?
- 组件是否通过 Apex 获取数据,却依赖 LDS 缓存进行显示,并且在更新后未进行同步?
- 是否有多个数据源访问同一对象,却没有明确的刷新策略?
4. 过度使用 Apex
- 组件是否仅调用 Apex 来检索或更新单条记录,而
getRecord、updateRecord或基础记录表单即可完成此操作? - 是否使用 Apex 运行简单的 SOQL 查询,而这些查询所需的字段可通过标准 LDS wire 适配器获取?
- 是否为基本 CRUD 编写了自定义 Apex 方法,而代码中没有出现 LDS/UIAPI 调用?
工作流
步骤 1 — 清查数据层
列出组件中的每项数据操作:
- Wire 适配器(
@wire(getRecord, …)、@wire(getRecords, …)、@wire(someApexMethod, …))。 - 命令式调用(
updateRecord、createRecord、deleteRecord、Apex 命令式调用)。 - 读取与写入、目标对象、字段,以及写入后的刷新路径是否通过 wire 实现。
步骤 2 — 执行四部分检查清单
按顺序检查 §1–§4。针对每个部分,判断其是否适用于正在审核的组件,并在报告中记录结果。使用以下格式:每个部分都必须且只能出现一次,作为 ## LDS Best Practices 下的问题(违规项),或作为 ## Sections checked (no issue) 下的合规条目。最后添加一个列出数量的 ## Summary 行和一段概述。
报告格式:
## LDS Best Practices
- §<N> <section title> — <file>:<lines>
Issue: <what is wrong, specifically citing the pattern in the code>
Fix: <the corrective change, naming the exact import / API to use>
Applied: <yes | no>
## Sections checked (no issue)
- §<N> <section title> — <file>:<lines>
Status: Compliant (no action).
Evidence: <what in the code makes this section compliant — cite lines, imports, and the base component or schema token being used>
## Summary
- <X> issue(s) found; <Y> fixed; <Z> deferred.
- <one-paragraph narrative of the review — what the component does, why the flagged issues matter, and why the compliant sections are compliant.>
生成此报告的规则:
- §1–§4 中的每个部分都必须且只能出现在两个区块之一。即使某部分符合要求,也不得省略;请在
## Sections checked (no issue)下附上证据。 - 在
## LDS Best Practices下仅列出实际违规项。如果没有违规项,请将 "No best-practice issues found." 作为首行,然后将所有部分移至合规区块。 - 引用正在审核的组件中的具体文件路径和行号范围,不得使用泛指。
- 不要添加 §1–§4 之外的其他部分;后续的 a11y / RTL / 安全审核会作为独立工作流运行,并使用各自的报告。
步骤 3 — 应用引用完整性修复
对于每个硬编码的 API 名称:
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import NAME_FIELD from '@salesforce/schema/Account.Name';
import INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';
在对象或字段的所有引用位置使用这些常量 — wire 配置、@wire 字段数组、getFieldValue(record, NAME_FIELD) 调用,以及基础组件的 object-api-name / fields 属性。
完整规则:references/lds-referential-integrity.md。
步骤 4 — 应用数据一致性修复
- 在 命令式 LDS 修改(
updateRecord、createRecord、deleteRecord)后,触发刷新:import { updateRecord, getRecord } from 'lightning/uiRecordApi'; import { refreshApex } from '@salesforce/apex'; async handleSave() { await updateRecord({ fields: { Id: this.recordId, Name: this.name } }); await refreshApex(this.wiredRecord); } - 在 Apex 修改缓存中所持有的记录后,优先使用:
import { notifyRecordUpdateAvailable } from 'lightning/uiRecordApi'; await notifyRecordUpdateAvailable([{ recordId: this.recordId }]); - 保留 wire 结果的引用(
this.wiredRecord = result; return result.data;),以便refreshApex能够对其进行刷新。 - 基础表单组件会自行刷新;无需手动刷新。
完整规则:references/lds-data-consistency.md。
步骤 5 — 在适用时用 UIAPI 替换 Apex
- 单条记录读取 →
getRecord(使用fields和 schema 导入)。 - 单条记录更新 →
updateRecord或lightning-record-edit-form。 - 单条记录创建 →
createRecord或使用mode="edit"的lightning-record-form。 - 相关记录读取 →
getRelatedListRecords。 - 选项列表值 →
getPicklistValues。 - 对象元数据 →
getObjectInfo/getObjectInfos。
如果不确定适配器的结构,请在 references/adapter-apis.md 中搜索反引号括起的适配器名称(例如 # `getRecord`)——其中包含权威的参数、返回值和用法。对于 @salesforce/schema/<Object>.<Field> 路径,请在 Setup → Object Manager → <Object> → Details → API Name 中确认准确的 API 名称。对于不熟悉的返回类型,请在 references/wire-adapter-types.md 中搜索类型名称。
步骤 6 — 验证
- 组件文件中不再包含硬编码的 API 名称。
- 每条写入路径都有对应的刷新路径(或使用基础表单组件)。
- 不会通过 Apex 和 UIAPI 重复读取同一条记录。
- 现有 Jest 测试均通过;添加对刷新流程的覆盖(每次变更恰好调用一次
refreshApex)。
交叉引用
- 相关技能:
experience-lwc-generate— 当审查发现需要重新生成而不是修补组件时使用。design-systems-slds-apply— 用于清理 LDS 审查发现的 SLDS 类/设计令牌。
- 相邻工作(目前在此流程之外):
- GraphQL 查询/变更编写、上游数据需求分析,以及安全性/RTL/a11y 审查流程,均作为独立工作流运行,并使用各自的工具。
示例
优先使用基础组件
<template>
<lightning-record-form
record-id={recordId}
object-api-name="Account"
fields={fields}
mode="edit"
onsuccess={handleSuccess}>
</lightning-record-form>
</template>
import { LightningElement, api } from 'lwc';
import NAME_FIELD from '@salesforce/schema/Account.Name';
import INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';
export default class AccountEditor extends LightningElement {
@api recordId;
fields = [NAME_FIELD, INDUSTRY_FIELD];
handleSuccess() {
this.dispatchEvent(new CustomEvent('saved'));
}
}
使用命令式更新并刷新
import { LightningElement, api, wire } from 'lwc';
import { getRecord, updateRecord } from 'lightning/uiRecordApi';
import { refreshApex } from '@salesforce/apex';
import ACCOUNT_NAME from '@salesforce/schema/Account.Name';
export default class RenameAccount extends LightningElement {
@api recordId;
wiredRecord;
@wire(getRecord, { recordId: '$recordId', fields: [ACCOUNT_NAME] })
wired(result) {
this.wiredRecord = result;
}
async handleRename(event) {
await updateRecord({ fields: { Id: this.recordId, Name: event.detail } });
await refreshApex(this.wiredRecord);
}
}
验证
- 搜索
@salesforce/schema/导入——它们应覆盖组件引用的每个字段/对象。 - 搜索看起来像 API 名称的字符串字面量(
'Account'、'Name')——它们不应出现在 wire 配置或字段数组中。 - 追踪每个变更调用,确认其对应的刷新调用(
refreshApex、notifyRecordUpdateAvailable,或由基础表单在内部处理)。 - 确认仅在 UIAPI 无法满足需求时才使用 Apex(批量操作、复杂联接、自定义逻辑)。