“More code, less talk”

Thanks

Inspired by You Don’t Know JS (book series)

What are we doing here today?

We want to know how to develop an openui5 application using sap.ui.core.ComponentContainer and sap.ui.core.Component. Also we want to know how to add automatic .js source code validating with eslint. As core source code for the project and quick start you may use project from my second article.

Introduction

A goal of my blog is do not teach you how to use openui5 library from SAP in right way. The openui5 was designed to solve one issue with several possible ways. So you are able to choose.

The goal is sharing my personal experience of using the library and some other web development stuff, which helps you to speed up your development using openui5.

All code samples are developed on MacOS environment. On other environments (Linux or Windows) process should be nearly the same.

Pre-requirements

Minimal:

  • MacOS, Linux or Windows operating system prepared
  • Chromium browser installed
  • Node.js javascript runtime installed
  • Yarn dependency manager installed
  • Gulp4 javascript task runner installed globally

Additional:

  • Git client (command-line or GUI) installed
  • Preferred IDE installed (for ex. Visual Studio Code or WebStorm)

Let’s go

First of all I recommend you to create project as described in my second article (preferable). Or just clone project from repository (for lazy developers)

git clone https://github.com/sergiykh/you-do-not-know-openui5.git cd you-do-not-know-openui5 git checkout tags/app-and-pages

First of all, project structure will be changed a little bit

├── .babelrc ├── .eslintrc (new) ├── .editorconfig ├── .gitignore ├── LICENSE.md ├── README.md ├── gulpfile.js => (Changed) ├── package.json => (Changed) ├── proxies.js ├── src ├── app ├── pages | ├── CustomerDetail.page.js | ├── Customer.page.js | ├── Login.page.js ├── Component.js (New) ├── manifest.json (New) ├── app.config.js => ├── app.startup.js => (Changed) └── index.html 

Add new developer dependencies via yarn

yarn add -D gulp-eslint babel-eslint

You packages.json will be automatically updated with new dependencies. Never update dependencies in  package.json manually.

Just a brief explanation of used dependencies:

  • gulp-eslint validating of you .js source code via gulp task
  • babel-eslint parser for eslint tool

In .eslintrc

{ "parser": "babel-eslint", "extends": "eslint:recommended", "rules": { "strict": 0, "no-alert": 0, "no-bitwise": 0, "camelcase": 1, "curly": 1, "eqeqeq": 0, "no-eq-null": 0, "guard-for-in": 1, "no-empty": 1 }, "globals": { "$": true, "_": true, "jQuery": true, "sap": true, "app": true }, "env": { "browser": true, "node": true } }

Full list of configuration options can be found here. In configuration you may found that we can enable ES6 syntax fo linter via “ecmascriptVersion”: 6, but it will not work, because we have custom babel preset for openui5. That’s why we are using parser “babel-eslint”.

Update gulpfile.js

const gulp = require('gulp'); // Require gulp-eslint plugin const eslint = require('gulp-eslint'); ... // Turn of log for gulp-mem plugin gulpMem.enableLog = false; // Stream for all .js files const copyJs = () => { let b = babel() .on("error", (e) => { console.log(e.stack); b.end(); }); return gulp.src([ 'src/**/*js' ]) .pipe(sourcemaps.init()) // Validate our .js source code with linter .pipe(eslint()) .pipe(eslint.format()) .pipe(b) .pipe(replace('src.', '')) .pipe(replace('src/', '')) .pipe(sourcemaps.write('.')) }; ...

Update src/app.startup.js

/*eslint-disable no-unused-vars*/ let app; /*eslint-enable no-unused-vars*/ // Now we can use arrow functions in our code (feature of ES6) sap.ui.getCore().attachInit(() => { sap.ui.require([ "sap/ui/core/ComponentContainer", "app/Component" ], (ComponentContainer, MainComponent) => { // Our main Component of application let mainComponent = new MainComponent("main-component", { id: "main-component", name: "app" }); // It is also possible to use factory function // let mainComponent = sap.ui.component({ // id: "main-component", // name: "app" // }) // Or load component asynchronous // sap.ui.component({ // id: "main-component", // name: "app", // async: true // }).then((mainComponent) => { // let componentContainer = new ComponentContainer("main-component-container", { // component: mainComponent, // height: "100%", // width: "100%", // }); // // componentContainer.placeAt("content"); // });  // Our main Container for Component let componentContainer = new ComponentContainer("main-component-container", { component: mainComponent, height: "100%", width: "100%", }); componentContainer.placeAt("content"); }); }); 

In src/appComponent.js

import UIComponent from "sap/ui/core/UIComponent"; import App from "sap/m/App"; import Login from "app/pages/Login.page"; import Customers from "app/pages/Customers.page"; import CustomerDetail from "app/pages/CustomerDetail.page"; // Create object and export as module to use in future // Also here we are using class/extends (feature of ES6) export default class Component extends UIComponent { metadata = { manifest: "json" } createContent() { app = new App("app", { initialPage: "login" }); return app .addPage(Login) .addPage(Customers) .addPage(CustomerDetail); } } 

In our next articles we will found other cool features of component approach from openui5.

In src/manifest.json

{ "_version": "0.0.1", "sap.app": { "_version": "0.0.1", "id": "you-do-not-know-openui5", "type": "application", "title": "you-do-not-know-openui5", "description": "Project for articles from https://blogs.sap.com/author/skholod/", "applicationVersion": { "version": "0.0.1" } }, "sap.ui": { "_version": "1.50.7", "technology": "UI5", "deviceTypes": { "desktop": true, "tablet": true, "phone": true }, "supportedThemes": [ "sap_belize" ] }, "sap.ui5": { "_version": "0.0.1", "dependencies": { "minUI5Version": "1.44", "libs": { "sap.ui.core": {}, "sap.m": {} } } } } 

It is minimum configuration for application component. Other configuration options you can found here.

Looks like everything is ready! Now we can issue gulp default task in command line.

gulp

Content of src folder will be validated via Eslint (.js), compiled (.js) via Babel, copied to root path in-memory, watchers will be started, browser-sync server will be started and our app will be opened in Chromium browser.

In command line we see the following

In browser we see the following

Now we need to be sure that linter of .js source code is working.

Update src/app/Component.js

... createContent() { // Declare variable here let unusedVariable; app = new App("app", { initialPage: "login" }); return app .addPage(Login) .addPage(Customers) .addPage(CustomerDetail); } ..

Because of changes in .js file (watchers in gulpfile.js), gulp task build will be issued automatically

In command line we see the following

And let see how classes/extends of ES6 source code compiled to ES5 openui5 sources.

Open DevTools in Chromium browser and click Sources tab.

Our original source code

And our compiled code to ES5

So, it is the end for today. Source code for our project can be found here. Feel free to experiment with source code, because it is only one way to become a developer. And Happy Coding!

Next topic of “You Don’t Know Openui5” series will be soon.

Summary

So, we enhance our simple openui5 application:

  • Use Component as application means that Component is a main entry point for the whole ui of our application. But we still using pages inside Component. I recommend you to use Component and configure it like application for production use.

and enhance our development environment:

  • Add validating of js code via Eslint.

Something to read

  • Walkthrough: Step 9: Component Configuration
  • Walkthrough: Step 10: Descriptor for Applications
  • Descriptor for Applications, Components, and Libraries

Previous articles

  1. You Don’t Know Openui5: bootstrapping
  2. You Don’t Know Openui5: app and pages