SAPUI5 How To: Create a custom library and how to use the JS files in other apps
Hello guys
We have a few SAPUI5 apps and they share common code, so I will show you how to create a library and how to access it in your other apps.
Basically the Library is just a SAPUI5 app or normal BSP. We create all our files that we want to reuse and deploy them to the APAB server/ Gateway (as we would any other SAPUI5 app).
So let’s start.
LibraryApp
We create the project, and inside it we create a JS file that looks like this:
sap.ui.define([
"sap/ui/base/Object"
], function (Object) {
"use strict";
return Object.extend("libraryApp.utilities.LoggedOnUser", {
getLoggedOnUser : function () {
console.log("Inside LoggedOnUser.getLoggedOnUser");
// your code here
return "Antonette Venter" ;
}
});
});
Now we want to reuse this function in all of our other apps:
ConsumerApp
First we have to register the path to our library app to be able to access the files inside it:
Index
<!-- Init -->
<script>
// Register LibraryApp (to be able to access the functions in Component sap.ui.define)
jQuery.sap.registerModulePath("libraryApp.utilities", "../zlibraryApp/utilities");
// Load Component
sap.ui.getCore().attachInit(function () {
sap.ui.require([
"sap/m/Shell",
"sap/ui/core/ComponentContainer"
], function (Shell, ComponentContainer) {
new Shell({
app: new ComponentContainer({
name: "consumerApp",
})
}).placeAt("content");
});
});
</script>
Once registered, we will be able to access the files via Component:
Component
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/json/JSONModel",
"libraryApp/utilities/LoggedOnUser" // Here we define the JS files
], function (UIComponent, JSONModel, LoggedOnUserJS) { // . . . and here
"use strict";
return UIComponent.extend("consumerApp.Component", {
id: "consumerAppId",
metadata : {
manifest: "json"
},
/**
* The component is initialized by UI5 automatically during the startup of the app (sap.ui.getCore().attachInit()) and calls the init method once.
* @public
* @override
*/
init : function () {
//<!-------- Component and Router apply init ----------->
console.log("Component Initialize");
// Call the init function of the parent
console.log("Component - before prototype.init.apply(this, arguments)");
UIComponent.prototype.init.apply(this, arguments);
console.log("Component - after prototype.init.apply(this, arguments)");
// Initialize Router
console.log("Component - Router Initialize");
this.getRouter().initialize();
//<!-------- Using the JS functions from libraryApp ----------->
this.getUser = new LoggedOnUserJS(); // Create new instance. Like new sap.m.Button
// And now we can call the functons inside the JS file as we please :)
console.log(this.getUser.getLoggedOnUser());
},
});
});
And there you go! 🙂
Please don’t be shy to comment if you have also found other ways to do the same thing.
To see how to reuse controls, check out this blog: SAPUI5 How To: Reuse parts of a SAPUI5 application in other/multiple SAPUI5 applications
Regards
Antonette
Nice Blog!!!
Just to add one point, the library registration path can be done in manifest.json under sap.ui5>resourceRoots.
The following is the answer from Wolf Gregor when I posted the question in OpenUI5 Slack:
Thanks Hsia-Liang
I've tested it and it works. However when I read more about it I found this on sapui5.hana.ondemand.com
"Map of URL locations keyed by a resource name prefix; only relative paths inside the component are allowed and no ".." characters
This attribute is intended for actual sub-packages of the component only, meaning that it must not be used for the component namespace itself. The defined resource roots will be registered after the component controller is loaded and do not affect the modules being declared as dependencies in the component controller."
We are using external libraries (".."), am I understanding this correct? Is it not really supposed to be used in this way inside Manifest?
Regards
Antonette
Antonette: the description sounds confusing. If is a sub-packages of the components then we can directly access without declaring in the resource root. Agree that it have to relative but doesn't make sense to me if this is intended only for subpackages.
Hi Antonette,
I'm wondering what happens when the custom library needs to be used in multiple controllers within the same application.
Would a new LoggedOnUserJS need to be instantiated in each controller where it's used? And if so, what are the performance implications of that?
Ideally with util libraries it would be best if they can be statically imported or instantiated only once.