msg | October 2017 | SAP Conference 2017

Building an Open Source Library

Using ES6 syntax and UI5

by Serban Petrescu

Project structure

Folder structure

package.json

Contains metadata about the library (name, description, git repository and so on).

Also holds the dependency list.

Can be automatically generated by using "npm init".

.editorconfig

Ensures that the code editor config is consistent.


root = true

[*]
indent_style = tab
indent_size = 4
end_of_line = crlf
charset = utf-8

.eslintrc.json

JavaScript linter settings.


{
	"env": {
		"browser": true,
		"es6": true
	},
	"extends": "eslint:recommended",
	"parserOptions": {
		"sourceType": "module"
	}
}

README.md

The readme file which will be displayed at the root of the repository (and in the JSDoc).


# UI5 ES6 Demo Library

Repository which shows how to enable the usage of ES6 syntax when 
building UI5 libraries.

The latest version of the library cab be downloaded from here: 
[ui5-demo.zip](https://...).

You can find the documentation here: 
[JsDoc](https://...), [Presentation](https://...).

.jsdoc.json

For the JsDOC generation, we need to specify some properties in a config file:


{
	"plugins": [
		"plugins/markdown"
	],
	"templates": {
		"dateFormat": "dd.MM.yyyy",
		"systemName": "UI5 ES6 Demo",
		"copyright": "Copyright - 2017 Serban Petrescu",
		"theme": "lumen",
	},
	"markdown": {
		"parser": "gfm"
	}
}

Build files

We need the following files for the automated build:

  • "Gruntfile.js": Grunt task descriptions.
  • ".travis.yaml": Travis-CI configuration.

Writing the code

Before writing the code, we need to prepare babel:

  • install several npm packages
  • 
    npm i -D babel-cli 
    npm i -D babel-preset-env
    npm i -D babel-plugin-transform-es2015-modules-ui5
    
    
  • write the "babel" package.json section
  • 
     "babel": {
        "presets": [
          "env"
        ],
        "plugins": [
          "transform-es2015-modules-ui5"
        ]
      }
      
    

Our library just contains some high order functions:

// file: /src/spet/demo/library.js

import sapUi from "sap/ui/Global";
import jQuery from "jquery.sap.global";

let oLibrary = sapUi.getCore().initLibrary({/* ... */}) 
	|| jQuery.sap.getObject("spet.demo");

oLibrary.curry = f => a => b => f(a, b)
oLibrary.uncurry = f => (a, b) => f(a)(b)
oLibrary.papply = (f, a) => b => f(a, b)

export default oLibrary;

We of course don't forget to write JSDoc comments (for each function and for the library as a whole).

We also create some unit tests:

// file: /test/spet/demo/all.js

import library from "spet/demo/library";

QUnit.module("library");

let fnRegAdd = (a, b) => a + 2 * b;

QUnit.test("Should curry the add function.", assert => {
	let fnAdd = library.curry(fnRegAdd);
	assert.equal(fnAdd(5)(10), 25, "Result is correct.");
});

/* and some more tests... */

Code

The build process

This whole process is run by grunt. Therefore we need the following grunt plugins:

  • grunt-babel
  • grunt-contrib-clean
  • grunt-contrib-copy
  • grunt-contrib-qunit
  • grunt-contrib-uglify
  • grunt-openui5
  • grunt-contrib-compress
  • grunt-jsdoc

For each plugin, one or more task configurations are written in the Gruntfile.js. At the end of the file, the grouping and order of the tasks is described:


grunt.registerTask("stage", [
	"clean:stage", 
	"babel:stage", 
	"copy:stage"
]);

grunt.registerTask("dist", [
	"clean:dist", 
	"uglify:dist", 
	"copy:dist", 
	"openui5_preload:dist"
]);

Gruntfile

Travis-CI

We want the build to run automatically on each commit. For this we will use Travis.

First we need to enable it (a simple switch) and we have to write a ".travis.yml" file:


language: node_js
node_js: '7'
before_script: npm install
script: grunt
cache:
  directories:
  - node_modules

Deployment

GitHub Pages and Releases

We will deploy to 2 different providers:

  • GitHub Pages (on each commit to master).
  • GitHub Releases (on each new tag).

GitHub Pages

Everything from the "pages" folder is deployed directly. A GitHub personal access token has to be generated and saved into the travis environment.

The travis.yml needs to be changed:


deploy:
  - provider: pages
    skip_cleanup: true
    github_token: $GITHUB_TOKEN
    local_dir: pages
    on:
      branch: master

GitHub Releases

Just the zip file is deployed. This deployment provider requires an OAuth token, (encrypted by the travis cli).

The travis.yml needs to be changed:


deploy:
  - provider: releases
    api_key:
      secure: ...
    file: pages/spet-ui5-demo.zip
    on:
      tags: true
	  

.travis.yml

Pages

Releases

The end

Thank you for your attention.