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: 

Content Navigation


Part 1: A simple UI5 app that runs in the SAP Launchpad Service

Part 2: Multiple Apps with a Shared Reuse Library (Current page)

Part 3: Splitting bigger projects

Multiple Apps with a Shared Reuse Library


In part 1 you have learned how to build and deploy a single app. In this 2nd part this is now extended to multiple apps that share a reuse library with common code.
The library contains a control as well as a reuse component.

The sample code can be found in the GitHub repository.

Deployed Content


Let’s have a look at how the deployment looks now and what has changed. The needed service instances haven't changed at all, but more HTML5 apps are now deployed to the same app host:


Both apps depend on the reuse library, which is expressed in their manifest.json file under sap.ui5/dependencies. The reuse library contains an embedded manifest.json for the component.

MTA Project Structure


The mta.yaml of the project has been enhanced slightly. Two more modules for the 2nd app and the library are added and they are linked to the UI deployer module:




The UI5 Library



The library only contains the bare minimum to demonstrate relevant aspects. Here it contains a sample reusable control and an embedded reusable component. Of course there could also be other reusable content like base classes, etc.

Build


The UI5 library is also built with UI5 Tooling. The build is controlled the same way as the apps via the package.json and the ui5-deploy.yaml.
In the ui5-deploy.yaml and the manifest.json the type is now set to library.

For libraries the builder requires a different project structure. Instead of a webapp folder there must be a src folder..
Since version 3.0 of the UI5 Tooling, it is no longer needed to add a folder structure for the library namespace.

Instead of a Component.js file the library contains the files library.js and .library to define the library metadata.


The build produces a library-preload.js file that packages all minified files including the sources of the reuse component. No dedicated Component-preload.js is produced.

Routings


The xs-app.json file only contains a route to serve its own sources.
This lib doesn't use an own OData service, but this would be possible for the embedded component. In that case you would have to create a corresponding route here.
{
"authenticationMethod": "route",
"routes": [
{
"source": "^(.*)$",
"target": "$1",
"service": "html5-apps-repo-rt",
"authenticationType": "xsuaa"
}
]
}

The lib doesn't need to be started standalone and therefore has no ui5.yaml with a local middleware.
Note that if you want to build unit test pages for the library you might need a local test environment for it as well in the same way as for the apps.

App Descriptor


It has a manifest.json file that defines a unique sap.app/id and the sap.app/type library for it. There are no inbounds and no services defined, but the embeds property lists the subfolder of the embedded reuse component
"sap.app": {
"id": "btp.samples.multiple.apps.lib",
"type": "library",
"i18n": "i18n/i18n.properties",
"title": "{{title}}",
"applicationVersion": {
"version": "1.0.0"
},
"embeds":["comp/reuse"]
}

It also specifies sap.cloud/service with the same service name as for the apps. This way it will also be bound to the single XSUAA instance.
"sap.cloud": {
"public": true,
"service": "btp.samples.multiple.apps"
}


The Embedded Component


The component is located in the comp/reuse subfolder. It is kept simple and only contains a Main view that renders a simple button in the Main.view.xml file. It doesn't declare any models or use any OData services but this would be possible in the same way as for an application.

The manifest.json defines type as component and an ID which is constructed including the parent library ID and the relative path inside. This is needed to avoid any issues with module path resolution.
It declares the embeddedBy property with the path to the embedding library. This is an important indicator for the platform that the preload package of the component is part of the library preload package. Without it, there might be an unnecessary request at startup which ends with a 404 Not Found error.
{
"_version": "1.32.0",
"sap.app": {
"id": "btp.samples.multiple.apps.lib.comp.reuse",
"type": "component",
"i18n": "i18n/i18n.properties",
"title": "{{appTitle}}",
"description": "{{appDescription}}",
"applicationVersion": {
"version": "1.0.0"
},
"embeddedBy": "../../"
}
}

There is no need to specify the sap.cloud node here. This will be inherited from the manifest.json of the lib.

The UI5 Apps



For the apps (app1 and app2) there are only small changes.

In the manifest.json of the first app the dependency to the library has been added.
"sap.ui5": {
"dependencies": {
"minUI5Version": "1.95.0",
"libs": {
"sap.ui.core": {},
"sap.m": {},
"sap.f": {},
"btp.samples.multiple.apps.lib": {}
}
}
}

