Help us understand the problem. What is going on with this article?

Salesforce DX 使ってみた(その1)

More than 1 year has passed since last update.

はじめに

Salesforce DX とは

TRAILHEAD:Salesforce DX の設定 から抜粋。

Salesforce DX は、開発ライフサイクル全体を合理化する新しいツールセットです。Salesforce DX によって、チーム開発とコラボレーションが向上し、自動テストと継続的インテグレーションが促進され、リリースサイクルがより効率的で俊敏になります。
Salesforce DX は、単に新しいツールセットというだけにとどまらず、情報源を組織からバージョン管理システム (VCS) へと移行する新しい開発パラダイムです。Salesforce DX によって、開発の焦点が、組織ベースの開発からアーティファクトベースの開発へと移ります。

目的

TRAILHEADを元に、Salesforce DX の基本的な機能を使ってみて、操作方法を学ぶ。
細かい部分は、TRAILHEAD:Salesforce DX を使用したアプリケーション開発 を参照。

前提

  • Windows10 64 ビット
  • GitHub

構成

  1. ハブ組織作成
  2. Salesforce CLIをインストール
  3. ハブ組織にログイン
  4. プロジェクト作成
  5. スクラッチ組織作成
  6. スクラッチ組織に変更を加える -1-
  7. 変更の取得 -1-
  8. gitでリポジトリ作成
  9. git init ~ git push
  10. サンプルデータ作成
  11. データ格納ディレクトリ作成
  12. Apexコントローラクラス作成
  13. Lightning コンポーネントの作成
  14. スクラッチ組織に変更を加える -2-
  15. 変更の取得 -2-
  16. 追加の Lightning コンポーネントの作成
  17. スクラッチ組織に変更を加える -3-
  18. 変更の取得 -3-
  19. AccountMap コンポーネントの作成
  20. 地図にマーカーを追加する Lightning イベントの作成
  21. git push
  22. アプリケーションの検証

1. ハブ組織作成

  • ハブ組織とは、組織を管理する組織のこと。
  • 有料の組織(Enterpriseとか)で有効化すると使える。
  • とりあえず試したいなら、Dev Hub トライアル組織 が30日間無料で使える。

ということで、無料組織にサインアップ。

2. Salesforce CLIをインストール

Windows 64 ビット版 をインストール。インストールしたら、sfdxして、以下を確認できれば、OK。

$ sfdx
Usage: sfdx COMMAND

Help topics, type sfdx help TOPIC for more details:

 force    tools for the Salesforce developer
 plugins  create a new sfdx-cli plugin
 update   update the sfdx CLI

3. ハブ組織にログイン

# ハブ組織に接続(と同時にデフォルト組織、エイリアス設定)
$ sfdx force:auth:web:login -d -a DevHub

# ハブ組織を開く
$ sfdx force:org:open -u DevHub

以下、おまけ。

# Sandboxとかも接続可能
$ sfdx force:auth:web:login -r https://test.salesforce.com -a FullSandbox

# 接続組織のリスト
$ sfdx force:org:list --verbose

4. プロジェクト作成

$ sfdx force:project:create -n geolocation

5. スクラッチ組織作成

$ cd geolocation
$ sfdx force:org:create -s -f config/project-scratch-def.json -a GeoAppScratch

6. スクラッチ組織に変更を加える -1-

$ sfdx force:org:open

TRAILHEAD:アプリケーション作成の準備 の カスタム項目の作成 を参照。

7. 変更の取得 -1-

$ sfdx force:source:pull

8. gitでリポジトリ作成

省略。

9. git init ~ git push

$ git init
$ git remote add origin <url>
$ git add .
$ git commit -m "commit_1"
$ git push origin master

10. サンプルデータ作成

$ sfdx force:org:open

TRAILHEAD:アプリケーション作成の準備 の サンプルデータの作成 を参照。

11. データ格納ディレクトリ作成

$ mkdir data
$ sfdx force:data:tree:export -q "SELECT Name, Location__Latitude__s, Location__Longitude__s FROM Account WHERE Location__Latitude__s != NULL AND Location__Longitude__s != NULL" -d ./data

中身はこんな感じ。

Account.json
{
    "records": [
        {
            "attributes": {
                "type": "Account",
                "referenceId": "AccountRef1"
            },
            "Name": "Marriott Marquis",
            "Location__Latitude__s": 37.785143,
            "Location__Longitude__s": -122.403405
        },
        {
            "attributes": {
                "type": "Account",
                "referenceId": "AccountRef2"
            },
            "Name": "Hilton Union Square",
            "Location__Latitude__s": 37.786164,
            "Location__Longitude__s": -122.410137
        },
        {
            "attributes": {
                "type": "Account",
                "referenceId": "AccountRef3"
            },
            "Name": "Hyatt",
            "Location__Latitude__s": 37.794157,
            "Location__Longitude__s": -122.396311
        }
    ]
}

インポートする時は、以下。

$ sfdx force:data:tree:import --sobjecttreefiles data/Account.json

12. Apexコントローラクラス作成

$ sfdx force:apex:class:create -n AccountController -d force-app/main/default/classes
AccountController.cls
public with sharing class AccountController {
@AuraEnabled
public static List<Account> findAll() {
return [SELECT Id, Name, Location__Latitude__s, Location__Longitude__s
   FROM Account
   WHERE Location__Latitude__s != NULL AND Location__Longitude__s !=
          NULL
   LIMIT 50];
  }
}
$ sfdx force:source:push

13. Lightning コンポーネントの作成

$ sfdx force:lightning:component:create -n AccountLocator -d force-app/main/default/aura
AccountLocator.cmp
<aura:component implements="force:appHostable">
  <div>
    <div>AccountMap goes here</div>
    <div>AccountList goes here</div>
  </div>
</aura:component>
AccountLocator.css
.THIS {
  position:absolute;
  height: 100%;
  width: 100%;
  background: #FFFFFF;
}

.THIS>div {
  height: 50%;
}
$ sfdx force:source:push

14. スクラッチ組織に変更を加える -2-

$ sfdx force:org:open

TRAILHEAD:Salesforce CLI を使用した地理位置情報アプリケーションの作成 の Lightning コンポーネントを開くタブの設定 を参照。

15. 変更の取得 -2-

$ sfdx force:source:pull

16. 追加の Lightning コンポーネントの作成

$ sfdx force:lightning:component:create -n AccountListItem -d force-app/main/default/aura
AccountListItem.cmp
<aura:component>
  <aura:attribute name="account" type="Account"/>
  <li><a>{!v.account.Name}</a></li>
</aura:component>
AccountListItem.css
.THIS {
    border-bottom: solid 1px #DDDDDD;
}

.THIS a {
    display: block;
    padding: 20px;
    color: inherit;
}

.THIS a:active {
    background-color: #E8F4FB;
}
$ sfdx force:lightning:component:create -n AccountList -d force-app/main/default/aura
AccountList.cmp
<aura:component controller="AccountController">

    <aura:attribute name="accounts" type="Account[]"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <ul>
    <aura:iteration items="{!v.accounts}" var="account">
        <c:AccountListItem account="{!account}"/>
    </aura:iteration>
    </ul>

</aura:component>
AccountListController.js
({
    doInit : function(component, event) {
        var action = component.get("c.findAll");
        action.setCallback(this, function(a) {
          component.set("v.accounts", a.getReturnValue());
        });
        $A.enqueueAction(action);
    }
})
AccountList.css
.THIS {
    list-style-type: none;
    padding: 0;
    margin: 0;
    background: #FFFFFF;
     height: 100%;
}
AccountLocator.cmp
<aura:component implements="force:appHostable">
    <div>
        <div>AccountMap goes here</div>
        <div>
          <c:AccountList/>
        </div>
    </div>
</aura:component>
$ sfdx force:source:push

17. スクラッチ組織に変更を加える -3-

$ sfdx force:org:open

TRAILHEAD:取引先の地図表示の作成 の スクラッチ組織への Leaflet のダウンロードとインストール を参照。

18. 変更の取得 -3-

$ sfdx force:source:pull

19. AccountMap コンポーネントの作成

$ sfdx force:lightning:component:create -n AccountMap -d force-app/main/default/aura
AccountMap.cmp
<aura:component>

    <aura:attribute name="map" type="Object"/>

    <ltng:require styles="/resource/leaflet/leaflet.css"
        scripts="/resource/leaflet/leaflet.js"
        afterScriptsLoaded="{!c.jsLoaded}" />

    <div id="map"></div>

</aura:component>
AccountMapController.js
({
   jsLoaded: function(component, event, helper) {

      var map = L.map('map', {zoomControl: false}).setView([37.784173, -122.401557], 14);
      L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
        {
              attribution: 'Tiles © Esri'
        }).addTo(map);
      component.set("v.map", map);
  }
})
AccountMap.css
.THIS {
   width: 100%;
   height: 100%;
}
AccountLocator.cmp
<aura:component implements="force:appHostable">

    <div>
        <div>
            <c:AccountMap />
        </div>

        <div>
            <c:AccountList />
        </div>
    </div>

</aura:component>
$ sfdx force:source:push

20. 地図にマーカーを追加する Lightning イベントの作成

$ sfdx force:lightning:event:create -n AccountsLoaded -d force-app/main/default/aura
AccountsLoaded.evt
<aura:event type="APPLICATION">
    <aura:attribute name="accounts" Type="Account[]"/>
</aura:event>
AccountList.cmp
<aura:component controller="AccountController">
    <aura:registerEvent name="accountsLoaded" type="c:AccountsLoaded"/>
    <aura:attribute name="accounts" type="Account[]"/>
    <ltng:require styles="/resource/leaflet/leaflet.css" scripts="/resource/leaflet/leaflet.js" afterScriptsLoaded="{!c.doInit}" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <ul>
    <aura:iteration items="{!v.accounts}" var="account">
        <c:AccountListItem account="{!account}"/>
    </aura:iteration>
    </ul>

</aura:component>
AccountListController.js
({
    doInit : function(component, event) {
        var action = component.get("c.findAll");
        action.setCallback(this, function(a) {
            component.set("v.accounts", a.getReturnValue());
            var event = $A.get("e.c:AccountsLoaded");
            event.setParams({"accounts": a.getReturnValue()});
            event.fire();
        });
    $A.enqueueAction(action);
    }
})
AccountMap.cmp
<aura:component>

  <aura:attribute name="map" type="Object"/>
  <aura:handler event="c:AccountsLoaded" action="{!c.accountsLoaded}"/>
  <ltng:require styles="/resource/leaflet/leaflet.css" scripts="/resource/leaflet/leaflet.js" afterScriptsLoaded="{!c.jsLoaded}" />
  <div id="map"></div>

</aura:component>
AccountMapController.js
({
    jsLoaded: function(component, event, helper) {

        var map = L.map('map', {zoomControl: false}).setView([37.784173, -122.401557], 14);
        L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
             {
                 attribution: 'Tiles © Esri'
             }).addTo(map);
        component.set("v.map", map);
    },

    accountsLoaded: function(component, event, helper) {

        // Add markers
        var map = component.get('v.map');
        var accounts = event.getParam('accounts');
        for (var i=0; i<accounts.length; i++) {
            var account = accounts[i];
            var latLng = [account.Location__Latitude__s, account.Location__Longitude__s];
            L.marker(latLng, {account: account}).addTo(map);
        }  
    }
})
$ sfdx force:source:push

21. git push

$ git add .
$ git commit -m "commit_2"
$ git push origin master

22. アプリケーションの検証

# テスト組織作成
$ sfdx force:org:create -f config/project-scratch-def.json -a GeoTestOrg

# テスト組織にソースをpush
$ sfdx force:source:push -u GeoTestOrg

# テスト組織のユーザに権限セットを付与
$ sfdx force:user:permset:assign -n Geolocation -u GeoTestOrg

# データをインポート
$ sfdx force:data:tree:import -f data/Account.json -u GeoTestOrg

# 環境を開く
$ sfdx force:org:open -u GeoTestOrg

最後に

上手くいけばこんな感じ。次回に続く...

UI.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away