Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
anditru
Advisor
Advisor
In this blog post, we will go through the process of including an external library, in our case an NPM package, in a UI5 application that serves as a frontend for CAP application. We will cover the setup of the necessary tools and the development of the custom control that will glue the UI5 app and the library together. Finally, we will deploy the entire project to the BTP and include the UI5 app in a Launchpad Site using SAP Build Work Zone, Standard Edition.

I am aware that there are already several great blog posts on the subject of including external libraries in UI5 but going through the development myself, facing the different approaches to include an NPM package, I found that an end-to-end example including the deployment and the integration with CAP would have been very helpful. The code for this project can of course be found in a GitHub repository.

Setup & Tools


For the development, we will use the SAP Business Application Studio but most of the steps can be executed in VS Code as well with the right extensions installed.

As mentioned before in our scenario we will assume that the UI5 app will serve as the UI for a CAP application. So we will use the cds CLI to run our app in the development environment. Additionally,  we will use the cds-plugin-ui5 since it integrates the UI5 development server provided by the UI5 Tooling into our cds sever and thus allows us to use the benefits of the UI5 Tooling without starting a UI5 development server separately.

To integrate the NPM package we will use ui5-tooling-modules. In the following section, I will elaborate, on how I came to that decision.

Approaches to include external libraries


There are two approaches to how an external library can be integrated into a UI5 application.

  1. The officially recommended way is using project shims provided by the UI5 Tooling. How to integrate an NPM package with this approach has been described thoroughly in this blog post.

  2. The second way is using the aforementioned ui5-tooling-modules. This approach has been described in this blog post.


In my opinion second one is the better approach for the following reasons:

  • It requires less configuration. The project shims require a lengthy configuration in the ui5.yaml while the ui5-tooling-modules only require a few lines. If you want to deploy your app to SAP Build Work Zone, Standard Edition, additional configuration in the Component.js is required, which the ui5-tooling-modules provides out of the box.

  • It provides a better developer experience. When you run your app locally, UI5 needs to find the coding of your external library. The only way to archive this that I could find using project shims is rather unelegant: You need to copy the resources folder containing the bundled external library which is generated during the build to your webapp folder. The ui5-tooling-modules provide a custom middleware for the UI5 development server which resolves the packages automatically.


For these reasons, we will use the ui5-tooling-modules.

Development


Now let's dive into development. I will assume that you already have a locally working CAP application that delivers some data that you want to display in your custom control.

As an example I have prepared a CAP app with a single service that returns common AI buzzwords which we want to display in a word cloud in the UI. The word cloud will be the custom control we are going to implement. It will have one aggregation, the words to display. To layout the word cloud we will use the NPM package d3-cloud. The entire code of the project can be found in the corresponding GitHub repository.

Step 1: Preparing the CAP app for deployment


As the first step, we need to prepare our CAP application for deployment, because afterward when we add our UI we want the mta.yaml to be updated with the deployment configuration for the UI as well. To do so we first run
cds add mta

Then we add XSUAA and HANA Cloud to our production profile by running
cds add xsuaa,hana --for production

Now we have a working mta.yaml for the deployment of the CAP app.

Step 2: UI setup


For the UI setup, we first need to add the configuration for the managed approuter to our mta.yaml. This is the only step that, to my knowledge, must be done in the BAS if you do not want to type in the configuration in the mta.yaml manually.

  • Right-click your mta.yaml and select "Create MTA Module from Template"

  • In the wizard select "Approuter Module".

  • Follow the steps in the wizard and make sure that Managed Approuter is selected as HTML5 application runtime.


Next, we need to generate our initial UI5 application. If you want to do this in VS Code make sure you have all the Fiori Tools extensions installed.

  • Open the command palette

  • Select "Fiori: Open Application Generator"

  • In the wizard select the template "Basic" which will give us a UI5 freestyle app.

  • As the data source select your local CAP project and your desired service.

  • Provide view name

  • In the step "Project Attributes" make sure that "Add deployment configuration to MTA project" and "Add FLP configuration" are set to "yes".

  • In the step "Deployment Configuration" select "Local CAP Project API (Instance Based Destination)" as the destination name.

  • Follow the remaining steps in the wizard and wait until the generation has finished.


The steps conducted so far in this section are the same as for any other UI5 app to be used in SAP Build Work Zone, Standard Edition. The following is to integrate the UI5 development server into our cds server:

  • Add the cds-plugin-ui5 as a dev dependency to your CAP app by running
    npm i --save-dev cds-plugin-ui5


  • Add the configuration for the plugin to the cds section of your package.json. It should look like this:
        "cds": {
    ...,
    "cds-plugin-ui5": {
    "modules": {
    "<module-name>": {
    "configFile": "ui5.yaml"
    }
    }
    }
    }​

    <module-name> needs to be replaced with the module name you chose for the UI5 app in the generation wizard. In case you do not remember it: It is the name of the folder of your UI5 app in the app folder of your project.

  • To check if it worked run the app with
    cds watch


  • Open it in your browser. In the CAP start page, you should see little UI5 icons next to the paths of your UI5 app.


Step 3: Integrate the NPM package