There are no resourceRoots URLs defined here, because these depend on the way how the apps are started. 

 

The Master.view.xml uses the library by adding the Reuse control.
<mvc:View
controllerName="btp.samples.multiple.apps.app1.controller.Master"
xmlns="sap.m"
xmlns:semantic="sap.f.semantic"
xmlns:mvc="sap.ui.core.mvc"
xmlns:lib="btp.samples.multiple.apps.lib">

<!-- Reuse control from shared lib -->
<lib:controls.Reuse text="App1" />

</mvc:View>

 

In the manifest.json of the 2nd app there is also a component usage for the reuse component.
    "sap.ui5": {
"dependencies": {
"minUI5Version": "1.95.0",
"libs": {
"sap.ui.core": {},
"sap.m": {},
"sap.f": {},
"btp.samples.multiple.apps.lib": {}
}
},
"componentUsages": {
"resuse": {
"name": "btp.samples.multiple.apps.lib.comp.reuse",
"settings": {},
"componentData": {},
"lazy": false
}
}
}

 

In the Master.view.xml there is a component container that shows the component usage.
<mvc:View
controllerName="btp.samples.multiple.apps.app2.controller.Master"
xmlns="sap.m"
xmlns:semantic="sap.f.semantic"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc"
xmlns:lib="btp.samples.multiple.apps.lib">
<semantic:titleContent>
<Image id="titleImage" />
<!-- Reuse control from shared lib -->
<lib:controls.Reuse text="App2" />
<core:ComponentContainer usage="resuse" manifest="true" async="true" />
</semantic:titleContent>
</mvc:View>

Routings


The xs-app.json files of the apps haven't changed. There is no route for the library added because the library will be accessed directly and not via the apps.

However the ui5.yaml files that define the server for the local run have been enhanced.
They define the entire isolated test environment for an app and therefore also need a route mapping for the static sources of the lib.
server:
customMiddleware:
- name: fiori-tools-servestatic
afterMiddleware: compression
configuration:
paths:
- path: /btpsamplesmultipleapps.btpsamplesmultipleappslib
src: "../lib/src"

Again to start the local test just run the start or start-local script in one of the package.json files.

Running the Deployed Apps


Deploying the App


Build and deploy the single MTA project in the same way as before.

Running Standalone


After the deployment the apps can be run standalone from their index.html via the managed approuter. Again you can find them in the SAP BTP cockpit on the HTML5 Applications page under your subaccount.

The index.html need to define a resource mapping for the library to tell UI5 where to find the resources. Unfortunately this can't be hardcoded here, because of the destination guid which is a part of the URL. The guid and the service name are the same as for the index.html but the library ID is at the end.


 

Since there is no way to specify this as a relative URL, there is a small piece of code to calculate it:
<script id="sap-ui-bootstrap"
src="https://ui5.sap.com/resources/sap-ui-cachebuster/sap-ui-core.js"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-resourceroots='{
"btp.samples.multiple.apps.app1": "./"
}'
data-sap-ui-libraries="sap.m"
data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
data-sap-ui-compatVersion="edge"
data-sap-ui-async="true"
data-sap-ui-preload="async"
data-sap-ui-frameOptions="trusted">
</script>
<script>
let parts = window.location.pathname.split('/');
let destinationGuid = (parts.length > 2) ? parts[1].split(".")[0] + "." : "";
sap.ui.loader.config({paths:{"btp/samples/multiple/apps/lib": `/${destinationGuid}btpsamplesmultipleapps.btpsamplesmultipleappslib`}});
</script>

The script also contains a condition to support the local run. Here the paths are also different, and a different relative path is needed.



Running in the Launchpad Service


To run the apps in the launchpad, synchronize the html5 provider in the launchpad configuration and configure the apps. Afterwards you can run the new apps in a similar way as before.
Here the platform will provide the URLs to access the apps and the library.


