Skip to Content

The previous part of the series briefly explained how to implement a Custom Control library for SAPUI5 and then deploy it to the HCP to make it possible using the library by your other UI5 apps inside the Web IDE.

Deployment to on-premise SAP ABAP Repository

In Part 1 I unequivocally stated that all the library files should be put into the project root folder. However Web IDE works equally fine with the folder hierarchy according to the library name space. So, when first trying to load deployed library within Web IDE I created the name space hierarchy starting with src folder and thus the new-app.json file (or more precisely the entry in “routes” array) looked like this:

{
	"path": "/webapp/resources/",
	"target": {
		"type": "application",
		"name": "mycustomlib", 
		"entryPath": "/src/my/custom/control"
	},
	"description": "Custom control library"
}

But the next question is: how we put the library onto SAP ABAP server?

As you might know SAP by default stores all the SAPUI5 library files in the MIME repository accessible from SE80. If you select uppermost long button “MIME repository” and then select in the tree-pane this folder path “/SAP/PUBLIC/BC/UI5/LIBRARIES/VER” you should see something like this:

And under each version folder (e.g. “1.38”) you can find all the resources of SAPUI5 library.

My first (quite naive) plan was to mimic the similar structure and place my custom library to the same MIME repository along with other SAPUI5 resources. All the tries failed with error 404.

And then I decided to try the similarity principle: if the Web IDE managed to load library from deployed HCP application, then probably SAP NW server should do the same with library deployed as BSP application. And so it goes. The library with accurately placed folder hierarchy (see above) was deployed to the SAP ABAP Repository under the name “zcustlib“… and again error 404!

However looking into the network log in Chrome development tools I have noticed that the faulty request url which tried to load library control file “my.custom.control.ProductRating.js” looks like this: http://…/sap/bc/ui5_ui5/sap/zcustlib/~C2BA8580F0AD68211B5F48EF79A345B7~5/ProductRating.js.

Just notice that SAP NW server successfully mapped the library name space “my.custom.control” into the deployed application name “zcustlib“. Hope? Yes.

It appears that for one or another reason SAP NW UI5 runtime just ignores the library namespace folder hierarchy and always tries to load library files from the root folder of the deployed BSP application. Probably there is some other configuration file to overcome this, for example UI5RepositoryPathMapping.xml, but I could not find a proper documentation on this and I left it as it is.

Next time I put all the library files into the project root folder and remapped the corresponding entry in the neo-app.json file as described in Part 1. After that all apps started working both in Web IDE and in SAP ABAP Repository.

Theming and CSS

If your library has its own CSS styles then according to the guide you have to create library.css file for each supported theme. To do this you create themes folder within the folder where your library js files reside. Then inside themes folder you create subfolder for each supported theme and put there the corresponding library.css file and also “base” folder which should contain default styles, as on the following figure:

This should work in theory, while in practice the Web IDE managed to load control js files but made no attempt to load library.css – there were no trace of such action in the Network log.

