1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【UI5】TypeScriptを使ってみる

Last updated at Posted at 2021-09-19

はじめに

今年の7月に、UI5でTypeScriptが使えるようになったとアナウンスがありました。

具体的には、@sapui5/ts-types-esmまたは@openui5/ts-types-esmというモジュールでUI5の型情報が提供されており、使うことができます。ただし、両モジュールともBeta Stateとなっており、今後互換性のない変更の可能性があります。よって、個人で試してみるのはいいが、プロジェクトで使うにはまだ早いという段階です。

このブログでは、以下の3点について書きたいと思います。TypeScriptに対応したUI5アプリについては、以下に詳細な説明があります。このブログではエッセンスをかいつまんでお伝えします。
Using TypeScript in UI5 Apps

  1. TypeScriptに対応したUI5プロジェクトの特徴
  2. プロジェクトの作成方法
  3. BTPにデプロイする方法(オプション)

※3.はTypeScriptか否かにかかわらず、UI5プロジェクトをBTPのLaunchpadで使えるようにする一般的な設定です。

1. TypeScriptに対応したUI5の特徴

1.1. そもそも、TypeScriptとは

こちらから引用・翻訳します。

  • JavaScriptに型が追加されたもの
  • 開発時にだけで使われる(ブラウザには理解されないので、実行前にビルドのステップが必要)
  • Microsoftによって開発されたが、オープンソースで広く使われている

特徴は、ソースの中で変数や関数の宣言時に型を明示する必要があるということです。宣言で指定された型と、実際に割り当てようとした変数の型が違った場合、エディタ上でエラーが出ます。これによって、従来は動かしてみないとわからなかった不具合を開発時に知ることができます。

var suomeNumber: number;

始めてTypeScriptを触るという方には、以下のドキュメントがお勧めです。短くまとまっていてコードも載っているのでわかりやすいと思います。
TypeScript for JavaScript Programmers

1.2. UI5はどうやってTypeScriptに対応しているのか

UI5では、@sapui5/ts-types-esmまたは@openui5/ts-types-esmというモジュールによって型情報が提供されます。モジュールの中を見てみると、*.d.tsというファイルがあり、この中でUI5の部品の型定義がされています。型定義はUI5のドキュメントをベースに生成されています。ドキュメントが完全でないと型の定義がされないので、「問題があれば以下にissuesを上げてください」ということになっています。
https://github.com/SAP/openui5/blob/master/CONTRIBUTING.md#report-an-issue

image.png
TypeScriptで書かれたソースは、Babelのプラグインであるbabel-plugin-transform-modules-ui5によって、従来のUI5のコードに変換されます。このプラグインはTypeScriptからJavaScriptへの変換だけでなく、ES6で書かれたコードからES5への変換も行ってくれます。つまり、プラグインを使うことでTypeScriptが使えるだけでなく、ES6でのモダンな書き方もできるようになります。
image.png
図:Getting Started with TypeScript for UI5 Application Developmentより引用

UI5に対応させるために必要な設定ファイルや各種モジュールのインストール方法は以下に載っています。
A Detailed Guide to Create a UI5 TypeScript App From Scratch in Five to Ten Steps

ただし、generator-easy-ui5を使えばTypeScriptに対応したプロジェクトを自動で生成してくれるので、裏の仕組みを全て知らなくてもよいと思います。

1.3. TypeScriptに対応したUI5の特徴

TypeScript (+ES6)に対応したUI5のソースには以下のような特徴があります。

モジュールのロードはimport xxx from ...の形で行う

ES6に対応したおかげで、以下のような書き方ができるようになりました。