If you check the ui5AppInfo.json that is used to start the app you can find the additional dependencies for the library. The reuse component doesn't appear here, because it is embedded in the library and all paths can be derived from it.
{
"name": "btp.samples.multiple.apps.app2",
"url": "/b7f4982c-02d4-4c24-a4f6-5f23ff2f8aef.btpsamplesmultipleapps.btpsamplesmultipleappsapp2/~060222132517+0000~/",
"manifest": true,
"asyncHints": {
"libs": [
{
"name": "sap.m",
"lazy": false
},
{
"name": "btp.samples.multiple.apps.lib",
"url": {
"url": "/b7f4982c-02d4-4c24-a4f6-5f23ff2f8aef.btpsamplesmultipleapps.btpsamplesmultipleappslib/~060222132517+0000~/",
"final": true
},
"lazy": false
},
{
"name": "sap.f",
"lazy": false
},
{
"name": "sap.ui.fl",
"lazy": false
}
],
"components": []
},
"messages": [],
"version": "1.0.0"
}

Next Steps


Now you are ready to build multiple apps and move common parts of them into a reusable library.
However, everything is still contained in the same MTA project. In bigger projects, you might need to split this into smaller parts in order to achieve independent lifecycles and split responsibilities.
Please check out Part 3 of this blog for this.
37 Comments
0 Kudos
Hi all,

Part 3 has now been published as well.

Best regards
Matthias
peng_li01
Discoverer
0 Kudos

Hi Matthias,

How to configure the library in the local launchpad site?

Best Regards,

Arvin

0 Kudos
Hi Arvin,

thank you for the question.
I have enhanced the samples and added the missing files the the start-local scripts to run the local launchpad. The test/flpSandbox.html file also contains the resource mapping for the library. Since this is only used for testing from the workspace, the paths could be hardcoded here.

Best regards
Matthias
0 Kudos
Hi,
I have followed the steps and added the app on BTP cloud portal.The reusable UI is seen but its related CSS ,i18n and Odata services are going into SDK resource path and getting following error:

https://sapui5.hana.ondemand.com/1.100.0/resources/com/test/testapp/css/style.css

regards,
Asia
0 Kudos
Hi Asia,

where and how do you specify the URLs for these resources?
For paths in the manifest.json it is important to always use relative links. They must not contain a host name and must not have a leading /
If you calculate URLs in the source code, the final path has to be resolved relative to the app (see the mentioned sample for an image in part 1).

However in your case it seems like UI5 resolves a resource path based on an unknown namespace and therefore points to the UI5 dist layer resources.
Please verify the the sap.app/id in the manifest.json fits to the used module names. In your sample the id should be "com.test.testapp".

Best regards

Matthias
0 Kudos
Hi Matthias,

 

Its correct, com.test.testapp is app id.I am not specifying the hardcoded path.

 

regards,

Asia
0 Kudos
Hi Asia,

so where have you entered the URLs and what is the exact value?

Best regards
Matthias
0 Kudos
Hi Matthias,

I am not defining urls.

CSS ,i18 and datasource i defined in manifest.json.

Can i manually harcode my portal site url somewhere in manifest,mta.yaml to make it work?
Hi Asia,
what you enter in the manifest.json is also an URL, but you would provide a relative one.
So which value have to entered there?
Regards Matthias
0 Kudos
Hi Matthias,

i have not entered any url , just defined view,models, css,datasource,but when i am using reuse component those resourcepath is going into https:sapui5.hana.../sap/opu/sap/odata/...instead of portal site ..https:myportalsite/sap/opu/sap/odata...

regards,

Asia Shaikh
0 Kudos
Hi Matthias,

datasource,css,model is taking https:sapui5.hana../sap/odata/opu/sap/ztestservice instead of https://myportalsite/testservice.testapp/sap/odata/opu/sap/ztestservice

regards,

Asia
0 Kudos
I meant which values have you entered in the manifest?
0 Kudos
Please find below manifest entry:

 

