Lightning Web Components をほんのちょっぴり体験した

# はじめに

Salesforceが`Lightning Components`を世に送り出したのが2015年の夏頃でしたでしょうか。昨年あたりから「だいぶ小慣れてきた」などの意見を耳にする一方で、独自のフレームワークであるがゆえに「ツラい」という意見も多数ありました。
そんな中で、次世代のSalesforce用UIフレームワークとして`Lightning Web Components(以下、LWC)`が誕生しました。

先にリリースされていた`Lightning Components`は`Aura Components`として、`LWC`と`Aura Components`をひっくるめて、`Lightning Components`と呼ぶようです。
![LightnincComponent_System.png](https://qiita-image-store.s3.amazonaws.com/0/1840/b9fed7d2-d927-80ae-980c-8aa339c0122e.png)
["Introducing Lightning Web Components" より抜粋
](https://developer.salesforce.com/blogs/2018/12/introducing-lightning-web-components.html)

本記事では、そんなLWCをほんのちょっぴり体験したことを共有します。
なお、本記事は[Salesforce Platform Advent Calendar 2018](https://qiita.com/advent-calendar/2018/salesforce-platform)の21日目です。

# 何はともあれQuickStart

LWCのQuickStart用のTrailheadモジュールがすでに公開されています。
[Quick Start: Lightning Web Components](https://trailhead.salesforce.com/ja/content/learn/projects/quick-start-lightning-web-components)
まずは、このモジュールを一通りやってみると良いでしょう。

### [Set Up Your Salesforce DX Environment](https://trailhead.salesforce.com/ja/content/learn/projects/quick-start-lightning-web-components/set-up-salesforce-dx)

まずは環境を整えるということで
1. pre-release Developer Edtionの取得およびDevHub有効化
2. salesforce CLIのインストールおよびpre-release用プラグインのインストール
といった作業を進めます。

### [Set Up Visual Studio Code](https://trailhead.salesforce.com/ja/content/learn/projects/quick-start-lightning-web-components/set-up-visual-studio-code)

ローカルでの開発ではデファクトスタンダードと化した`Visual Studio Code`(VSCode)を使います。
余談ですが、Force.com IDEは来年10月にサポートも切れるということで役目を終える模様です。
ありがとう Force.com IDE...
※あと、誰か[Welkin Suite](https://welkinsuite.com/)を試して欲しいですね..

こちらも手順に沿って、`salesforce extension pack`をインストールすればOKです。
なお、Trailheadモジュールでは、ステップの確認は実質なくて、ただボタンを押すだけのようです。

### [Create a Hello World Lightning Web Component](https://trailhead.salesforce.com/ja/content/learn/projects/quick-start-lightning-web-components/create-a-hello-world-lightning-web-component)

いよいよLWCを作成します。これまた手順通りに進めましょう。
ちなみに、`sfdx force:source:push` する際に思わぬ罠があるようなので、ご注意ください。

<img width="632" alt="twitter_kimura_san.png" src="https://qiita-image-store.s3.amazonaws.com/0/1840/a061288d-7a71-4346-b035-1ec2832197f1.png">


# その他サンプルアプリケーション

一旦、QuickStartが終わりましたら、[Sample Gallery](https://trailhead.salesforce.com/ja/sample-gallery)よりサンプルアプリケーションをデプロイしてみて試してみましょう。
例えば[EBikes](https://github.com/trailheadapps/ebikes-lwc)というアプリケーションを試すには、READMEの手順に沿って、ソースコードをScratchOrgにデプロイすればOKです。

が、実際に試してみたところ、`sfdx force:source:push`で以下のエラーが発生しました

```
PROJECT PATH                                                                    ERROR
──────────────────────────────────────────────────────────────────────────────  ───────────────────────────────────────────────────────────────────────────────
force-app/main/default/objects/Order_Item__c/Order_Item__c.object-meta.xml      Cannot specify a startsWith attribute for this language
```

詳細まで調べていませんが、
`force-app/main/default/objects/Order_Item__c/Order_Item__c.object-meta.xml` にて、`<startsWith>`タグを削除して再度pushすれば正常に処理されました。
<img width="451" alt="Order_Item__c.object-meta.xml.png" src="https://qiita-image-store.s3.amazonaws.com/0/1840/d46c9891-22cb-f19c-701f-22d6b3c69fcd.png">

※`force-app/main/default/objects/Order__c/Orde__c.object-meta.xml`も同様に修正しました


# もう少し詳しく

※`LWC`の中身をもっとみてみようという場合には、[Lightning Web Components Dev Guide](https://developer.salesforce.com/docs/component-library/documentation/lwc)を確認すると良いでしょう。

### Web Componentsがベース
Web Componentsは大きく4つの仕様から構成されています。

* Shadow DOM
* Custom Elements
* HTML Templates
* HTML Imports（ただ、HTML importsの実装が進まず、代わりにES Modulesを使ってコンポーネント宣言するjsを読み込むのがスタンダードになるとか？）

`LWC`は`Web Components`をベースにして、Salesforceとの連携部分([Work with Salesforce Data](https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.data))や、セキュリティの強化([Security with Lightning Locker](https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.security_locker_service))などを付け足したもの、というイメージなのかな、と思います。
※ただLightning Lockerは様々な制約を課してる？模様...。(詳細は誰か詳しい人お願いします！ [(Dynamic component creation in Lightning Web Components)](https://salesforce.stackexchange.com/questions/243876/dynamic-component-creation-in-lightning-web-components) etc)

そのほか、ES Modulesの仕組みがあるので、異なるコンポーネントの機能を利用することも簡単に可能となります。

### Salesforceとのデータ連携について

大きくは以下2つの方法が推奨されているようです。

* `Lightning Data Service`を使う

例えば、`lightning/uiRecordApi`といったモジュールが用意されていますので、それをインポートして利用します。

```js
import { LightningElement, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
import NAME_FIELD from '@salesforce/schema/Account.Name';

export default class Example extends LightningElement {
    @wire(getRecord, { recordId: '001xxxxxxxxxxxxxxx', fields: [NAME_FIELD] })
    propertyOrFunction;
}
```

* `Apex`で定義したメソッドを使う

Apexクラス側で`@AuraEnabled`アノテーションをつけてstaticなメソッドを定義しておけば、`LWC`でインポートして利用します。

```java
public with sharing class ContactController {

    @AuraEnabled(cacheable=true)
    public static List<Contact> getContactList() {
        return [SELECT Id, Name, Title, Phone, Email, Picture__c FROM Contact WHERE Picture__c != null LIMIT 10];
    }

}
```

```js
import { LightningElement, wire, track } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';
...
```

### テストについて

`LWC`では、`Jest`を使うことが推奨されているようです。[(Test Lightning Web Components)](https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.testing)
[Jest](https://jestjs.io/ja/)はFacebook製のテストフレームワークで、"高速なテスト実行", "ゼロ・コンフィグレーション", "コードカバレッジ機能を内蔵"といった特徴を備えています。

サンプルアプリケーションのEBikesで、試すことができるようで、実際に試してみました。

（↓こちらの環境です）

```bash
$ node -v
v10.14.2
```

1. npmのインストール

EBikesのプロジェクト直下にて、以下のコマンドで必要なモジュールをインストールします。

```bash
$ npm install
$ npm install @salesforce/lwc-jest --save-dev
```

2. テストを実行する

```bash
$ npm run test:unit
```

```
> ebikes-lwc@1.0.0 test:unit /Users/takahiro-yonei/dev/salesforce/12_Pre/ebikes-lwc
> lwc-jest

 PASS  force-app/main/default/lwc/productFilter/__tests__/productFilter.test.js (13.516s)
  c-product-filter
    filterChange event
      ✓ fired when slider value changes (819ms)
      ✓ fired when search value changes (522ms)
      ✓ fired when checkbox is toggled (952ms)
...(途中略)
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        17.107s, estimated 20s
Ran all test suites.
```

`Jest`では、以下の条件にマッチしたファイルをテストコードとして認識して、テストを実行します。

* `__test__`ディレクトリ内の、ファイル名の末尾が`.js`のファイル
* ファイル名の末尾が`.test.js`のファイル
* ファイル名の末尾が`.spec.js`のファイル

EBikesアプリケーションの場合、`force-app/main/default/lwc/productFilter`に`__test__`というディレクトリがあり、その中に`productFilter.test.js`というファイルがあるのでそれがテストコードとして認識され、テスト実行された、という具合です。

`Jest`を使ったテストのセットアップ方法の詳細は[コチラ](https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.unit_testing_using_jest_installation)にあります。

### Playground

[Playground](https://developer.salesforce.com/docs/component-library/tools/playground)が用意されていて、色々試してみることもできるようです。

### LEXへの組み込み

AppBuilderに組み込むことが可能です。その場合、　コンポーネントの`.js-meta.xml`ファイルに設定情報を定義しておくようです。（以下、例）

```xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>45.0</apiVersion>
  <isExposed>false</isExposed>
  <masterLabel>Best Component Ever</masterLabel>
  <description>This is a demo component.</description>
  <targets>
      <target>lightning__RecordPage</target>
      <target>lightning__AppPage</target>
      <target>lightning__HomePage</target>
  </targets>
  <targetConfigs>
      <targetConfig targets="lightning__RecordPage">
          <property name="prop1" type="String" />
          <objects>
              <object>Account</object>
              <object>Opportunity</object>
              <object>Warehouse__c</object>
          </objects>
      </targetConfig>
      <targetConfig targets="lightning__AppPage, lightning_HomePage">
          <property name="prop2" type="Boolean" />
      </targetConfig>
  </targetConfigs>
</LightningComponentBundle>
```

# さいごに

以上、ほんのちょっぴり触ってみたあたりの話でした。

さて、`LWC`が誕生した背景には一体何があるのでしょうか。
おそらく、`Lightning Components`では解決できなかった「何か」をクリアすべく創られたものだと思いますが、`LWC`はそれをクリアできるでしょうか？
今回（？）は、かなりWebの標準技術をベースにしたものとして創られているようですので、`Lightning Component`に手を出すのに躊躇していたエンジニアには非常に関心が高いものになっているのではないでしょうか？（たぶん）

現時点ではクリアすべき技術的な課題が多く残されていると思いますが、まだ産まれたばかりのUIフレームワークですので、暖かくいじっていきたいと思います。
そして、今後の動向を継続してウォッチしていきましょう！

それでは楽しい`LWC`ライフを