//従来の書き方
sap.ui.define(["sap/m/MessageBox"],
	function(MessageBox) {
}

//新しい書き方
import MessageBox from "sap/m/MessageBox";

コントローラーはクラスとして定義する

ES6に対応したおかげで、以下のような書き方ができるようになりました。

//従来の書き方
return Controller.extend("namespace.projectName.controller.App", {})

//新しい書き方
export default class AppController extends Controller {}

メソッド定義で引数、および返り値の型を指定する

このように型を明示するところがTypeScriptの特徴です。

//従来の書き方
	getMessage: function (name) {
		return `Hello, ${name}`;
	}

//新しい書き方
	public getMessage(name:string): string {
		return `Hello, ${name}`;
	}

get系のメソッド呼び出しでは、必要に応じてas xxxでキャストして型を明示する

以下はgenerator-easy-ui5で生成したTypeScriptのプロジェクトに入っているサンプルソースです。

//従来の書き方
this.getOwnerComponent().getContentDensityClass()

//新しい書き方
import AppComponent from "../Component";
...
(this.getOwnerComponent() as AppComponent).getContentDensityClass()

キャストをしなかった場合、以下のようにgetContentDensityClassがComponentに存在しないというエラーになります。
image.png
背景
getOwnerComponent()の返り値はsap.ui.core.Component型です。ただし、sap.ui.core.ComponentにはgetContentDensityClassというメソッドがありません。このメソッドは、sap.ui.core.Componentを拡張したsrc/Component.tsで定義されたものだからです。そこで、getOwnerComponent()で取れるComponentの型を明示することによって、エラーを回避しています。

2. プロジェクトの作成方法

2.1. プロジェクトを生成

generator-easy-ui5を使ってプロジェクトを作成します。ts-appというのがTypeScriptに対応したプロジェクト用のテンプレートです。

yo easy-ui5 ts-app

以下のように質問に答えます。UI5のバージョンは、デフォルトでは1.90.0が設定されています。UI5Conのセッションの中で、TypeScriptがサポートされるのは1.90以降と言われていました。

? How do you want to name this application? ui5TsDemo
? Which namespace do you want to use? miyasuta
? Which framework do you want to use? SAPUI5
? Which framework version do you want to use? 1.90.0
? Who is the author of the library? Mio Yasutake
? Would you like to create a new directory for the application? Yes

プロジェクトの構造は以下のようになります。通常のUI5プロジェクトだとwebappフォルダ配下にview, controllerなどのリソースが配置されますが、TypeScriptだとsrcフォルダになっています。
image.png

easy-ui5を使うと、サンプルソースがあらかじめ入った状態でプロジェクトが生成されます。
src/controller/App.controller.tsを見てみると、TypeScriptに対応したUI5の特徴で紹介した特徴があります。

import MessageBox from "sap/m/MessageBox";
import Controller from "sap/ui/core/mvc/Controller";
import AppComponent from "../Component";

/**
 * @namespace miyasuta.ui5TsDemo.controller
 */
export default class AppController extends Controller {

	public onInit() : void {
		// apply content density mode to root view
		this.getView().addStyleClass((this.getOwnerComponent() as AppComponent).getContentDensityClass());
	}

	public sayHello() : void {
		MessageBox.show("Hello World!");
	}
}

2.2. 実行

package.jsonには、"start"のコマンドが以下のように定義されています。

"start": "npm-run-all --parallel watch:ts start:ui5"

npm startでそのまま実行してみましょう。
以下のブラウザ画面が立ち上がり、"Say Hello"ボタンを押すとダイアログが出力されます。
image.png

2.3. ビルド

以下のコマンドでビルドします。

npm run build

この結果、distフォルダにビルドされたファイルが作成されます。
image.png
App-dbg.controller.jsを見てみると、従来のUI5の書き方になっていることがわかります。

sap.ui.define(["sap/m/MessageBox", "sap/ui/core/mvc/Controller"], function (MessageBox, Controller) {
  /**
   * @namespace miyasuta.ui5TsDemo.controller
   */
  const AppController = Controller.extend("miyasuta.ui5TsDemo.controller.AppController", {
    onInit: function _onInit() {
      // apply content density mode to root view
      this.getView().addStyleClass(this.getOwnerComponent().getContentDensityClass());
    },
    sayHello: function _sayHello() {
      MessageBox.show("Hello World!");
    }
  });
  return AppController;
});

3. BTPにデプロイする方法(オプション)

generator-easy-ui5で生成したTypeScriptのプロジェクトには、デプロイに必要な設定が入っていません。BTPのLaunchpadから利用できるようにするため、以下の設定を行います。

3.1. index.htmlを修正

デフォルトでは、sap-ui-core.jsをローカルのリソースフォルダから持ってくる設定になっています。Launchpadから実行する場合はこのままでよいですが、HTML5 Appsメニューから実行する場合はindex.htmlが使われるので、取得元を以下のように変更する必要があります。

元の状態

src="resources/sap-ui-core.js"

これを、CDNからの取得に変更します。

src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"

3.2. xs-app.json

srcフォルダの直下にxs-app.jsonファイルを追加します。

{
    "welcomeFile": "/index.html",
    "routes": [ 
      {
        "source": "^(.*)",
        "target": "$1",
        "authenticationType": "xsuaa",
        "service": "html5-apps-repo-rt"
      }
    ]
  }

3.3. manifest.jsonを修正

Launchpadで使うため、crossNavigation、およびsap.cloud.serviceの設定を追加します。

	"sap.app": {
		...,
		"crossNavigation": {
		  "inbounds": {
			"intent1": {
			  "signature": {
				"parameters": {},
				"additionalParameters": "allowed"
			  },
			  "semanticObject": "TypeScriptSample",
			  "action": "display",
			  "title": "TypeScript Sample"
			}
		  }
		}
		...
	},
	"sap.cloud": {
	  "service": "ui5tsdemo.service"
	}

3.4. ui5-task-zipperの設定

ビルドした結果をzipするための設定です。まず、devDependenciesにui5-task-zipperを追加します。

npm i ui5-task-zipper --save-dev

インストールされたら、package.jsonのui5.dependenciesにも追加します。

  "ui5": {
    "dependencies": [
      "ui5-middleware-livereload",
      "ui5-task-zipper"
    ]
  }

ui5.yamlに以下の設定を追加します。

builder:
  customTasks:
    -  name: ui5-task-zipper
       afterTask: uglify
       configuration:
         includeDependencies: false
         archiveName: ui5tsdemo  

3.5. mta.yamlを作成

デプロイするための設定です。mta.yamlファイルを新規作成します。
※以下のui5tsdemoは必要に応じて、ご自身のプロジェクト名に置き換えてください

ID: ui5tsdemo
_schema-version: 3.2.0
version: 0.0.1
parameters:
  enable-parallel-deployments: true
modules:
  - name: ui5tsdemo_deployer
    type: com.sap.application.content
    path: .
    requires:
      - name: ui5tsdemo_html5_repo_host
        parameters:
          content-target: true
    build-parameters:
      build-result: resources
      requires:
        - name: ui5tsdemo
          artifacts:
            - dist/ui5tsdemo.zip
          target-path: resources/
  - name: ui5tsdemo
    type: html5
    path: .
    build-parameters:
      builder: custom
      commands:
        - npm install
        - npm run build
      supported-platforms: []  

  - name: ui5tsdemo_destination-content
    type: com.sap.application.content
    build-parameters:
      no-source: true
    requires:
      - name: ui5tsdemo_uaa
        parameters:
          service-key:
            name: ui5tsdemo_uaa-key
      - name: ui5tsdemo_html5_repo_host
        parameters:
          service-key:
            name: ui5tsdemo_html5_repo_host-key
      - name: ui5tsdemo_destination
        parameters:
          content-target: true
    parameters:
      content:
        instance:
          existing_destinations_policy: update
          destinations:
            - Name: ui5tsdemo_html5_repo_host
              ServiceInstanceName: ui5tsdemo_html5_repo_host
              ServiceKeyName: ui5tsdemo_html5_repo_host-key
              sap.cloud.service: ui5tsdemo.service
            - Name: ui5tsdemo_uaa
              Authentication: OAuth2UserTokenExchange
              ServiceInstanceName: ui5tsdemo_uaa
              ServiceKeyName: ui5tsdemo_uaa-key
              sap.cloud.service: ui5tsdemo.service 

resources:
  - name: ui5tsdemo_destination
    type: org.cloudfoundry.managed-service
    parameters:
      service-plan: lite
      service: destination
      config:
        HTML5Runtime_enabled: true
        version: 1.0.0
  - name: ui5tsdemo_html5_repo_host
    type: org.cloudfoundry.managed-service
    parameters:
      service-plan: app-host
      service: html5-apps-repo
      config:
        sizeLimit: 2
  - name: ui5tsdemo_uaa
    type: org.cloudfoundry.managed-service
    parameters:
      path: ./xs-security.json
      service-plan: application
      service: xsuaa                           

プロジェクト直下にxs-security.jsonも作成しておきます。

{
    "xsappname": "ui5tsdemo",
    "tenant-mode": "dedicated"
}

3.6. ビルド、デプロイ

以下のコマンドでビルド、デプロイします。

mbt build
cf deploy mta_archives/ui5tsdemo_0.0.1.mtar

HTML5 Applicationのメニューからアプリを開けるようになっています。
image.png

image.png
設定をすればLaunchpadで開くこともできます。
image.png

思うこと

Babelのプラグインのおかげで、ES6に対応した書き方ができるようになったということが開発者にとってはうれしいのかな、と思います。これで、バックエンドとフロントエンドでコードの書き方を統一することができます。
また、私自身TypeScriptはほとんど使ったことがなかったので、慣れるため個人開発ではしばらくTypeScriptで書いてみようと思います。

参考

TypeScriptについて

UI5とTypeScript

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?