关于 salesforce-component-standards
面向 Salesforce 开发者的组件质量标准技能,涵盖 LWC、Aura 和 Visualforce。它提供数据访问、安全、无障碍、性能及测试方面的检查要点,适用于编写和审查组件。
主要功能
- 01LWC 数据访问与安全规范
- 02SLDS 2 样式与无障碍要求
- 03组件通信与性能准则
- 04Jest 测试要求
- 05Aura 与 Visualforce 安全检查
适用场景
- 01编写或审查 LWC 组件
- 02检查 Aura 组件迁移方案
- 03审查 Visualforce 页面安全性
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ github/ awesome-copilot --skill salesforce-component-standards安装后在 Claude Code 中输入/salesforce-component-standards确认已加载。
详细介绍
Salesforce 组件质量标准
对你编写或审查的每个 LWC、Aura 组件和 Visualforce 页面应用这些检查。
第 1 节 — LWC 质量标准
1.1 数据访问模式选择
在编写 JavaScript 控制器代码之前,选择正确的数据访问模式:
| 用例 | 模式 | 原因 |
|---|---|---|
| 响应式读取单条记录(跟随导航) | @wire(getRecord, { recordId, fields }) | Lightning Data Service — 已缓存、响应式 |
| 单个对象的标准 CRUD 表单 | <lightning-record-form> 或 <lightning-record-edit-form> | 内置 FLS、CRUD 和无障碍支持 |
| 复杂的服务端查询或筛选列表 | 在 cacheable=true 方法上使用 @wire(apexMethodName, { param }) | 允许缓存;参数变化时 wire 会重新触发 |
| 用户触发的操作、DML 或不可缓存的服务端调用 | 命令式 apexMethodName(params).then(...).catch(...) | DML 必须如此 — 没有 cacheable=true 时,wired 方法不能是 @AuraEnabled |
| 跨组件通信(无共享父组件) | Lightning Message Service (LMS) | 解耦,可跨 DOM 边界工作 |
| 多对象图关系 | GraphQL @wire(gql, { query, variables }) | 复杂关联数据只需一次往返 |
1.2 安全规则
| 规则 | 执行方式 |
|---|---|
innerHTML 中不得包含原始用户数据 | 在模板中使用 {expression} 绑定 — 框架会自动转义。切勿使用 this.template.querySelector('.el').innerHTML = userValue |
Apex @AuraEnabled 方法强制实施 CRUD/FLS | 在 SOQL 中使用 WITH USER_MODE 或显式的 Schema.sObjectType 检查 |
| 组件 JavaScript 中不得硬编码特定组织的 ID | 通过查询获取或作为 prop 传入 — 切勿在源码中嵌入记录 ID |
来自父组件的 @api 属性:使用前先验证 | 父组件可以传入任何内容 — 在用作查询参数前验证类型和范围 |
1.3 SLDS 2 和样式标准
- 切勿硬编码颜色:
color: #FF3366→ 使用color: var(--slds-c-button-brand-color-background)或语义化 SLDS token。 - 切勿使用
!important覆盖 SLDS 类 — 通过自定义 CSS 属性进行组合。 - 凡是存在
<lightning-*>基础组件的地方就使用它们:lightning-button、lightning-input、lightning-datatable、lightning-card等。 - 基础组件内置 SLDS 2、深色模式和无障碍支持 — 避免重新实现它们的行为。
- 如果使用自定义 CSS,在宣布完成前需在浅色模式和深色模式下都进行测试。
1.4 无障碍要求(WCAG 2.1 AA)
每个 LWC 组件在视为完成之前必须通过以下所有检查:
- 所有表单输入都有
<label>或aria-label— 切勿将 placeholder 作为唯一的标签 - 所有纯图标按钮都有
alternative-text或描述操作的aria-label - 所有交互元素都可通过键盘到达和操作(Tab、Enter、Space、Escape)
- 颜色不是传达状态的唯一方式 — 需配合文本、图标或
aria-*属性 - 错误消息通过
aria-describedby与其输入关联 - 模态框中的焦点管理正确 — 打开时焦点移入模态框,关闭时移回
1.5 组件通信规则
| 方向 | 机制 |
|---|---|
| 父 → 子 | @api 属性或调用 @api 方法 |
| 子 → 父 | CustomEvent — this.dispatchEvent(new CustomEvent('eventname', { detail: data })) |
| 兄弟 / 不相关组件 | Lightning Message Service (LMS) |
| 切勿使用 | document.querySelector、window.* 或 Pub/Sub 库 |
对于 Flow 屏幕组件:
- 需要到达 Flow 运行时的事件必须设置
bubbles: true和composed: true。 - 暴露
@api value以与 Flow 变量进行双向绑定。
1.6 JavaScript 性能规则
connectedCallback中不要有副作用:它会在每次 DOM 挂载时运行 —— 避免在此处进行 DML、重计算或渲染状态变更。- 为
renderedCallback加守卫:始终使用布尔守卫防止无限渲染循环。 - 避免响应式属性陷阱:在
renderedCallback中设置响应式属性会导致重新渲染 —— 仅在必要时使用并加上守卫。 - 不要在组件状态中存储大型数据集 —— 应改为分页或流式处理大型结果。
1.7 Jest 测试要求
每个处理用户交互或获取 Apex 数据的组件都必须有 Jest 测试:
// Minimum test coverage expectations
it('renders the component with correct title', async () => { ... });
it('calls apex method and displays results', async () => { ... }); // Wire mock
it('dispatches event when button is clicked', async () => { ... });
it('shows error state when apex call fails', async () => { ... }); // Error path
使用 @salesforce/sfdx-lwc-jest 模拟工具:
wire适配器模拟:setImmediate+emit({ data, error })- Apex 方法模拟:
jest.mock('@salesforce/apex/MyClass.myMethod', ...)
第 2 节 —— Aura 组件标准
2.1 何时使用 Aura 还是 LWC
- 新组件:始终使用 LWC,除非目标上下文仅支持 Aura(例如扩展
force:appPage、在旧版托管包中使用 Aura 专属事件)。 - 将 Aura 迁移到 LWC:优先使用 LWC,逐组件迁移;LWC 可以嵌入 Aura 组件内部。
2.2 Aura 安全规则
@AuraEnabled控制器方法必须声明with sharing并强制执行 CRUD/FLS —— Aura 不会自动强制执行这些规则。- 不要在
<div>非绑定辅助函数中使用{!v.something}搭配未转义的用户数据 —— 使用<ui:outputText value="{!v.text}" />或<c:something>进行转义。 - 在将组件属性中的所有输入用于 SOQL / Apex 逻辑之前,必须先进行校验。
2.3 Aura 事件设计
- 组件事件用于父子通信 —— 作用域最小。
- 应用事件仅在组件事件无法到达目标时使用 —— 它们会向整个应用广播,可能带来性能和维护问题。
- 对于 LWC + Aura 混合技术栈:使用 Lightning Message Service 解耦通信 —— 不要依赖 Aura 应用事件到达 LWC 组件。
第 3 节 —— Visualforce 安全标准
3.1 XSS 防护
<apex:outputText value="{!userInput}" escape="false" />
<apex:outputText value="{!userInput}" />
规则:escape="false" 绝不能用于用户可控的数据。如果必须渲染富文本,请在输出前使用白名单在服务端进行净化。
3.2 CSRF 防护
对所有回发操作使用 <apex:form> —— 平台会自动向表单注入 CSRF 令牌。不要使用原生 <form method="POST"> HTML 元素,它们会绕过 CSRF 防护。
3.3 控制器中的 SOQL 注入防护
// ❌ NEVER
String soql = 'SELECT Id FROM Account WHERE Name = \'' + ApexPages.currentPage().getParameters().get('name') + '\'';
List<Account> results = Database.query(soql);
// ✅ ALWAYS — bind variable
String nameParam = ApexPages.currentPage().getParameters().get('name');
List<Account> results = [SELECT Id FROM Account WHERE Name = :nameParam];
3.4 视图状态管理检查清单
- 视图状态低于 135 KB(在浏览器开发者工具或 Salesforce 视图状态选项卡中检查)
- 仅用于服务端计算的字段声明为
transient - 大型集合不会在回发之间不必要地持久化
- 只读页面在
<apex:page>上设置了readonly="true"以跳过视图状态序列化
3.5 Visualforce 控制器中的 FLS / CRUD
// Before reading a field
if (!Schema.sObjectType.Account.fields.Revenue__c.isAccessible()) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'You do not have access to this field.'));
return null;
}
// Before performing DML
if (!Schema.sObjectType.Account.isDeletable()) {
throw new System.NoAccessException();
}
标准控制器会自动为绑定字段强制执行 FLS。自定义控制器不会 —— 必须手动强制执行 FLS。
快速参考 — 组件反模式摘要
| 反模式 | 技术 | 风险 | 修复 |
|---|---|---|---|
将用户数据用于 innerHTML | LWC | XSS | 使用模板绑定 {expression} |
| 硬编码十六进制颜色 | LWC/Aura | 深色模式 / SLDS 2 失效 | 使用 SLDS CSS 自定义属性 |
图标按钮缺少 aria-label | LWC/Aura/VF | 无障碍访问失败 | 添加 alternative-text 或 aria-label |
renderedCallback 中没有防护 | LWC | 无限重新渲染循环 | 添加 hasRendered 布尔防护 |
| 用应用事件处理父子通信 | Aura | 不必要的广播范围 | 改用组件事件 |
对用户数据使用 escape="false" | Visualforce | XSS | 移除 — 使用默认转义 |
原始 <form> 回发 | Visualforce | CSRF 漏洞 | 使用 <apex:form> |
自定义控制器上没有 with sharing | VF / Apex | 数据泄露 | 添加 with sharing 声明 |
| 自定义控制器中未检查 FLS | VF / Apex | 权限提升 | 添加 Schema.sObjectType 检查 |
| 将 URL 参数拼接到 SOQL 中 | VF / Apex | SOQL 注入 | 使用绑定变量 |
评论
支持 Markdown