Now let's integrate the NPM package.

  • cd to your UI5 app

  • Install the ui5-tooling-modules, @Sap/ux-ui5-tooling and version 3 of the UI5 cli by running
    npm i --save-dev @ui5/cli@3 @sap/ux-ui5-tooling ui5-tooling-modules


  • In both ui5.yaml and ui5-deploy.yaml set the specVersion to 3.1

  • Add both packages to the UI5 dependencies in the package.json of the UI5 app:
        "ui5": {
    "dependencies": [
    ...
    "ui5-tooling-modules",
    "@sap/ux-ui5-tooling"
    ]
    }​


  • Add the configuration for the UI5 development server to your ui5.yaml:
    server:
    customMiddleware:
    - name: fiori-tools-proxy
    afterMiddleware: compression
    configuration:
    backend:
    - path: /resources
    url: https://ui5.sap.com
    - path: /test-resources
    url: https://ui5.sap.com
    - path: /odata
    url: http://localhost:4004
    - name: ui5-tooling-modules-middleware
    afterMiddleware: compression
    configuration:
    addToNamespace: true​


  • In the ui5-deploy.yaml, add the ui5-tooling-modules-task to the builder configuration:
    ...
    builder:
    ...
    customTasks:
    ...
    - name: ui5-tooling-modules-task
    afterTask: replaceVersion
    configuration:
    addToNamespace: true
    ...​

    Notice the option addToNamespace being set to true. This makes the ui5-tooling-modules bundle the NPM package such that they can also be used in SAP Build Work Zone, Standard Edition. According to the documentation of the ui5-tooling-modules this only works seamlessly for non-UI5 packages. For details, please look at the documentation.

  • In the index.html of your application the src property of the boot strap tag will look like this

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

    Change it to the following to make the app load the UI5 resources through the UI5 development server:


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



  • Install the NPM packages you want to integrate as dev dependencies. In my case by running
    npm i --save-dev d3-cloud



Now you are all set to use the library. You can import them into your Control or Controller as follows:
sap.ui.define([
...
"d3-cloud"
], function(..., cloud) {
"use strict";

return Control.extend("aibuzzwords.control.WordCloud", {
...
});
});

If you then run the app using cds watch and open it in your browser, the ui5-tooling-modules will resolve the packages on the fly.

Step 4: Developing the controls


Now we can start developing our controls. For the word cloud, I developed two of them: The parent control WordCloud which is responsible for computing the layout using the d3-cloud library and the child control Word which is used in the words aggregation of the WordCloud control. I think the code mostly speaks best for itself. Nevertheless, I would like to mention some quirks of UI5 I encountered during development.

  • Asynchronous tasks: In my case, I use d3-cloud to compute the layout of the word cloud, which happens asynchronously. If you have anything asynchronous to calculate, never do that in the renderer function. This will give you lots of unhelpful error messages.

  • Updating properties: Be cautious when you update properties of your control in the onBeforeRendering function since changing a property of the control causes it to be rerendered which can cause infinite loops. To prevent this, I added the hidden property _layoutComputed as a "circuit breaker".


Step 5: Deployment


Now we are going to deploy our application to SAP BTP. First, make sure that you have access to a Subaccount with an available SAP HANA Cloud and a subscription to SAP Build Work Zone, Standard Edition.

Then build your application by running
npm run build

This script should have been generated during Step 1. If not, you can find it here.
Now login to your Subaccount using the Cloud Foundry CLI and target the space you want to deploy to.

Run the deploy script
npm run deploy

If you do not have one, you can find it here. Once the script has finished, you can add your UI5 app to a Launchpad Site in SAP Build Work Zone, Standard Edition as described in step 4 "Create your SAP Build Work Zone, standard edition site" of this tutorial.

Based on my experience getting the application to appear in SAP Build Work Zone, Standard Edition is the most error-prone task in the development. Therefore, here are some troubleshooting tips to addressing the most common issues:

  • sap.cloud.service: In your mta.yaml and in the manifest.json of your UI5 app there is a property sap.cloud.service which must match. Otherwise, the app will not appear in SAP Build Work Zone, Standard Edition.

  • Inbound navigation: Another common mistake is a missing inbound navigation intent in your UI5 app: In the manifest.json of your UI5 app there must be an inbound intent configured in the section "crossNavigation". It should look something like this:
        "crossNavigation": {
    "inbounds": {
    "AiBuzzword-view": {
    "semanticObject": "AiBuzzword",
    "action": "view",
    "title": "{{flpTitle}}",
    "signature": {
    "parameters": {},
    "additionalParameters": "allowed"
    }
    }
    }
    }​

    If you are missing this intent, your app will also not appear in SAP Build Work Zone, Standard Edition.

  • HTML5Runtime_enabled: The configuration of the Destination Service in your mta.yaml has a property HTML5Runtime_enabled  which must be set to true. Otherwise, your app will also not appear in SAP Build Work Zone, Standard Edition.

  • Character limits: If all this is not the reason, the name of your HTML5 app in the mta.yaml or in the ID of the UI5 application in the manifest.json or the SemanticObject might be too long since there are character limits for both of them.


Conclusion


Now we have worked our way through the entire process of developing a UI5 application using an external library and deploying it to SAP BTP. I admit that there is still a lot of configuration to do at the beginning but I think the developer experience afterwards is worth it. If you feel that anything is unclear or that I overlooked an important aspect, feel free to leave a comment.