【SAP CP CF環境】MTA内で共有できるカスタムライブラリを作る

この記事は [SAP Advent Calendar 2020](https://adventar.org/calendars/5047?fbclid=IwAR1ObBAb-epbzbaYDcmyWDU99ybOKkcWN6YO_CVAAS2YFIbQbliJFGec2Ro) の12月11日分の記事として執筆しています

# 目的
以前、ABAPリポジトリにデプロイするSAPUI5アプリ向けに[共通化できるカスタムライブラリを作成した](https://qiita.com/yonekura-h/items/053fc34acba91fe472d2)が、
今回はCloudFoundryに向けて同一MTAに存在するSAPUI5アプリ（HTML5モジュール）が参照可能なSAPUI5 Libraryを作ってみます。

公式のドキュメントは下記
[Develop an SAPUI5 Library](https://help.sap.com/viewer/825270ffffe74d9f988a0f0066ad59f0/CF/en-US/ec4fda32e66f49d880a8fc6ad54a993c.html)

（せっかくなのでSAP Business Application Studioで作成したかったのですがLibraryのジェネレートがわからず挫折しました。
WebIDEで作成しています。）


# MTAプロジェクト+HTML5モジュールの作成

[このあたり](https://qiita.com/yonekura-h/items/3c53d8129a2cf25ab939)を参考にMTAプロジェクトとHTML5モジュールを作成します。
※MTA作成時の「Use HTML5 Application Repository」にはチェックを入れておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/af7f23a1-27e5-4bd9-16b9-d9295828848c.png)

下記のようにHTML5モジュール「demoUICallLibrary」を持つMTAプロジェクト「demoLibraryMta」を作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/3c19c6c2-2d68-9866-5331-fdaea9db7dd1.png)

# SAPUI5 Libraryの作成

本題のLibraryを作成していきます。
MTAプロジェクトのディレクトリを右クリック -> New -> HTML5 Moduleを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/f17eb60e-5cdf-c1fd-bdf5-e1144ea029b4.png)

テンプレート選択画面が表示されるので、
Categoryを「All Categories」に変更し、SAP Fiori Libraryを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/b141819d-4f07-22f7-8599-d7cd3b9dc304.png)

モジュール名称は「demoLibrary」としました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/bbdcd545-dff2-8508-768f-45b307c88fd1.png)

タイトル、Namespaceを設定してFinishを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/38b29d8e-eb7d-efd5-f674-e786b0d77c3a.png)

MTAプロジェクト「demoLibraryMta」の配下にSAPUI5 Library「demoLibrary」を作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/5c249ad4-37d3-d67f-f9e9-83a6b18a4607.png)

# SAPUI5 Libraryの編集
## 共通関数（jsファイル）を追加
同一MTA内のHTML5モジュールから呼出が可能な関数を作成します。
「demoLibrary」内のsrc配下（`src/jp/co/kyoso/demo/demolibrary`）にフォルダを作成し、jsファイルを配置します。
名称は任意です。
今回は`functions/common.js`としました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/e87752d2-b121-5a25-d628-620b85c437a3.png)

common.jsの中身には以下を記載します。

```javascript:common.js
sap.ui.define([
	"sap/ui/base/Object",
	"sap/m/MessageBox"
], function ( Object, MessageBox) {
	"use strict";
	return Object.extend("jp.co.kyoso.demo.demolibrary.functions.common", {
		_testCommonFunction: function (sMsg) {
			// 呼出テスト
			MessageBox.information(sMsg);
		}
	});
});
```

※Namespaceはlibrary.jsの記載に合わせればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/c0501f26-2bbb-38bb-e9f2-bbba23522110.png)


今回、テスト用に呼び出す関数として`_testCommonFunction`を用意しました。

## 共通メッセージ（i18n.properties）を追加

次に、メッセージのリソースを共通化できるよう、
i18nプロパティをSAPUI5 Libraryに設定します。

先ほど同様に「demoLibrary」内のsrc配下にフォルダを作成し、`i18n.properties`ファイルを作成します。
`i18n/i18n.properties`を作成しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/3cd88167-5437-caab-d4cb-44131179ab03.png)

i18n.propertiesの中身には共通化したいメッセージを記載します。

```properties:i18n.properties

CallCommonMassage=共通メッセージ
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/0061be50-ba8c-3340-7f47-078333935d49.png)

# HTML5モジュールからライブラリを呼び出す
上記でライブラリ内に作成したcommon.jsやi18n.propertiesをHTML5モジュールで呼び出すための
方法を記載していきます。

## 呼出設定
### 1.index.htmlの編集
まずはSAPUI5 LibraryのモジュールをHTML5モジュール「demoUICallLibrary」で読み込むために
index.htmlを編集します。

index.htmlのscriptに記載されている`data-sap-ui-resourceroots`プロパティに以下を追記します。

```
"jp.co.kyoso.demo.demolibrary": "../jpcokyosodemodemolibrary-1.0.0"
```
※下図参考
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/84b711c3-3d4a-c9cc-7ad3-42d06b079969.png)

※※
上記で`"jp.co.kyoso.demo.demolibrary"`という名称でライブラリを読み込むよう設定しています。
"../jpcokyosodemodemolibrary-1.0.0"はライブラリがHTMLリポジトリに格納された際のパスになります。


### 2.manifest.jsonの編集
manifest.jsonにライブラリの設定をします。
`sap.ui5` -> `dependencies` -> `libs`以下に下記を追記します。

```json
"jp.co.kyoso.demo.demolibrary": {}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/c421e0e2-6d2c-0a0a-a4c0-bd25b59bb281.png)

