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: 
Christophe_SW
Participant
2,789
Hi, all,
With this blogpost I would like to document the steps that I went through in order to obtain a clean starting CAP project setup using TypeScript.

Below I will go through a series of terminal commands and some file configuration.

It might take quite some time to go through all the steps the first time around.
But once finished, you can easily copy-paste this config to your different projects.

This whole process should ideally be included into one big Yeoman generator, but for now this is how I do it manually.

Feel free to comment for any suggestions or variations on this. I'm curious to learn about the best approach myself.

Advantages / features of the this current setup:



  • CAP project is using TypeScript

  • Custom Fiori project is using TypeScript

  • Breakpoints get triggered in BAS in the CAP TypeScript files

  • Fiori TypeScript files can be viewed in the browser console for debugging

  • Live reload when updating the Fiori project


Initializing the CAP-side of the project


Getting started


Let's get started with some initial files by running the "cds init" command.
(Make sure to do this within a previously created project folder)
cds init

Converting CAP project to TypeScript


Use the following commands to install TypeScript locally in our project and to add the TypeScript dependencies.
npm install --save-dev typescript
npm i -g typescript ts-node
npm i --save-dev @types/node

Now we can add a new file "tsconfig.json to our rootdir. To finalize our TypeScript setup.

tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./gen/srv/srv",
"rootDir": "./srv",
"baseUrl": "./",
"moduleResolution": "node",
"skipLibCheck": true,
"preserveConstEnums": true,
"sourceMap": false,
"allowJs": true,
"strict": true,
"strictNullChecks": false,
"strictPropertyInitialization": false,
"esModuleInterop": true
},
"include": [
"./srv/**/*"
]
}

 

Our project is now TypeScript ready, but it isn't doing anything yet so let's create a quick test service and function.

/srv/warehouse.cds
service warehouse {
//warehouse/hello(to='world')
function hello (to:String) returns String;
}

/srv/warehouse.ts
import { Service } from "@sap/cds/apis/services";

module.exports = (warehouse: Service)=>{
warehouse.on ('hello', req => {
return `Hello ${req.data.to} `
})
}

At this point you could already do a first CAP test, see if the TypeScript version is working with the follwing commands

Make sure everything is installed:
npm i

Run the project:
cds-ts watch

We can test our first function by going to the endpoint:
...localhost:4004/service/warehouse/hello(to='world')

But if we want our breakpoints to work in BAS, the easiest way is to run cap via a debug configuration file.

To do so, add the config below to the list of "configurations"
in the launch file.

/.vscode/launch.json
{
"command": "cds-ts run --with-mocks --in-memory?",
"name": "cds-ts run",
"request": "launch",
"type": "node-terminal",
"skipFiles": [
"<node_internals>/**"
],
"sourceMaps": true,
"disableNetworkCache": true,
"showAsyncStacks": true
}

Great, we are done on the CAP side of things for now.

Initializing the Fiori project


So we have our CAP back-end but now we want to generate a custom Fiori front-end on top of this. We could simply use the Wizard, but this doesn't offer any TypeScript options for now. So we are going to do it with Yeoman terminal commands instead.

Installing the necessary tools:


Go to the app folder of your  current project and run the following commands:
npm install -g yo generator-easy-ui5

Note: The command above installs Yeoman andthe eay-ui5 generator globally. You don't need to repeat these steps each time if you installed these tools previously.
You can check whether or not the tools are installed by running "yo --generators".
If everything is installed correctly it will display a list of available generators.
 

Now let's start the actual Fiori project:
yo easy-ui5 ts-app

The Yeoman terminal wizard will be appear prompting you with some question for the creation of your project.


Be careful, if you choose to use capital letters in your namespace or application name.
This by itself is fine, but you will have to change them to lower case manually in the ui5.yaml file later.
Also notice that I didn't opt for a git repository.
I decided to use one big Git repository for the whole CAP project (including the app folder and  thus also this Fiori sub-project.)

ui5.yaml

make sure that this is all lowercase as mentioned previously:



 

At this point we have a working Fiori project that can be executed with:
npm run start

 

Quick UI5 code-snippet so we can test our app.


I added a button to my Fiori app in order to test the CAP function that we created previously.
If you want to follow along with the same test function you can copy this setup:

Main.view.xml
added:
<Button text="CAP test TVC" press="callCap" />