After another set of try-and-fail attempts I finally figured out how to make Web IDE load the library CSS file: add an entry into dependencies in the manifest.json file of the app project. That’s the place where you normally enter other library dependencies such as sap.ui.core or sap.m. For our custom library the entry should look like this:

	"sap.ui5": {
	...
	"dependencies": {
		"minUI5Version": "1.36.0",
		"libs": {
			"sap.ui.core": {
				"minVersion": "1.36.0"
			},
			"sap.m": {
				"minVersion": "1.36.0"
			},
			"my.custom.control": {
			}
		}
	},
...

With this setup the app runs fine from the Web IDE, however after I attempted to deploy it to SAP ABAP Repository it refused to start with 404 error. It appears that if you put the library into the manifest.json dependency array SAP NW server always tries to load library-preload.js file from library root folder – this is a minified file containing all the library modules. Unlike an ordinary UI5 app project (where Web IDE creates Component-preload.js file) it does not do this for library project.

Another round of source code investigation and debugging finally produced a workaround: to add library.js file as a dependency to each of library controls. After a minor dependency part amendment our ProductRating.js file header should look like this:

	
sap.ui.define([
	"sap/ui/core/Control",
	"sap/m/RatingIndicator",
	"sap/m/Label",
	"sap/m/Button",
	"./library" // Load library.js as a dependency
], function (Control, RatingIndicator, Label, Button) {
...
});

As you can see we don’t need a parameter for the library.js dependency because function sap.ui.define already does what we need: it executes the loaded module to obtain an object instance. In case of library.js module one thing it has to do is calling Core function initLibrary, and otherwise it is just a common executable JavaScript module. Thus, we can add a call to Core function includeLibraryTheme and the resulting library.js file would look as follows:

/* global my:true */

sap.ui.define([
		"jquery.sap.global",
		"sap/ui/core/library"
	], // library dependency
	function(jQuery) {

		"use strict";

		sap.ui.getCore().includeLibraryTheme("my.custom.control");
	
		sap.ui.getCore().initLibrary({
			name: "my.custom.control",
			version: "1.0.0",
			dependencies: ["sap.ui.core"],
			types: [],
			interfaces: [],
			controls: [
				"my.custom.control.ProductRating"
			],
			elements: []
		});

		return my.custom.control;

	}, /* bExport= */ false);

Bottom line

So, let’s summarise all the findings to produce a workable setup for shareable custom control library:

  • Create a separate project for the library in the Web IDE and put all the library files into the project root folder
  • Make sure you marked the type of the project as “library” not “application” in the manifest.json file (see Part 1)
  • Fill the “id” value of “sap.app” part of the manifest.json file with the library name space (see Part 1)
  • If the library has CSS rules create proper folder hierarchy starting with themes folder and place the library.css file into each supported theme folder
  • If the library has CSS rules add includeLibraryTheme Core function call into the library.js file
  • Add the library to the dependency list of each library control files
  • Deploy the library project both to HCP and SAP ABAP Repository
  • In the app project which uses the library amend the neo-app.json file as suggested in the Part 1
  • Don’t add the library to the manifest.json dependency of the app, otherwise SAP NW server can refuse to load the library
  • Have fun

Further steps

As you see this is quite a minimal setup allowing you to use your own custom control library both within Web IDE and on SAP ABAP Repository. At the same time there are still tasks to make it a kind of state-of-the-art solution:

  1. It is unclear if it is possible at all to make a custom library shareable for more than one HCP account (just like SAPUI5)
  2. At this point Web IDE does not “build” the library project – it would be good to have a minified version of the library files together with library-preload.js file
  3. As far as I can understand UI Theme designer currently does not support generation of library specific css files. UI Theme designer produces the theme which is assumed to replace the whole application theme and thus affects all the controls

For points 2 and 3 there is a solution though: Grunt utility.  OpenUI5 itself uses Grunt for producing builds and there is a github repository containing probably most required packages to produce minified version of the library and CSS files. However you should be aware that this is quite a low level tool based on Node.js server side JavaScript run-time.

UPDATE (22-Feb-2017): For points 2 and 3 please see Robin’s excellent blog.

To report this post you need to login first.

11 Comments

You must be Logged on to comment or reply to a post.

  1. Pierre DOMINIQUE

    Thanks again for sharing this Sergey. I’m currently looking into using Grunt to build the custom library and deploy it to HCP and or an ABAP AS. I’ll post on SCN if I find a way to do it.

    (1) 
  2. Helmut Tammen

    Hi Sergey,
    thank you for sharing your findings. I was able to reproduce and understand part 1 of this blog series. Currently I don’t have access to an ABAP system so I cannot reproduce part 2.

    But I don’t understand why NW server maps “my.custom.control.ProductRating.js” to “http://…/sap/bc/ui5_ui5/sap/zcustlib/~C2BA8580F0AD68211B5F48EF79A345B7~5/ProductRating.js“.

    You didn’t define this mapping from namespace to zcustlib in a descriptor file like you similarly did on HCP in nep-app.json. Does the NW server scan the manifest.json during deployment and save the information in a table where it looks up unresolved namespaces at runtime or is there another reason for using zcustlib I don’t see?

    (0) 
    1. Sergei Korolev Post author

      Hi Helmut,

      It appears that this is done without specific configuration in manifest. Unfortunately by this instance I have no clue of the underlying mechanism. It should be hidden inside NW logic of converting project specific url into NW specific one. As you might remember when you deploy UI5 app to SAP ABAP it requires a BSP name which is then stored in .project.json (section “deploy”) file in Web IDE, and apparently NW uses BSP name with additional GUID part to map to the root folder.

      (0) 
      1. Sergei Korolev Post author

        Just to add: in manifest file of the library project (section “sap.app”) you specify an id of the library, which normally is its name space (in our case “my.custom.control”), then in .project.json (which stores the Web IDE project settings) you specify the BSP name for deploying to SAP ABAP server, and most likely when deployment proceeds the SAP NW stores some map between BSP name and the project ID and that’s how it can decipher library file name and convert it to the SAP NW specific url.

        (0) 
  3. Robin Panneels

    Hello Helmut and Sergey,

    What you also can do is add the control library “my.custom.control” to the dependencies (libs) of sap.ui5 in your manifest of your UI5 application. But you need to preload your control library, because it seems that the framework searches for a library-preload.json (or library-preload.js from version 1.40), without a fallback to the basic library.js file. SO the first time you would open your application you will receive the “Could not open app.”-error. But the second time you try to open your application it would open it successfully…

    So that first error you can solve by using the openui5_preload grunt task for the library. Next thing that I found that can block things is that you really, really need to have a .library file in your dist folder.

    Normally this way it should work, or at least is working here in my system. Maybe I need to create a blog covering these last steps?

    Robin

    (1) 
    1. Sergei Korolev Post author

      Hi Robin,

      Yes, it would be really great if you could post a blog on GRUNTing a custom library. Actually the best way would be to have some support for developing libraries in SAP Web IDE, but having a blog on GRUNT would also be a good step.

      Thank you.

      (0) 

Leave a Reply