{

    "_version": "1.32.0",

    "sap.app": {

      "id": "com.umusic.invoicecreditnote",

      "type": "application",

      "i18n": "i18n/i18n.properties",

      "applicationVersion": {

        "version": "0.0.1"

      },


      "title": "{{appTitle}}",

      "description": "{{appDescription}}",

      "dataSources": {

        "mainService": {

          "uri": "/sap/opu/odata/sap/Z_U3INVOICE_BND/",

          "type": "OData",

          "settings": {

            "odataVersion": "2.0",

            "localUri": "localService/metadata.xml"

          }

        },

        "testserv": {

          "uri": "/sap/opu/odata/sap/ZUNP_UI_ZSUPPLR_B/",

          "type": "OData",

          "settings": {

            "odataVersion": "2.0",

            "localUri": "localService/metadata.xml"

          }

        }

      },

      "crossNavigation": {

        "inbounds": {

          "com-umusic-invoicecreditnote-inbound": {

            "signature": {

              "parameters": {},

              "additionalParameters": "allowed"

            },

            "semanticObject": "so_invoicecreditnote",

            "action": "display",

            "title": "{{flpTitle}}",

            "subTitle": "{{flpSubtitle}}",

            "icon": ""

          }

        }

      }

    },

    "sap.ui": {

      "technology": "UI5",

      "icons": {

        "icon": "",

        "favIcon": "",

        "phone": "",

        "phone@2": "",

        "tablet": "",

        "tablet@2": ""

      },

      "deviceTypes": {

        "desktop": true,

        "tablet": true,

        "phone": true

      }

    },

    "sap.ui5": {

      "flexEnabled": false,

      "dependencies": {

        "minUI5Version": "1.97.2",

        "libs": {


          "sap.ui.core": {},


          "sap.m": {},


          "sap.ui.comp": {},


          "sap.ui.table": {},


          "sap.ui.unified": {},


          "sap.ui.layout": {


              "lazy": true


          },


          "sap.f": {}


      }

      },

      "contentDensities": {

        "compact": true,

        "cozy": true

      },

      "models": {

        "i18n": {

          "type": "sap.ui.model.resource.ResourceModel",

          "settings": {

            "bundleName": "com.umusic.invoicecreditnote.i18n.i18n"

          }

        },

        "": {

          "dataSource": "mainService",

          "preload": true,

          "settings": {

            "defaultBindingMode": "TwoWay",

            "defaultCountMode": "Inline",

            "refreshAfterChange": false

          }

        },

        "testservModel": {

          "dataSource":"testserv",

        "preload": true,

        "settings": {

          "defaultBindingMode": "TwoWay",

          "defaultCountMode": "Inline",

          "refreshAfterChange": false

        }

      }

      },

      "resources": {

        "css": [

          {

            "uri": "css/style.css"

          }

        ]

      },

      "routing": {

        "config": {

          "routerClass": "sap.m.routing.Router",

          "viewType": "XML",

          "async": true,

          "viewPath": "com.umusic.invoicecreditnote.view",

          "controlAggregation": "pages",

          "controlId": "Invapp",

          "clearControlAggregation": false

        },

        "routes": [

          {

            "name": "Route_DispInvoice",

            "pattern": "",

            "target": [

              "TargetDispInvoice"

            ]

          },

          {

            "name": "Routeinvoicecreditnote",

            "pattern": "{Belnr}",

            "target": [

              "Targetinvoicecreditnote"

            ]

          }

        ],

        "targets": {

          "TargetDispInvoice": {

            "viewType": "XML",

            "transition": "slide",

            "clearControlAggregation": false,

            "viewId": "DisplayInvoice",

            "viewName": "DisplayInvoice"

          },

          "Targetinvoicecreditnote": {

            "viewType": "XML",

            "transition": "slide",

            "clearControlAggregation": false,

            "viewId": "invoicecreditnote",

            "viewName": "invoicecreditnote"

          }

        }

      },

      "rootView": {

        "viewName": "com.umusic.invoicecreditnote.view.App",

        "type": "XML",

        "async": true

      }

    },

    "sap.cloud": {

      "public": true,

      "service": "invoicecreditnote.services"

    }

  }

0 Kudos
Hi Asia,
at least there is a problem with the OData URLs e.g.
/sap/opu/odata/sap/Z_U3INVOICE_BND/
This has a leading slash which only works on ABAP platform but on CF this must be removed i.e.
sap/opu/odata/sap/Z_U3INVOICE_BND/
Otherwise it will not resolve correctly.

The css and i18n urls and module names look correct and should work.
At least they do not match your first sample which tried to access
https://sapui5.hana.ondemand.com/1.100.0/resources/com/test/testapp/css/style.css
This must be caused by a different app.

Regards Matthias
lidia_sarasua
Explorer
0 Kudos
Hi Matthias,

Thank you very much for such detailed post.