Main.controller.ts
added:
//Simple Function call to CAP
public async callCap() {
const oContext = this.getOwnerComponent().getModel().bindContext("/hello(...)");
oContext.setParameter("to", "test");
await oContext.execute();
let result = oContext.getBoundContext().getObject() as capFunctionResult;

console.log(result);

MessageBox.show(result.value);
}

 

The final part bellow will connect both apps.
We want to call our CAP function from within the Fiori and get the response from our request.

Connecting Fiori to CAP


There is no connection yet to the CAP backend though.
To fix this, we need to:

Add the following files

/app/services.cds
using from './yourFioriProjectFolder/annotations';

 

/app/yourFioriProjectFolder/services.cds
using warehouse as service from '../../srv/warehouse';

Update the manifest

/app/yourFioriProjectFolder/webapp/manifest.json

Under "sap.app": ==> datasource
"dataSources": {
"mainService": {
"uri": "/warehouse/",
"type": "OData",
"settings": {
"annotations": [],
"localUri": "localService/metadata.xml",
"odataVersion": "4.0"
}
}
}

Under "sap.ui5" --> "models" ==> datasource new model
"": {
"dataSource": "mainService",
"preload": true,
"settings": {
"synchronizationMode": "None",
"operationMode": "Server",
"autoExpandSelect": true,
"earlyRequests": true
}
}

But running our app at this point would give us a connection error


Fixing this local connection can be done with the fiori-tools-proxy


The command for Installing the dependency:
npm install @sap/ux-ui5-tooling --save-dev

 

Adding the configuration for this tooling:

/app/yourFioriProjectFolder/ui5.yaml

Under
server ==> customMiddleware:
- name: fiori-tools-proxy
afterMiddleware: compression
configuration:
backend:
- path: /warehouse
url: http://localhost:4004

 

Running the final app:


We can now run the entire app but we still need to execute 2 different bash commands in 2 different instances.

  • The CAP part

    • Run the cap project via the debugger “play button



  • The Fiori app

    • Via the command “npm run start” within the Fiori project folder.




If you run into this error while executing the app:


Update the index.html

index.html











old new
src="resources/sap-ui-core.js" src="https://sapui5.hana.ondemand.com/1.114.0/resources/sap-ui-core.js"

Live reload when updating the Fiori project


The live reload settings below assume that your transpiled JavaScript files reside in the "webapp" folder.
But In our current setup we already have the TypeScript files in that directory

Therefore rename your “webapp” folder to “src”.

A new folder called "webapp" will be generated again once we run our TypeScript transpiler.

package.json (from the Fiori app)

replace
"start": "ui5 serve --port 8080 -o index.html",

with
"start": "npm-run-all --parallel watch:ts start:ui5",
"watch:ts": "babel webapp --out-dir webapp --source-maps true --extensions \".ts,.js\" --copy-files --watch",
"start:ui5": "ui5 serve --port 8081 -o index.html",

(I renamed the original start to “start_old” as backup in case I ever need it again)

still in the same file, we need will need to declare our additional dependencies Don’t copy them manually though, we can use the npm commands mentioned below in order to get the latest up-to-date versions:

something like this will be added to the package.json:
"@babel/cli": "^7.16.8",
"@babel/core": "^7.16.7",
"@babel/preset-env": "^7.16.8",
"@babel/preset-typescript": "^7.16.7"

"npm-run-all": "^4.1.5",

 

The npm commands to add these last dependencies:
npm install --save-dev @babel/cli @babel/core @babel/preset-env @babel/preset-typescript

npm install npm-run-all --save-dev

 

A last step, almost done 🙂

ui.yaml
configure the live reloading in the yaml file by adding the following config under
server ==> customMiddleware:
- name: fiori-tools-appreload
afterMiddleware: compression
configuration:
port: 35729
path: webapp

 

And finished!

Your Fiori project should automatically refresh with every change you make.

I'm still investigating options to run it all with one single command.
At this point we still need to terminal instances.

But we should have the following features as promised:

  • CAP project is using TypeScript

  • Custom Fiori project is using TypeScript

  • Breakpoints get triggered in BAS in the CAP TypeScript files

  • Fiori TypeScript files can be viewed in the browser console for debugging

  • Live reload when updating the Fiori project

3 Comments
Labels in this area