salesforce-component-standards
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSalesforce Component Quality Standards
Salesforce组件质量标准
Apply these checks to every LWC, Aura component, and Visualforce page you write or review.
请将以下检查项应用于你编写或审核的每一个LWC、Aura组件和Visualforce页面。
Section 1 — LWC Quality Standards
第1节 — LWC质量标准
1.1 Data Access Pattern Selection
1.1 数据访问模式选择
Choose the right data access pattern before writing JavaScript controller code:
| Use case | Pattern | Why |
|---|---|---|
| Read a single record reactively (follows navigation) | | Lightning Data Service — cached, reactive |
| Standard CRUD form for a single object | | Built-in FLS, CRUD, and accessibility |
| Complex server query or filtered list | | Allows caching; wire re-fires on param change |
| User-triggered action, DML, or non-cacheable server call | Imperative | Required for DML — wired methods cannot be |
| Cross-component communication (no shared parent) | Lightning Message Service (LMS) | Decoupled, works across DOM boundaries |
| Multi-object graph relationships | GraphQL | Single round-trip for complex related data |
在编写JavaScript控制器代码前选择合适的数据访问模式:
| 用例 | 模式 | 原因 |
|---|---|---|
| 响应式读取单条记录(跟随导航) | | Lightning Data Service — 已缓存、响应式 |
| 单对象的标准CRUD表单 | | 内置FLS、CRUD和可访问性支持 |
| 复杂服务端查询或过滤列表 | 在 | 支持缓存;参数变化时wire会自动重新触发 |
| 用户触发的操作、DML或不可缓存的服务端调用 | 命令式调用 | DML必须使用该方式 — 没有设置 |
| 无共享父组件的跨组件通信 | Lightning Message Service (LMS) | 解耦,可跨DOM边界工作 |
| 多对象图关系 | GraphQL | 复杂关联数据仅需一次往返请求 |
1.2 Security Rules
1.2 安全规则
| Rule | Enforcement |
|---|---|
No raw user data in | Use |
Apex | Use |
| No hardcoded org-specific IDs in component JavaScript | Query or pass as a prop — never embed record IDs in source |
| A parent can pass anything — validate type and range before using as a query parameter |
| 规则 | 实施方式 |
|---|---|
不可在 | 在模板中使用 |
Apex | 在SOQL中使用 |
| 组件JavaScript中不可硬编码特定组织的ID | 通过查询获取或作为属性传入 — 绝对不要在源码中嵌入记录ID |
来自父组件的 | 父组件可能传入任意值 — 在作为查询参数使用前需校验类型和取值范围 |
1.3 SLDS 2 and Styling Standards
1.3 SLDS 2与样式标准
- Never hardcode colours: → use
color: #FF3366or a semantic SLDS token.color: var(--slds-c-button-brand-color-background) - Never override SLDS classes with — compose with custom CSS properties.
!important - Use base components wherever they exist:
<lightning-*>,lightning-button,lightning-input,lightning-datatable, etc.lightning-card - Base components include built-in SLDS 2, dark mode, and accessibility — avoid reimplementing their behaviour.
- If using custom CSS, test in both light mode and dark mode before declaring done.
- 绝对不要硬编码颜色:→ 改用
color: #FF3366或语义化SLDS令牌。color: var(--slds-c-button-brand-color-background) - 绝对不要用覆盖SLDS类 — 通过自定义CSS属性组合实现。
!important - 只要存在对应的基础组件就优先使用:
<lightning-*>、lightning-button、lightning-input、lightning-datatable等。lightning-card - 基础组件内置SLDS 2、暗黑模式和可访问性支持 — 不要重复实现其功能。
- 如果使用自定义CSS,交付前请同时在亮色模式和暗黑模式下测试。
1.4 Accessibility Requirements (WCAG 2.1 AA)
1.4 可访问性要求(WCAG 2.1 AA)
Every LWC component must pass all of these before it is considered done:
- All form inputs have or
<label>— never use placeholder as the only labelaria-label - All icon-only buttons have or
alternative-textdescribing the actionaria-label - All interactive elements are reachable and operable by keyboard (Tab, Enter, Space, Escape)
- Colour is not the only means of conveying status — pair with text, icon, or attributes
aria-* - Error messages are associated with their input via
aria-describedby - Focus management is correct in modals — focus moves into the modal on open and back on close
每个LWC组件必须满足以下所有要求才可视为开发完成:
- 所有表单输入都有或
<label>— 绝对不要仅用placeholder作为唯一标签aria-label - 所有仅显示图标的按钮都有或
alternative-text描述其操作aria-label - 所有可交互元素都可通过键盘访问和操作(Tab、Enter、Space、Escape)
- 颜色不是传递状态的唯一方式 — 需搭配文本、图标或属性
aria-* - 错误信息通过与对应的输入项关联
aria-describedby - 弹窗的焦点管理正确 — 弹窗打开时焦点移入,关闭时焦点回到原位置
1.5 Component Communication Rules
1.5 组件通信规则
| Direction | Mechanism |
|---|---|
| Parent → Child | |
| Child → Parent | |
| Sibling / unrelated components | Lightning Message Service (LMS) |
| Never use | |
For Flow screen components:
- Events that need to reach the Flow runtime must set and
bubbles: true.composed: true - Expose for two-way binding with the Flow variable.
@api value
| 通信方向 | 机制 |
|---|---|
| 父 → 子 | |
| 子 → 父 | |
| 兄弟/无关联组件 | Lightning Message Service (LMS) |
| 禁止使用 | |
针对Flow屏幕组件:
- 需要传递到Flow运行时的事件必须设置和
bubbles: true。composed: true - 暴露用于和Flow变量实现双向绑定。
@api value
1.6 JavaScript Performance Rules
1.6 JavaScript性能规则
- No side effects in : it runs on every DOM attach — avoid DML, heavy computation, or rendering state mutations here.
connectedCallback - Guard : always use a boolean guard to prevent infinite render loops.
renderedCallback - Avoid reactive property traps: setting a reactive property inside causes a re-render — use it only when necessary and guarded.
renderedCallback - Do not store large datasets in component state — paginate or stream large results instead.
- 中不要写副作用逻辑:它会在每次DOM挂载时运行 — 避免在此处执行DML、 heavy computation或渲染状态变更。
connectedCallback - 需添加守卫:始终使用布尔值守卫避免无限渲染循环。
renderedCallback - 避免响应式属性陷阱:在中设置响应式属性会触发重渲染 — 仅在必要时使用且必须添加守卫。
renderedCallback - 不要在组件状态中存储大型数据集 — 改用分页或流式返回大型结果。
1.7 Jest Test Requirements
1.7 Jest测试要求
Every component that handles user interaction or retrieves Apex data must have a Jest test:
javascript
// 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 pathUse mocking utilities:
@salesforce/sfdx-lwc-jest- adapter mocking:
wire+setImmediateemit({ data, error }) - Apex method mocking:
jest.mock('@salesforce/apex/MyClass.myMethod', ...)
每个处理用户交互或拉取Apex数据的组件都必须编写Jest测试:
javascript
// 最低测试覆盖率要求
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+setImmediateemit({ data, error }) - Apex方法模拟:
jest.mock('@salesforce/apex/MyClass.myMethod', ...)
Section 2 — Aura Component Standards
第2节 — Aura组件标准
2.1 When to Use Aura vs LWC
2.1 何时使用Aura vs LWC
- New components: always LWC unless the target context is Aura-only (e.g. extending , using Aura-specific events in a legacy managed package).
force:appPage - Migrating Aura to LWC: prefer LWC, migrate component-by-component; LWC can be embedded inside Aura components.
- 新组件优先选择LWC,除非目标运行上下文仅支持Aura(例如扩展、在旧托管包中使用Aura专属事件)。
force:appPage - 将Aura迁移到LWC:优先使用LWC,按组件逐步迁移;LWC可以嵌入到Aura组件中。
2.2 Aura Security Rules
2.2 Aura安全规则
- controller methods must declare
@AuraEnabledand enforce CRUD/FLS — Aura does not enforce them automatically.with sharing - Never use with unescaped user data in
{!v.something}unbound helpers — use<div>or<ui:outputText value="{!v.text}" />to escape.<c:something> - Validate all inputs from component attributes before using them in SOQL / Apex logic.
- 控制器方法必须声明
@AuraEnabled并强制校验CRUD/FLS — Aura不会自动执行这些校验。with sharing - 不要在非绑定辅助工具中使用包含未转义用户数据的
<div>— 使用{!v.something}或<ui:outputText value="{!v.text}" />进行转义。<c:something> - 在SOQL/Apex逻辑中使用组件属性的输入值前必须先校验。
2.3 Aura Event Design
2.3 Aura事件设计
- Component events for parent-child communication — lowest scope.
- Application events only when component events cannot reach the target — they broadcast to the entire app and can be a performance and maintenance problem.
- For hybrid LWC + Aura stacks: use Lightning Message Service to decouple communication — do not rely on Aura application events reaching LWC components.
- 父子通信用组件事件 — 作用域最小。
- 仅当组件事件无法触达目标时才使用应用事件 — 应用事件会向整个应用广播,可能引发性能和维护问题。
- 针对LWC + Aura混合栈:使用Lightning Message Service解耦通信 — 不要依赖Aura应用事件触达LWC组件。
Section 3 — Visualforce Security Standards
第3节 — Visualforce安全标准
3.1 XSS Prevention
3.1 XSS防护
xml
<!-- ❌ NEVER — renders raw user input as HTML -->
<apex:outputText value="{!userInput}" escape="false" />
<!-- ✅ ALWAYS — auto-escaping on -->
<apex:outputText value="{!userInput}" />
<!-- Default escape="true" — platform HTML-encodes the output -->Rule: is never acceptable for user-controlled data. If rich text must be rendered, sanitise server-side with a whitelist before output.
escape="false"xml
<!-- ❌ 禁止 — 将原始用户输入渲染为HTML -->
<apex:outputText value="{!userInput}" escape="false" />
<!-- ✅ 推荐 — 开启自动转义 -->
<apex:outputText value="{!userInput}" />
<!-- 默认escape="true" — 平台会对输出进行HTML编码 -->规则:用户可控数据绝对不允许设置。如果必须渲染富文本,输出前需在服务端使用白名单进行清理。
escape="false"3.2 CSRF Protection
3.2 CSRF防护
Use for all postback actions — the platform injects a CSRF token automatically into the form. Do not use raw HTML elements, which bypass CSRF protection.
<apex:form><form method="POST">所有回发操作都使用 — 平台会自动向表单中注入CSRF令牌。不要使用原生HTML元素,这类元素会绕过CSRF防护。
<apex:form><form method="POST">3.3 SOQL Injection Prevention in Controllers
3.3 控制器中SOQL注入防护
apex
// ❌ 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];apex
// ❌ 禁止
String soql = 'SELECT Id FROM Account WHERE Name = \\'' + ApexPages.currentPage().getParameters().get('name') + '\\'';
List<Account> results = Database.query(soql);
// ✅ 推荐 — 绑定变量
String nameParam = ApexPages.currentPage().getParameters().get('name');
List<Account> results = [SELECT Id FROM Account WHERE Name = :nameParam];3.4 View State Management Checklist
3.4 视图状态管理检查清单
- View state is under 135 KB (check in browser developer tools or the Salesforce View State tab)
- Fields used only for server-side calculations are declared
transient - Large collections are not persisted across postbacks unnecessarily
- is set on
readonly="true"for read-only pages to skip view-state serialisation<apex:page>
- 视图状态小于135 KB(可在浏览器开发者工具或Salesforce视图状态标签页中检查)
- 仅用于服务端计算的字段声明为
transient - 大型集合不会不必要地在回发间持久化
- 只读页面的设置
<apex:page>以跳过视图状态序列化readonly="true"
3.5 FLS / CRUD in Visualforce Controllers
3.5 Visualforce控制器中的FLS/CRUD校验
apex
// 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();
}Standard controllers enforce FLS for bound fields automatically. Custom controllers do not — FLS must be enforced manually.
apex
// 读取字段前
if (!Schema.sObjectType.Account.fields.Revenue__c.isAccessible()) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, '你没有权限访问该字段。'));
return null;
}
// 执行DML前
if (!Schema.sObjectType.Account.isDeletable()) {
throw new System.NoAccessException();
}标准控制器会自动为绑定字段执行FLS校验,自定义控制器不会 — 必须手动强制校验FLS。
Quick Reference — Component Anti-Patterns Summary
快速参考 — 组件反模式汇总
| Anti-pattern | Technology | Risk | Fix |
|---|---|---|---|
| LWC | XSS | Use template bindings |
| Hardcoded hex colours | LWC/Aura | Dark-mode / SLDS 2 break | Use SLDS CSS custom properties |
Missing | LWC/Aura/VF | Accessibility failure | Add |
No guard in | LWC | Infinite rerender loop | Add |
| Application event for parent-child | Aura | Unnecessary broadcast scope | Use component event instead |
| Visualforce | XSS | Remove — use default escaping |
Raw | Visualforce | CSRF vulnerability | Use |
No | VF / Apex | Data exposure | Add |
| FLS not checked in custom controller | VF / Apex | Privilege escalation | Add |
| SOQL concatenated with URL param | VF / Apex | SOQL injection | Use bind variables |
| 反模式 | 技术栈 | 风险 | 修复方案 |
|---|---|---|---|
对用户数据使用 | LWC | XSS | 使用模板绑定 |
| 硬编码十六进制颜色 | LWC/Aura | 暗黑模式/SLDS 2样式异常 | 使用SLDS CSS自定义属性 |
图标按钮缺失 | LWC/Aura/VF | 可访问性不达标 | 添加 |
| LWC | 无限重渲染循环 | 添加 |
| 父子通信用应用事件 | Aura | 不必要的广播作用域 | 改用组件事件 |
对用户数据设置 | Visualforce | XSS | 移除该配置,使用默认转义 |
原生 | Visualforce | CSRF漏洞 | 使用 |
自定义控制器未添加 | VF/Apex | 数据泄露 | 添加 |
| 自定义控制器未校验FLS | VF/Apex | 权限提升 | 添加 |
| SOQL与URL参数直接拼接 | VF/Apex | SOQL注入 | 使用绑定变量 |
| ", |