上記で呼出のための設定は完了です。

## 共通メッセージ（i18n.properties）のモデルを定義
ライブラリに定義したi18n.propertiesをローカルのプロパティと同じように呼び出せるようにするため、
manifest.jsonにModelを定義します。


`sap.ui5` -> `models`以下に下記を追記します。
`commoni18n`というモデル名で`jp.co.kyoso.demo.demolibrary`のi18nリソースを読み込むよう設定しています。

```json:manifest.json
			"commoni18n": {
				"type": "sap.ui.model.resource.ResourceModel",
				"settings": {
					"bundleName": "jp.co.kyoso.demo.demolibrary.i18n.i18n"
				}
			}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/f123a55f-d6d8-1df5-6d3c-3df08491a3d8.png)

## Controllerファイルからライブラリを呼び出す
上記まででようやくライブラリの作成～呼出設定が完了したので、
HTML5モジュールのcontroller.jsからライブラリを使用します。



```javascript:Main.controller.js
sap.ui.define([
	"sap/ui/core/mvc/Controller",
	// demolibrary（ライブラリ）配下のファイルを指定
	"jp/co/kyoso/demo/demolibrary/functions/common"
], function (Controller , common) {
	"use strict";

	return Controller.extend("jp.co.kyoso.demo.demoUICallLibrary.controller.Main", {
		// commmon.jsのインスタンス生成
		oCommonLib: new common(),
		
		onInit: function () {

		},
		// ボタン押下時処理
		onPress: function(){
			// 共通メッセージを呼び出す
			var sMassage = this.getView().getModel("commoni18n").getResourceBundle().getText("CallCommonMassage");
			// 共通関数を呼び出す
			this.oCommonLib._testCommonFunction(sMassage);
		}
	});
});
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/cb728c26-befb-b4ed-1d68-1c0895853e4a.png)

また、あわせてControllerに記載した関数を呼び出すButtonをView.xmlに配置します。

```xml:Main.view.xml
<mvc:View controllerName="jp.co.kyoso.demo.demoUICallLibrary.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
	<Shell id="shell">
		<App id="app">
			<pages>
				<Page id="page" title="{i18n>title}">
					<content>
						<!--共通メッセージを表示するボタン-->
						<Button text="{commoni18n>CallCommonMassage}" press="onPress"/>
					</content>
				</Page>
			</pages>
		</App>
	</Shell>
</mvc:View>

```

※この時点でWebIDEから実行してもライブラリが参照できず、
　うまく実行できないと思います。

# ビルドとデプロイ
HTML5モジュールが参照するライブラリはCF環境にデプロイされている必要があります。
Neo環境上でライブラリを開発する場合はWorkSpaceのライブラリを参照することが可能でしたが、
CF環境の作りでは難しそうでした。。

下記、とりあえずデプロイしてみたらうまくいかなかった点と解消法です。

## SAPUI5 Libraryのデプロイ設定（2020/12時点）
### Build設定の変更
MTA Buildを実施し、.mtarファイルを作成するところまではうまくいきますが、
CF環境へのデプロイを実行するとui_deployerで下記のようなエラーになります。。。

```
Application "demoLibraryMta_ui_deployer" startedError executing application "demoLibraryMta_ui_deployer": Deployment of html5 application content failed [Deployment Id: deploy-6bb9d679-37c8-11eb-b6f9-eeee0a80763d] Error: Error while uploading resources to Server; Status: 400 Response: "Upload application content failed { CODE: '1001' } validation error: manifest.json not found."
```


ライブラリをビルドする際、UI5 Buildを使用しているとデプロイがうまくいかないため、
Grunt Buildへ変更しました。
　→ 参考：[Updating Your MTA Project's Grunt Build to the UI5 Build](https://help.sap.com/viewer/825270ffffe74d9f988a0f0066ad59f0/CF/en-US/6bd449e60cec4020bdb2f7a5c27e8bb6.html)

mta.yamlに記載されているライブラリモジュールのbuild-parametersを変更します。
※`modules`配下

```yaml:mta.yaml
modules:
 ~~~省略~~~
  - name: demoLibrary
    type: html5
    path: demoLibrary
    build-parameters:
      builder: grunt
      supported-platforms: []
      build-result: dist
 ~~~省略~~~

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/e88e656d-635c-2d2c-8be8-dd10b4bc23c4.png)

### 文字化け解消
上記のBuild設定変更でデプロイはできましたが、
日本語で定義した共通メッセージが文字化けしてしまうので対策します。
（おそらくGrunt Buildに変更したことが原因ですが。。。）

ライブラリモジュールのフォルダ配下にある`ui5.yaml`に文字コード設定を以下を追記します。

```yaml:ui5.yaml
resources:
  configuration:
    propertiesFileSourceEncoding: UTF-8
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/8910deda-a30e-7d8c-0773-721f72077fff.png)

## 動作確認
上記の設定を追加してMTA Build -> Deploy to SAP Cloud Platformを実行します。
デプロイが完了すれば、共通の関数やメッセージが参照できるHTML5モジュールを実行することが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159467/5a6f39db-3190-5f4b-8fd7-9ac2b1fad0ea.png)

HTML5モジュールを更新してIDE上から実行することは可能ですが、
ライブラリを更新した場合、確認するためには再度デプロイをする必要があります。

# おわりに
WebIDEベースとなってしまいましたが、
CFに向けた場合のライブラリの作り方をまとめました。
Business Application Studioに今回の構成を持って行った場合にうまく実行できるかは
やってみないと分からない部分があるので確認してみようとおもいます。