salesforce-component-standards について
LWC、Aura、Visualforce を扱う Salesforce 開発者向けのコンポーネント品質基準スキルです。実装やレビューで使えるデータアクセス、セキュリティ、アクセシビリティ、性能、テストの確認項目をまとめています。
主な機能
- 01LWC のデータアクセスとセキュリティ規則
- 02SLDS 2 のスタイルとアクセシビリティ要件
- 03コンポーネント通信と性能の指針
- 04Jest のテスト要件
- 05Aura と Visualforce のセキュリティ確認
活用シーン
- 01LWC コンポーネントの実装やレビュー
- 02Aura コンポーネント移行案の確認
- 03Visualforce ページのセキュリティレビュー
インストール
コマンドをコピーしてターミナルで実行します。
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 には必須です — wire メソッドは cacheable=true なしでは @AuraEnabled にできません |
| コンポーネント間の通信(共通の親がない場合) | Lightning Message Service(LMS) | 疎結合で、DOM 境界を越えて動作します |
| 複数オブジェクトのグラフリレーションシップ | GraphQL @wire(gql, { query, variables }) | 複雑な関連データを 1 回のラウンドトリップで取得します |
1.2 セキュリティルール
| ルール | 適用方法 |
|---|---|
ユーザーデータを innerHTML に直接渡さない | テンプレートでは {expression} バインディングを使用してください — フレームワークが自動的にエスケープします。this.template.querySelector('.el').innerHTML = userValue は絶対に使用しないでください |
Apex の @AuraEnabled メソッドで CRUD/FLS を適用する | SOQL では WITH USER_MODE を使用するか、Schema.sObjectType で明示的にチェックしてください |
| コンポーネントの JavaScript に組織固有の ID をハードコードしない | クエリするかプロパティとして渡してください — レコード ID をソースに埋め込まないでください |
親から渡される @api プロパティは使用前に検証する | 親は任意の値を渡せます — クエリパラメーターとして使用する前に、型と範囲を検証してください |
1.3 SLDS 2 とスタイルの基準
- 色を絶対にハードコードしないでください:
color: #FF3366→color: var(--slds-c-button-brand-color-background)またはセマンティックな SLDS トークンを使用してください。 !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を設定してください。 - Flow 変数との双方向バインディングには
@api valueを公開してください。
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 の使い分け
- 新しいコンポーネントは、対象のコンテキストが Aura 専用の場合(例:
force:appPageの拡張、レガシーな管理パッケージでの Aura 固有イベントの使用)を除き、必ず LWC にしてください。 - 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 トークンを自動的に挿入します。CSRF 保護を回避してしまう、生の <form method="POST"> HTML 要素は使用しないでください。
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 の View State タブで確認してください)
- サーバー側の計算にのみ使用するフィールドが
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} を使用します |
| 16 進数カラーのハードコード | 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 インジェクション | バインド変数を使用します |