Skip to Content
Author's profile photo Saurabh Sharma

Creating a reusable library in SAP UI5

Re-usability in software development is the key for rapid development by making sure you do not start from scratch every time and consistency across the suite.

We had invested considerable time in our UI5 Applications and we wanted to re use some of the artifacts. But to my surprise there was no straight way to create a reusable library(something like sap.m) in WebIDE which is the preferred way to develop UI5 apps. I was finally able to crate a library and use it in multiple apps. When I started my analysis I found this blog and was really excited but unfortunately the option is not available in our version of WebIDE  –

https://blogs.sap.com/2017/12/18/create-link-a-custom-fiori-library-reusable-component-using-web-ide12/

This blog provides a summary of the steps that I followed by doing online research and studying and debugging the standard SAP libraries.

  • Create a SAP UI5 Application using Web IDE template –

  • Give the project a name and select none in the view and press Finish –

  • Delete the controller and the view folders which were automatically generated and create a new file library.js in the webapp folder as below(This is just a skeleton to make sure it is treated like a library by SAP server) –
sap.ui.define([
	"sap/ui/core/Core",
	"sap/ui/core/library"
],function(Core, Library) {
	"use strict";

	sap.ui.getCore().initLibrary({
		name : "com.in.reuse",
		noLibraryCSS: true,
		dependencies : [
			"sap.ui.core"
		],
		types: [],
		interfaces: [],
		controls: [],
		elements: [],
		version: "1.0.0"
	});

	return com.in.reuse;

}, /* bExport= */ false);
  • Right click on the app and Deploy as a new app on SAP Frontend Server.

Now the fun Part –

If you check your WebIDE application there will be a new folder created called ‘dist’. This is  used to deploy the app on ABAP front-end server. If we expand the folder structure there will be a new file created called Component-preload.js. This is what we are interested in.

 

Open your app (deployed as BSP component) in the ABAP Frontend server. The folder structure will look something like this –

Notice I have a javascript file initMap.js which I would like to reuse from the different application.

 

  • Open the UIRepositoryPathMapping.xml. Find the Mapping entry for Component-preload.js and replace the path with library-preload.js. Save and activate the file. Activate the application as well (as it does some sort of regeneration). Now recalculate the SAPUI5 application index using the report /UI5/APP_INDEX_CALCULATE(For more details refer to SAP help documentation).

 

On the consuming application

 

  • Open the consuming application and declare it as a dependency in manifest –

 

Now whenever you need the libraries just do a jQuery.sap.require and the javascript files will load up.

jQuery.sap.require("com/in/reuse/lib/initMap");

How to check if things worked 

  • Open the developer tools(on chrome F12) and place a break point at a source code line right after the “require” statement so that the processing stops.

 

  • Go to the Network tab and filter on library. We will be able to find the library-preload.js file here  –

  • Now go to the Sources tab. We can see that our library has a separate folder and the JavaScript file has loaded as well –

All done and dusted. You can now just plug and play your own Ui5 libraries in any UI5 app deployed on launchpad on Front-end server. You can use it for moving 3rd party APIs to SAP application server (to avoid CORs) or create a library of custom controls or any other use case that might be applicable in your environment.

 

Regards, Saurabh