This example contains all three "projects" (app1, app2 and library) within one single git repository and they are all built together within a single MTA to be deployed at once.

Would it be possible to achieve the same functionalities with the projects split in 3 different repositories? (one each)

And would it be possible to build and deploy them separately as well?

This would be very beneficial if  there are many apps and different teams working on them (e.g. if I only want to make changes in the library, it'd be good if I could just build the library alone and deploy it without all the other apps, same for the other individual apps)

Best regards,

Lidia
Hi Lidia,

please check out part 3 of the blog. This shows how to split into multiple MTAs which can be deployed independently.

My samples all reside in one single Github repository but this is a simplification I have done and not needed. Usually you would split each MTA project into an own Github repository.

Best regards
Matthias
jyotsna_singam
Explorer
0 Kudos

Hi Matthias,

Thank you for the wonderful blog! We have a scenario where we aren't using destination content module and Launchpad service. Our destination, xsuaa and required services are bound to standalone app router. Is destination content module mandatory for having resuable libraries? How does it work in case of standalone app router? Kindly, help with your inputs.

0 Kudos
Hi Jyotsna,

it depends on whether you are using the Portal service as well and are binding this to your app router in order to render a launchpad.
In this case the Portal service provides similar functionalities. The rules are quite similar in this case, but instead of service destinations you have to bind the html5 repo and xsuaa instances to your app router and the FLP content deployer. However this is outside the scope of this blog.

In case you are not using Portal at all, you are on your own.
In this case you have to calculate runtime URLs to bind your reuse libs to your apps on your own.

Best regards
Matthias
matheus_brasil
Explorer
0 Kudos
Hello matthias.schmalz ,

thank you for your blog. It is really helpful.

 

I would like to understand how we can reference the URL of the library when the UUID/GUID is generated dynamically in each of the environments that we will deploy.
      {
"name": "btp.samples.multiple.apps.lib",
"url": {
"url": "/b7f4982c-02d4-4c24-a4f6-5f23ff2f8aef.btpsamplesmultipleapps.btpsamplesmultipleappslib/~060222132517+0000~/",
"final": true
},
"lazy": false
}

 

I know if the MTA file is changed from INSTANCE to SUBACCOUNT the library will be deployed without the UUID/GUID but how it can impact if we change from a single tenancy to a multi-tenancy environment?

Hello Matheus,

the GUID is bound to the instance of the destination service that is created by the MTA. As long as the same instance is used the GUID will be stable.
The GUID only changes if the instance changes e.g. if it is deleted and recreated or if you deploy to another environment (landscape, sub account, ...).
When switching to multi-tenancy this should not affect the GUID. Only the hostname would change because the tenant subdomain would be added.

Anyway it is not recommended to hardcode it. Always calculate it dynamically as shown in the code samples above or rely on the platform to inject it.

Best regards
Matthias
matheus_brasil
Explorer
0 Kudos
Hello Matthias!
Thank you for your reply.

The point is I'm trying to use the resourceRoots to assign the library to my main app but if I use the path without the GUID it does not work.

 
        "resourceRoots": {
"btp.samples.multiple.apps.lib": "/btpsamplesmultipleapps.btpsamplemultipleappslib/"
}

 

Since I'm working with different apps with different MTA, each app deployment creates a new GUID to be part of the path. The logic you provided to get the GUID just works when the apps share the same GUID. I wonder if there is a better way to assign the library using the resourceRoot than the following one:
        "resourceRoots": {
"btp.samples.multiple.apps.lib": "/b7f4982c-02d4-4c24-a4f6-5f23ff2f8aef.btpsamplesmultipleapps.btpsamplesmultipleappslib/"
}

 

Or are the resourceRoots not necessary for apps that run inside of the Launchpad?

 

 

 

Thank you for your time,

BR,
Matheus Brasil.
Hi Matheus,

The resourceRoots in the manifest.json are an alternative way, but they are static and you can't calculate the GUIDs here. Therefore it won't work this way.

Please read the blog post above. It explains how the platform injects the resource roots automatically (Running in the Launchpad Service) and how to calculate it in your index.html (Running Standalone).

For your scenario with multiple MTAs please refer to part 3 of the blog. It explains how to split projects with shared libraries into multiple MTAs. In the end you will have just one instance of destination service with one common GUID.

Best regards
Matthias
matheus_brasil
Explorer
0 Kudos
Thank you matthias.schmalz !
I'll follow your guidance!

BR,

Matheus Brasil.
0 Kudos
Hi Matthias,

I have pulled the repo and copied the exact same commands that you mentioned.

NPM install runs fine, however when I run the npm run build:mta command I get the following error :

INFO executing the "make -f Makefile_20221220104243.mta p=cf mtar=archive strict=true mode=" command...Error: could not build the MTA project: could not execute the "make -f Makefile_20221220104243.mta p=cf mtar=archive strict=true mode=" command: exec: "make": executable file not found in %PATH%

I have not changed anything in the folder structure, and I am definitely logged in to the cloud foundry CLI.

Any help would be highly appreciated as I would like to adapt this project to my needs.

Kind regards,

Zelu

 
0 Kudos
Hi Zelu,

I have found that the MTA Builder is based on the Linux make tool.
So it runs best in a Linux environment and also in Business Application Studio (where I tested it).

However it should be possible to run it on Windows as well. You just need a way to have make available.
Some proposals how to get "make" on Windows can be found here:
https://stackoverflow.com/questions/32127524/how-to-install-and-use-make-in-windows

Best regards
Matthias

 
0 Kudos
Thanks for the quick response Matthias.

 

I decided to make use of BAS instead. The build command works fine, however the deploy command fails with the following error:

 

user: btp-samples-multiple-apps $ npm run deploy

> multiple.apps.mta@0.0.1 deploy
> fiori cfDeploy

sh: 1: fiori: not found

 

Do you perhaps know how this can be fixed?

Regards,

Zelu
0 Kudos
Hi Zulu,

thank you for the hint.
I had once installed the @sap/ux-ui5-tooling globally. Therefore the fiori command is always available.
You can add "@sap/ux-ui5-tooling": "^1.8.4" to the "devDependencies" and do an npm install, then it should work.

Best regards
Matthias
0 Kudos
Hi Matthias,

I have been able to get the library working well.

However I have run into a case where I get a 404 error when trying to access the odata service of any of the apps.

The applications have been used in normal abap deployments and neo environments, so I believe there should be no change in the manifest.js, however I am not sure if I am referencing the destinations correctly in the mta.yaml and the xs-app.json.

Is there any chance we could possibly set up a call for this? I would appreciate that very much.

Kind regards,

Zelu
0 Kudos
Hi Zelu,

the OData URLs in ABAP and in CF work differently which makes them incompatible. The same URL in the manifest.json won't work in both environments.

In ABAP the OData services are also relative to the server root under /sap/opu/odata (leading /).
In CF the app routes the OData service and the URL is relative to the app e.g. sap/opu/odata (no leading /).
In Neo it is the same, but the Web IDE projects had a build step which patched these URLs to make them compatible.

So for a CF deployment please ensure to have no leading / for the OData service URLs.

Best regards
Matthias
raffi1
Participant
0 Kudos
Hi altgether,

 

thank you very much matthias.schmalz for this detailed blog. It very much helps to understand the concept of the reuse libraries.

 

At the moment I am configuring this scenario in work zone. There I am using a standard reusable library (HCMFAB_COMMON). I got this deployed to CF besides the other executable HTML5-apps in the subaccount.

But now the executable apps try to read the files of the library (e.g. library.js) from sap standard sapui5 website: ModuleError: failed to load 'hcm/fab/lib/common/library.js' from https://sapui5.hana.ondemand.com/1.120.4/resources/hcm/fab/lib/common/library.js: 404 - Not Found

 

So there seems to be a routing problem. Am I correct that I have to edit the index.html of the executable HTML5 app, that consumes the library HCMFAB_COMMON? Or simply asked: How can I get the executable apps to run with the deployed library in the same subaccount?

 

thanks in advance and best regards

Christian
0 Kudos
Hi Christian,

yes exactly, when you run your app standalone and not inside the launchpad, you have to provide the resource mappings for the required library yourself via the index.html.
Please check the above sample, it shows how to configure the resource mappings.

Best regards
Matthias
raffi1
Participant
0 Kudos

Hi Matthias,

 

thanks for the quick response. I'm not sure what is the correct meaning: I start the apps through applications tab in the Work Zone starting page with clicking on the respecting tile. So is this "standalone"?

 

Nevertheless I added your example coding in the index.html of the executable app, but it still tries to search on the sapui5 website. First call that fails is: failed to load 'https://sapui5.hana.ondemand.com/1.120.4/resources/hcm/fab/lib/common/library-preload.json': Not Found -

 

Maybe my paths are not correct. But does it then change to the sapui5-website path if my given paths are wrong? I would expect a url that starts with (im my case) https://dev-digital-workplace-. where then something cannot be found if my paths are wrong. At least this is the case for files, that are missing in the executable app.

 

I added following script-part. Is this basically correct (I think I have to play a bit with the path/application name; application name I used the one from subaccount HTML5-apps)

	<script>
let parts = window.location.pathname.split('/');
let destinationGuid = (parts.length > 2) ? parts[1].split(".")[0] + "." : "";
sap.ui.loader.config({paths:{"hcm/fab/common": `/${destinationGuid}hcmfablibcommon.hcmfablibcommon`}});
</script>

 

best regards

Christian

0 Kudos
Hi Christian,

that rather sound like running in the launchpad. In that case your index.html won't be used.
Please check the documentation about that scenario above. Especially check your network log if the ui5AppInfo.json is fetched and have a look at the content:

Does it mention your lib? Is there an error shown?

If your lib is missing in the info, you have not declared the dependency in your manifest.
If it appears but shows an error, the location of the reuse lib is not known. In that case please ensure that the dependency matches the sap.app/id of the manifest of the lib. If it is on another app-host, please ensure that there is a destination created for it.

Best regards
Matthias
0 Kudos
Just to add: If the reuse lib is on another app-host, please read through part 3 of this blog.
raffi1
Participant
0 Kudos

Hi Matthias,

 

the executable app and the library are in the same HTML5 repo in the same subaccount. The app id is correct (I did not change it, cause it is standard; I added the lib in BAS per standard command, not manually). In BAS the bank details app is running without problems, so connection to the lib should be correct.

The ui5appinfo.json gives me the error which can be seen in console in developer tools in the browser as well:

    "name": "hcm.fab.mybankdetails",
"url": "/24d2cfdc-63be-4eda-91dd-217e1797d8c6.hcmfabmybankdetails.hcmfabmybankdetails/~120124130017+0000~/",
"manifest": true,
"asyncHints": {
"libs": [
{
"name": "sap.ui.layout",
"lazy": false
},
{
"name": "hcm.fab.lib.common",
"lazy": false
},
{
"name": "sap.m",
"lazy": false
},
{
"name": "sap.ushell",
"lazy": false
},
{
"name": "sap.ui.fl",
"lazy": false
}
],
"components": []
},
"messages": [
{
"severity": "error",
"text": "App 'hcm.fab.mybankdetails' has errors and will possibly not run properly"
},
{
"severity": "error",
"text": "Error in application dependency 'hcm.fab.lib.common': No descriptor was found"
}
],
"version": "1.2.30"
}

 

Descriptor not found is clear to me, cause it still tries to find the HCMFAB_COMMON-lib files on sapui5.hana.ondemand.com. I still can play around a bit with the folder structure in BAS in the lib. At the moment I only added the src-folder (with the respecting content) like you described above to be able to build/zip the whole thing and deploy it to CF. Besides that I did not change the original structure, so I only copied the respecting content to src-folder. I did not cut anything out of the original HCMFAB_COMMON-structure.

We are using Work Zone advanced edition, if this is important. Do you have another idea, what I can check? The lib itself is deployed the same way like the other executable apps. When I have a look in the subaccount and the content manager of the Work Zone, the lib seems to be a normal application. I hope this is technically correct, since it is not executable.

 

best regards

Christian

0 Kudos
Hi Christian,

what is the folder structure of your deployed library application?
Is the manifest.json that has sap.app/id hcm.fab.lib.common in the root folder?

Best regards
Matthias
0 Kudos
Hi Christian,

I have found you site instance in our database, it looks like you have not deployed the app and the library to the same app-host. They are located on different app-hosts and are connected via different destination service instances. This will not work.

Please read through part 3 of the block to understand how to connect libraries from another app-host.

Best regards
Matthias