Salesforce開発環境構築メモ

## ツールのインストール
- [SalesforceCLI](https://developer.salesforce.com/ja/tools/sfdxcli)インストール
- [Visual Studio Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)インストール
- Salesforce公式のVisual Studio Codeの拡張機能インストール
    - [Salesforce Extension Pack (Expanded)](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-expanded)
- その他おすすめのVisual Studio Codeの拡張機能
    - [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)：タイポの疑いがある語を強調表示する。
    - [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens)：エラー・警告・ヒントをエディタ上に表示する
    - [Git Graph](https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph)：Gitツリーを表示
    - [GitLens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)：GitのGUIツール
    - [Salesforce Package.xml Generator](https://marketplace.visualstudio.com/items?itemName=VignaeshRamA.sfdx-package-xml-generator)：Package.xmlをGUIで作成する
    - [Remove Final Newlines](https://marketplace.visualstudio.com/items?itemName=DoCode.vscode-remove-final-newlines)：Prettierで強制的につくファイル末尾の空行を削除する[^1]
    - [Render Line Endings](https://marketplace.visualstudio.com/items?itemName=medo64.render-crlf):改行コードをエディタに表示。デフォルトと異なる改行コードの時、強調表示することも可能。
- [Git](https://git-scm.com/)インストール
- [npm](https://nodejs.org/ja/download/)インストール
- [JDKのインストールと設定](https://developer.salesforce.com/tools/vscode/ja/vscode-desktop/java-setup)：Salesforce Apex拡張機能のApex言語サーバの利用や、prettierのApexプラグインを使用するのに必要。

## SFDCのプロジェクトフォルダ作成
新しくプロジェクトフォルダを作成する場合は、ターミナルから下記コマンドを実行する。

```bash
cd プロジェクトフォルダを作成するパス
sf project generate -n プロジェクトフォルダ名 --manifest
```

## git
- プロジェクトフォルダで`git init`
- gitignoreに`.pmdCache`を追加
- 初回コミット`git commit -m コミットコメント`

※リモートリポジトリを新規に作成する場合は下記を実行。

- githubリポジトリ作成
- githubにプッシュする
    ```bash
    git add -A
    git commit -m "init"
    git remote add origin リモートリポジトリのURL
    git push -u origin main
    ```

## Visual Studio Code 設定
### 推奨の拡張機能を追加（チームで開発する場合）
`.vscode/extensions.json`に開発メンバー全員に導入してもらう拡張機能を設定する。

```json:推奨の拡張機能のサンプル
{
  "recommendations": [
    "salesforce.salesforcedx-vscode",
    "redhat.vscode-xml",
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "financialforce.lana",
    "salesforce.salesforcedx-vscode-expanded",
    "streetsidesoftware.code-spell-checker",
    "usernamehw.errorlens",
    "DoCode.vscode-remove-final-newlines",
    "medo64.render-crlf"
  ]
}
```

### ワークスペースの設定を追加
`.vscode/settings.json`に設定を追加。

```jsonc:ワークスペースの設定のサンプル
{
  "search.exclude": {
    "**/node_modules": true,
    "**/bower_components": true,
    "**/.sfdx": true
  },
  "js/ts.implicitProjectConfig.experimentalDecorators": true,

  // 静的解析（プロジェクトでapexPMDを使用するときは追加
  "apexPMD.runOnFileOpen": true,
  "apexPMD.runOnFileSave": true,
  "apexPMD.enableCache": true,
  "apexPMD.rulesets": ["path/to/rulesets.xml"],

  // フォーマッター
  "editor.formatOnSave": false,
  // Visualforceでprettierを使う場合は↓が必要
  "prettier.documentSelectors": ["**/pages/*.page", "**/components/*.component"],

  // 改行コード
  "code-eol.highlightNonDefault": true,

  // ファイル別設定（プロジェクトの開発規約にあわせて設定を行う）
  // "[apex]", "[html]", "[javascript]", "[json]", "[visualforce]"
  "[apex]": {
    "editor.detectIndentation": false,
    "editor.insertSpaces": true,
    "editor.tabSize": 4,
    "files.trimTrailingWhitespace": true,
    "files.trimFinalNewlines": true,
    "files.encoding": "utf8",
    "files.eol": "\n",
    // フォーマッターを使用する場合は下記も設定する
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  },
  "[html]": {
    "editor.detectIndentation": false,
    "editor.insertSpaces": true,
    "editor.tabSize": 2,
    "files.trimTrailingWhitespace": true,
    "files.trimFinalNewlines": true,
    "files.removeFinalNewlines": true,
    "files.encoding": "utf8",
    "files.eol": "\n",
    // フォーマッターを使用する場合は下記も設定する
    "editor.formatOnSave": true
  },
  "[javascript]": {
    "editor.detectIndentation": false,
    "editor.insertSpaces": true,
    "editor.tabSize": 4,
    "files.trimFinalNewlines": true,
    "files.removeFinalNewlines": true,
    "files.encoding": "utf8",
    "files.eol": "\n",
    // フォーマッターを使用する場合は下記も設定する
    "editor.formatOnSave": true
  },
  "[json]": {
    "editor.detectIndentation": false,
    "editor.insertSpaces": true,
    "editor.tabSize": 2
  },
  "[visualforce]": {
    "editor.detectIndentation": false,
    "editor.insertSpaces": true,
    "editor.tabSize": 2,
    "files.trimFinalNewlines": true,
    "files.removeFinalNewlines": true,
    "files.encoding": "utf8",
    "files.eol": "\n",
    // フォーマッターを使用する場合は下記も設定する
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  }
}
```

experimentalDecoratorsをtrueにすることで、 LWCのエラー「デコレーターの実験的なサポートは将来のリリースで変更になる可能性がある機能です。'tsconfig' または 'jsconfig' に 'experimentalDecorators' オプションを設定してこの警告を削除します。」を非表示にする。

## 開発ツールをインストール
### ツールのインストール
```bash
# package.jsonを基に開発に必要なツールをインストールする
npm install
```

### フォーマッターの設定
`.prettierrc`にapexのルールを追加する。

```json:フォーマッターの設定のサンプル
{
  "printWidth": 120,
  "trailingComma": "none",
  "plugins": ["prettier-plugin-apex", "@prettier/plugin-xml"],
  "overrides": [
    {
      "files": "**/lwc/**/*.html",
      "options": {
        "parser": "lwc",
        "tabWidth": 4
      }
    },
    {
      "files": "**/lwc/**/*.js",
      "options": {
        "tabWidth": 4
      }
    },
    {
      "files": "*.{cmp,page,component}",
      "options": {
        "parser": "html",
        "tabWidth": 4
      }
    },
    {
      "files": ["*.cls", "*.trigger"],
      "options": {
        "tabWidth": 4,
        "apexInsertFinalNewline": false
      }
    }
  ]
}
```

### spell checkerの設定ファイルを追加
Visual Studio Codeの拡張機能「Spell Checker」を使用していて、チームで除外キーワードのリストがある場合、[こちら](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)の手順を参考に設定を行う。

### huskyの設定
huskyを使用すると、特定のGitアクションが発生したときにスクリプトを実行することができる。Salesforceのデフォルトのプロジェクトにはすでにpre-commitが作成されているので、npm installを実行するだけで使用することが可能。

```bash:.husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run precommit
```

プッシュ前以外にも処理を行いたい場合は、フックを作成する（[huskyが対応しているフック](https://git-scm.com/docs/githooks)）。
`npx husky add .husky/pre-push`

pre-commitでステージされたファイルごとに処理を行いたい場合は、package.jsonのlint-statedに処理を定義する。

```json:package.jsonの例
"lint-staged": {
  "**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}": [
    "prettier --check"
  ],
  "**/{aura,lwc}/**": [
    "eslint"
  ],
  "**/lwc/**": [
    "sfdx-lwc-jest -- --bail --findRelatedTests"
  ]
  "**/*.{cls,trigger}": [
    "sfdx scanner:run --engine pmd --pmdconfig pmd/rule.xml --severity-threshold 2 -t"
  ]
},
```

sfdx sccannerについては[こちら](https://forcedotcom.github.io/sfdx-scanner/)。

### 静的解析ツールの設定
ApexPMDの設定を行う。ApexPMDは拡張機能「Salesforce Extension Pack (Expanded)」に含まれている。
[[Apex PMD] VSCodeでApexの静的解析を行う](https://qiita.com/TaaaZyyy/items/d85a93009acefceaf10d)

## package.xmlの作成
gitで管理する資材、VSCodeで扱う資材をpackage.xmlに追加する。あらかじめ組織に接続しておく必要がある。
Visual Studio Codeの拡張機能「Salesforce Package.xml Generator」をインストールしている場合は、コントロールパネルから`SFDX Package.xml Generator: Choose Metadata Components command.`を選択し、資材を選択して「UPDATE PACKAGE.XML」ボタンをクリックする。

## Appendix: Salesforce環境設定(Developer Editionを使用する場合)
1. Developerエディション払い出し
    https://developer.salesforce.com/jpblogs/2016/04/developer-edition-signup/
1. Dev Hub有効化
    [設定] - [Dev Hub]
1. ロック解除済みパッケージの有効化
    [設定] - [Dev Hub]
1. SalesforceCLIに組織を認証・デフォルトのDevHubとして認証
    `sf org login web -a DevHub組織のエイリアス -d -s`
1. ScratchOrgを作成
    `sf force:org:create -a スクラッチ組織のエイリアス -f config/project-scratch-def.json -s`

## Appendix: ブラウザの設定
- [Chrome DevTools を使用したデバッグ - Salesforce Lightning Component Library](https://developer.salesforce.com/docs/component-library/documentation/ja-jp/lwc/lwc.debug_dev_tools)

## Appendix: LWCに型判定を使用する
LWCにTypescriptの型判定を使用する場合は、`force-app/main/default/lwc/jsconfig.json`に下記を追加したうえで、プロジェクトルートにtypingsフォルダを作成し、型定義ファイルを追加します。

```diff_javascript:jsconfig.json
{
    "compilerOptions": {
        "experimentalDecorators": true
    },
    "include": [
        "**/*",
        "../../../../.sfdx/typings/lwc/**/*.d.ts",
+       "../../../../typings/**/*.d.ts"
    ],
    "paths": {
        "c/*": [
            "*"
        ]
    },
    "typeAcquisition": {
        "include": [
            "jest"
        ]
    }
}
```

型定義ファイルのサンプル

```typescript:typings/cmn.d.ts
/**
 * {@link Handle Errors in Lightning Data Service | https://developer.salesforce.com/docs/platform/lwc/guide/data-error.html}
 */
interface FetchResponse {
  body: object | object[]
  ok: boolean
  status: number
  statusText: string
}
```

また、jsconfig.jsonは.gitignoreにデフォルトで追加されているため、上記設定をプロジェクトメンバーで共有したい場合は忘れずに.gitignoreから`**/lwc/jsconfig.json`を削除する。

- [SalesforceでTypeScriptを使用するには – パート2 | Developer Force Blog](https://developer.salesforce.com/jpblogs/2022/10/how-to-use-typescript-with-salesforce-part-2-jp/)
- [TypeScript: Documentation - JSDocリファレンス](https://www.typescriptlang.org/ja/docs/handbook/jsdoc-supported-types.html)

## 参考
- [Salesforce Extensions for Visual Studio Code](https://developer.salesforce.com/tools/vscode/ja)
- [[Apex PMD] VSCodeでApexの静的解析を行う](https://qiita.com/TaaaZyyy/items/d85a93009acefceaf10d)
- [🐶 husky](https://typicode.github.io/husky/#/?id=create-a-hook)
- [Salesforce Code Analyzer](https://forcedotcom.github.io/sfdx-scanner/)

<!-------------------------------------------------------------------->
[^1]:SalesforceではHTML、JavaScript、Apexでファイル末尾の空行が削除される。そのためPrettierで強制的に追加される空行の対応を行わないと、組織からメタデータを取得するたびに差分が発生してしまう。