Assigned Tags

      10 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Christian Schoeneberg
      Christian Schoeneberg

      Hello, Saurabh,

      very cool blog. That's exactly what we've wanted for a long time. We have tried to restore your example, but we have always failed.

      We get this error every time:

      failed to load 'com/in/reuse/library-preload' (failed to load 'com/in/reuse/library-preload.js' from ../../../../../resources/com/in/reuse/library-preload.js: 404 - Not Found)

      I'd say we took each step separately, as you described it.

      We already tried to set a new route in the neo-app. json, unfortunately without success.
      Can you give us a clue what we might have forgotten?

      Best regards
      Christian

      Author's profile photo Saurabh Sharma
      Saurabh Sharma
      Blog Post Author

      Hey Christian,

      I can think of 2 things looking at the error you are getting -

      • Both the library and consuming app were deployed in the same ABAP package in my case. Maybe you need to do something additional if it is in a different package.
      • Did you make the change in UIRepositoryPathMapping.xml. By default it will have Component-preload.js as in manifest we have specified that it is a "application" and not a "library".

      Regards,

      Saurabh

      Author's profile photo Christian Schoeneberg
      Christian Schoeneberg

      First of all, thank you for your help.

      • the library and the consuming application are included in my $TMP package for testing. Could that be a problem?
      • Yes, I made the change in UIRepositoryPathMapping. xml and then I used the report /UI5/APP_INDEX_CALCULATE.
      • I haven't changed the application type in manifest. json, it's still "application" - right?

      Would you like to tell me your query path to library. js? Our Fiori Launchpad uses this query path to find the library:

      Request URL:
      /sap/bc/bc/ui5_ui5/ui5/ui2/ushell/resources/~2018021414141212123700~/com/in/reuse/library. js

      However, this doesn't look right. In your example, the library app is not part of ui2/ushell root, but I don't know how to change it.

       

      Regards,

      Christian

      Author's profile photo Saurabh Sharma
      Saurabh Sharma
      Blog Post Author

      Hey Christian,

      Sorry for late reply.

      I am not sure about the local development. Maybe try tagging it to a Transport request and a proper package(Do not release your tasks, later you can revert it back and not take it to next environment).

      Even I did not change the application type. It was just to tell you why I made the change in UIRepositoryPathMapping.xml Since you have already changed it, that should be all right.

      As far as I know ui2/ushell root is used when the app is deployed on Fiori Launchpad. In my case the library was just deployed on ABAP Frontend server(using the deploy option on WebIDE) but not on Fiori launchpad. Thinking logically, I want to call my library from another app and not use it as a standalone app so no launchpad.

      Best regards,

      Saurabh Sharma

      Author's profile photo Christian Schoeneberg
      Christian Schoeneberg

       

      Hi Saurabh,

       

      the reuse library project and the consumable app are part of a Transport request. It is required for our deployment process. In the WebIDE we use the following method to deploy:

      • Deploy to SAPUI5 ABAP Repository

      This Frontend server is also the Fiori Launchpad.

       

      We use the SAP Web IDE Full-Stack Version with an NetWeaver Frontend Server 752 and SAPUI5 1.52.6, if this helps.

       

      Best regards,

      Christian

      Author's profile photo Saurabh Sharma
      Saurabh Sharma
      Blog Post Author

      Hi Christian,

      We are in-fact on a NetWeaver version lower than yours as upgrades were stopped due to pending go live. So that should not be a problem unless the higher version is more restrictive. The only difference that i can see is that you are using Web IDE full stack version and I am not. Give it a try with the normal one.

      If you are still not able to figure it out IM me on Linkedin (@saurabhsharma82) and we can have a chat.

      Best regards,

      Saurabh Sharma

      Author's profile photo Prerana CV
      Prerana CV

      Hi Christian,

       

      I had the same error. I was able to resolve it by adding resourceRoots in manifest.json file and now I'm able to use this custom control in other apps. Try making this change in your manifest.json file. For example,

       

      I did some research and found this link to be helpful - https://stackoverflow.com/questions/38593261/one-app-with-multiple-component-js-how-to-load-shared-modules

      Also check out these additional blogs -

      https://blogs.sap.com/2017/04/05/sapui5-how-to-reuse-parts-of-a-sapui5-application-in-othermultiple-sapui5-applications/

      https://blogs.sap.com/2018/01/15/step-by-step-procedure-to-create-sapui5-library-with-custom-controls-and-consume-the-library-into-sapui5-applications/

      https://blogs.sap.com/2017/10/23/demystifying-the-art-of-component-reuse-in-sapui5/?preview_id=559009

      They follow slightly different approach but they have the similar concepts.

      Good luck !

       

      Thanks,

      Prerana

       

      Author's profile photo Michal Keidar
      Michal Keidar

      This is now supported in SAP Web IDE 🙂

      https://blogs.sap.com/2018/08/16/how-sap-web-ide-supports-development-of-sap-fiori-reusable-libraries/

      Author's profile photo Saurabh Sharma
      Saurabh Sharma
      Blog Post Author

      Aah Finally... Thanks for sharing.

      Author's profile photo Laszlo Kajan
      Laszlo Kajan

      The following is enough for a custom SAPUI5 library template:

      1. webapp/library.js:
        sap.ui.define([
        	"sap/ui/core/Core",
        	// manifest.json "sap.ui5"."dependencies"."libs" dependencies (append "/library", e.g. "sap.ui.core" => "sap/ui/core/library")
        	"sap/ui/core/library"
        ], function(Core) {
        	"use strict";
        
        	sap.ui.getCore().initLibrary({
        		name: "com.*****.eihb.ict.lib",
        		version: "1.0.1",
        		noLibraryCSS: true,
        		dependencies: [
        			"sap.ui.core"
        		],
        		types: [],
        		interfaces: [],
        		controls: [],
        		elements: [],
        		extensions: []
        	});
        
        	return com.*****.eihb.ict.lib;
        
        }, /* bExport= */ false);

         

      2. webapp/manifest.json:
        {
        	"_version": "1.9.0",
        	"sap.app": {
        		"id": "com.*****.eihb.ict.lib",
        		"type": "library",
        		"embeds": [],
        		"applicationVersion": {
        			"version": "1.0.1"
        		},
        		"title": "com.*****.eihb.ict.lib",
        		"description": "com.*****.eihb.ict.lib",
        		"offline": true
        	},
        	"sap.ui": {
        		"technology": "UI5",
        		"supportedThemes": ["base", "sap_hcb"]
        	},
        	"sap.ui5": {
        		"dependencies": {
        			"minUI5Version": "1.30",
        			"libs": {
        				"sap.ui.core": {
        					"minVersion": "1.30.0"
        				}
        			}
        		},
        		"library": {
        			"i18n": "i18n/i18n.properties",
        			"content": {
        				"controls": []
        			}
        		}
        	}
        }

      In this case, when built with the WebIDE or grunt openui5_preload –

      		openui5_preload: {
      			library: {
      				options: {
      					resources: {
      						cwd: '<%= dir.app %>', // path to app root folder
      						prefix: 'com.*****.eihb.ict.lib', // namespace prefix (in case the namespace is not already in folder structure like sap/ui/core/**)
      						src: [
      							'**/*.js',
      							'**/*.fragment.html',
      							'**/*.fragment.json',
      							'**/*.fragment.xml',
      							'**/*.properties',
      							'**/*.view.html',
      							'**/*.view.json',
      							'**/*.view.xml',
      							'!**/*-preload.js',
      							'!localService/**',
      							'!test/**',
      							'test/launchers/**'
      						]
      					},
      					dest: '<%= dir.dist %>',	// destination for the Component-preload.js file
      					compatVersion: '1.44'		// https://github.com/SAP/grunt-openui5/issues/66:
      									//	UI5 version below 1.54, which isn't compatible with the new bundle format that has been added with #65 and released with 0.13.0
      				},
      				libraries: true
      			}
      		},

      – and deployed to the ABAP gateway, library-preload.js is found. E.g.:

      when the app that depends on the library has:

      • manifest.json “sap.ui5″.”dependencies”.”libs”: {“com.*****.eihb.ict.lib”: {}, … }

      See also: