Integrate a UI5 library in a UI5 app using TypeScript
When building UI5 apps you will need to develop a custom UI5 control sooner or later. Doing this also requires (or at least it is recommended to do so) to bundle those UI5 controls in a library. With TypeScript support for UI5 you do not only develop UI5 apps in TypeScript but most likely also UI5 Controls and libraries. For kickstarting your UI5 library and UI5 control you can use the TypeScript Library generator: URL to generator: https://blogs.sap.com/2022/10/11/ui5-library-typescript-generator/
Generating the UI5 Library in TypeScript is one thing, you also want to develop and run your TypeScript app with that TypeScript Library, you want to have autocompletion for your controls, you want to have syntax check and any other TypeScript feature.
Peter Muessig , Andreas Kunz , Volker Buzek and myself worked on a demo in the following GitHub repository how this can be achieved for a mono-repository: https://github.com/ui5-community/hacking-away-sampleapp
Nevertheless, we do not always build UI5 apps as a mono-repository. At many customers, we develop apps separately and often have one or more libraries with all the customer controls. In this case, many apps will consume one or more libraries. Setting up a mono-repo every time when developing an app would be a lot of effort.
In this blog post I would like to share an approach how to run your TypeScript app and library together in your IDE. This means you’ll always need to have the library in your IDE. (simply by pulling from GIT)
Generate a new UI5 app in TypeScript using this generator:
More details on how to run a TS generator: https://blogs.sap.com/2022/02/25/new-ui5-typescript-generator-flexible-column-layout/
Answer all the questions:
Next generate a UI5 TypeScript library in the same folder as described in the following blog post: https://blogs.sap.com/2022/10/11/ui5-library-typescript-generator/
Answer all the questions:
In the end you’ll have two folders, one for the app and one for the library. In case the library already exists, you have to clone it from git into the same parent folder as the app.
Consume the library
Go to app and configure it to consume the library
Use the library in the project by adding a reference in the manifest.json to the library:
Use the example control in the view:
Configure UI5 Tooling
Configure the UI5 Tooling to load the library when running the app.
Install “ui5-middleware-servestatic” in the ui app
Add it to the ui5 dependencies:
Map the library resource path with the folder where the library is stored in the ui5.yaml:
Start the app (in case of errors, run “npm I” first)
This will already work but TypeScript will still give errors when you try to access or create the control from in the controller:
- First error is not related to the library but rather because the library and app are open in the same VSCode workspace:
This can be solved by replace the eslint.json file with an eslint.js containing the configuration property “tsconfigRootDir” (tip from Peter):
- Second one, more importantly, is because the TypeScript configuration is not finding the library as a module:
As a solution for this I adapted the following changes to the tsconfig.json file of the app:
- Changed “rootDir” to “rootDirs” because it is not only the app but also the library the needs to be resolved
- Configure a path for the library so the correct path of the library can be used in the app. This is needed to not break the connection when the app is deployed to a Fiori Launchpad
- Add the path of the library to the includes for full TypeScript support
This allows us to use the library with it controls in the app without any error:
No errors + autocompletion and syntax checks are available !
One remark, running “tsc” will create two subfolders in the dist folder, one for the library and one for the app which would not be the case without these changes. Nevertheless, running “npm run build” of the app results in the exact same behavior as before so it doesn’t seem to be an issue.
Running tsc in the app will give an error about the following config of the “defaultValue”:
I simply changed “null” to an empty string to solve this:
In the end, no errors 😊
This covers the full chain with TypeScript, from controls to libraries into apps 😊
This config made it work for me but maybe this can be done otherwise. Feel free to share your input or any other improvements!