はじめに
Salesforce DX とは
TRAILHEAD:Salesforce DX の設定 から抜粋。
Salesforce DX は、開発ライフサイクル全体を合理化する新しいツールセットです。Salesforce DX によって、チーム開発とコラボレーションが向上し、自動テストと継続的インテグレーションが促進され、リリースサイクルがより効率的で俊敏になります。
Salesforce DX は、単に新しいツールセットというだけにとどまらず、情報源を組織からバージョン管理システム (VCS) へと移行する新しい開発パラダイムです。Salesforce DX によって、開発の焦点が、組織ベースの開発からアーティファクトベースの開発へと移ります。
目的
TRAILHEADを元に、Salesforce DX の基本的な機能を使ってみて、操作方法を学ぶ。
細かい部分は、TRAILHEAD:Salesforce DX を使用したアプリケーション開発 を参照。
前提
- Windows10 64 ビット
- GitHub
構成
- ハブ組織作成
- Salesforce CLIをインストール
- ハブ組織にログイン
- プロジェクト作成
- スクラッチ組織作成
- スクラッチ組織に変更を加える -1-
- 変更の取得 -1-
- gitでリポジトリ作成
- git init ~ git push
- サンプルデータ作成
- データ格納ディレクトリ作成
- Apexコントローラクラス作成
- Lightning コンポーネントの作成
- スクラッチ組織に変更を加える -2-
- 変更の取得 -2-
- 追加の Lightning コンポーネントの作成
- スクラッチ組織に変更を加える -3-
- 変更の取得 -3-
- AccountMap コンポーネントの作成
- 地図にマーカーを追加する Lightning イベントの作成
- git push
- アプリケーションの検証
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
中身はこんな感じ。
{
"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
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
<aura:component implements="force:appHostable">
<div>
<div>AccountMap goes here</div>
<div>AccountList goes here</div>
</div>
</aura:component>
.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
<aura:component>
<aura:attribute name="account" type="Account"/>
<li><a>{!v.account.Name}</a></li>
</aura:component>
.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
<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>
({
doInit : function(component, event) {
var action = component.get("c.findAll");
action.setCallback(this, function(a) {
component.set("v.accounts", a.getReturnValue());
});
$A.enqueueAction(action);
}
})
.THIS {
list-style-type: none;
padding: 0;
margin: 0;
background: #FFFFFF;
height: 100%;
}
<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
<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>
({
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);
}
})
.THIS {
width: 100%;
height: 100%;
}
<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
<aura:event type="APPLICATION">
<aura:attribute name="accounts" Type="Account[]"/>
</aura:event>
<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>
({
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);
}
})
<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>
({
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
最後に
上手くいけばこんな感じ。次回に続く...