Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
sergey_korolev
Active Contributor
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 panneels.robin excellent blog.
12 Comments
Labels in this area