Skip to Content
Author's profile photo Jakob Marius Kjær

Auto documentation using Grunt in the Multi-Cloud WebIDE

Hi all,

 

I thought I would share my latest findings on the SAP Cloud Platform, since I am pretty excited about the capabilities.

As most of you probably know, the Multi-Cloud version of WebIDE was in May this year. I must admit, I didn’t really look at it until recently, because I only thought it had something to do with the Cloud Foundry, which is still an area that I owe myself to look into in more depth.

However I think the most interesting innovation on the WebIDE is that they moved from the older Eclipse Orion platform onto the Eclipse Che. So this probably means a whole heap of new bells and whistles, which I probably wouldn’t be able to explain probably anyway. But one thing that I do know is that now you can run Grunt tasks and customise your build tasks for your UI5 projects.

This blog is to explain how you can use it. More specifically how you can convert your JSDOC comments into a proper documentation, without you having to do a thing! Cool right!!!

First of all you need to activate the Multi-Cloud WebIDE service in the Cloud cockpit

 

The URL is pretty much the same as for your normal WebIDE, just add CP after WebIDE in the URL.

 

So from:

https://webide-sxxxxxxxxtrial.dispatcher.hanatrial.ondemand.com/

to

https://webidecp-sxxxxxxxx.dispatcher.hanatrial.ondemand.com/

 

First thing you will notice is a new splash screen, but otherwise it looks pretty much the same.

 

I’ve cheated a bit and already created a project for this example. I’d expect you would know that by now.

 

First thing is to show you how you can easily create a JSDoc for a function.

 

Right-Click the function keyword and press the Generate JsDoc Comment.

A snippet like this comes up:

/**

*

* @param sText

*/

You can check how to write proper JSDoc comments here

This rule can also be used for your eslint.

 

My function is fairly simple. I receive a string as a parameter and output to the console. So my JSDoc is like:

 

/** 
 * Outputs the received string to the console
 * @param sText {String} Containing the text
 * @returns {void}
*/
myNewFunction: function(sText){
    console.log(sText);
}	

 

Now to the fun stuff.

 

I like to keep my Grunt tasks clean, so create a folder in the root of your project named “tasks”

And another one named “doc”

 

The first folder is for all our custom grunt tasks. The second is for storing our documentation.

 

Create a file in the task folder named “jsdoc.js”

Paste the following into your newly created file:

module.exports = function(grunt) {

  grunt.config('jsdoc', {
         dist : {
            src: ['./webapp/*.js', './webapp/controller/*.js'],
            options: {
                destination: 'doc'

        }
      }
  });

  grunt.loadNpmTasks('grunt-jsdoc');

};

 

So what does this file do?

Well this is our task configuration for the JSDoc grunt. This inputs the folders that we want documented. In our example its the webapp folder and the controller folder and then all js files in those folders.

 

Next thing is to create a package.json file in the root of your project. This file is the configuration for our build process. We need to load the depending npm libraries here.

Add the following to the file

{
  "name": "grunt-example",
  "version": "1.0.0",
  "description": "Example project for grunt JSDOC",
  "main": "component.js",
    "private": true,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Jakob",
  "license": "ISC",
  "devDependencies": {
    "grunt": "^1.0.1",
    "grunt-sapui5": "^1.3.18-g",
    "grunt-jsdoc": "^2.1.1"}
}

 

Obviously changing the name, description and author. The dependencies is where we load our npm libraries.

  • The grunt-sapui5 is the standard build process in webide.
  • Grunt is where we load the grunt library
  • grunt-jsdoc is the npm library to generate our documentation.

 

Next is the gruntfile.js, this needs to be created as well in the root of your project

module.exports = function(grunt) {


// Initialize config.
  grunt.initConfig({
    pkg: require('./package.json'),
  });

  // Load per-task config from separate files.
  grunt.loadTasks('tasks');

  grunt.registerTask('default', [
    'lint',
      'clean',
      'build',
      'jsdoc'
   ]);

};

 

Our grunt file first loads the config from our package.json file, next loads all our tasks from the task folder and thirdly builds our tasks in the default task runner. The ‘lint’,’clean’, ‘build’ are all the normal build process in the webide. The last one is our task for our documentation.

Now we are ready to build our project.

Right click the project and press build.

 

You can follow the progress in the progress tab (Look to the bottom right for the highlighted button)

 

When the build is complete our doc folder will be filled with html files with the same naming as our javascript files.

Each html file consists of all our code and then hyperlinks to the function documentation.

 

 

For more inspiration on grunt tasks, have a look at these blogs and tutorials:

https://www.sap.com/developer/tutorials/ci-best-practices-intro.html

https://www.sap.com/developer/tutorials/ci-best-practices-fiori-abap.html

https://blogs.sap.com/2017/09/16/component-preload.jsminification-and-uglification-for-enhancing-the-performance-of-sapui5-application/

 

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Mike Doyle
      Mike Doyle

      Nice work, Jakob. If the documentation is auto-generated there is a good chance that it will be up to date. If it's up to date we devs might actually use it

      Author's profile photo Stefanie Heil
      Stefanie Heil

      Great post. But I got always the same message: No "jsdoc" targets found.
      Do you know the problem?
      I tried different variants of defining the src. Your variant and also '**/*.js'. But always the same message is displayed.

      Author's profile photo Joseph BERTHE
      Joseph BERTHE

      Hello,

      Thanks for your blog. I followed all your steps but it didn't work.

      Here is the log :

      15:03:39 (Build) Build started.
      15:03:41 (DIBuild) Build of "/ux400todolist" in progress.
      15:03:42 (DIBuild) [INFO] Retrieving source code[INFO] Preparing node environment
      15:03:44 (DIBuild) [INFO] Node environment ready
      15:03:52 (DIBuild) [INFO] Installing node dependencies
      15:04:04 (DIBuild) 
      npm ERR! code ENOGIT
      npm ERR! Error while executing:
      npm ERR! undefined ls-remote -h -t git://github.com/jsdoc3/jsdoc.git
      npm ERR! 
      npm ERR! undefined
      npm ERR! No git binary found in $PATH
      npm ERR! 
      npm ERR! Failed using git.
      npm ERR! Please check if you have git installed and in your PATH.
      npm ERR! A complete log of this run can be found in:
      npm ERR!     /mnt/npm_cache/_logs/2018-10-22T13_04_01_268Z-debug.logBuild failed.
      Please follow the relevant troubleshooting tips below:
      ERROR: "Unable to find local grunt"- Right-click the project folder, select "Clean npm Folder", and build again.
      ERROR: "npm ERR! code EINTERGITY"- Delete the "package-lock.json" file from the project and build again.[INFO] Build finished in 24 seconds

      Here is my package.json :

      {
      	"name": "TodoList",
      	"version": "0.0.1",
      	"description": "",
      	"private": true,
      	"devDependencies": {
      		"grunt": "^1.0.1",
      		"grunt-sapui5": "^1.3.18-g",
      		"grunt-jsdoc": "^2.1.1",
      		"grunt-jsdoc-plugin": "^0.1.4",
      		"@sap/grunt-sapui5-bestpractice-build": "1.3.62"
      	}
      }

      Here is the Gruntfile.js :

      module.exports = function (grunt) {
      	"use strict";
      	grunt.config('jsdoc', {
      		dist: {
      			src: ['./webapp/controller/*.js'],
      			options: {
      				destination: 'doc'
      			}
      		}
      	});
      
      	grunt.loadNpmTasks('grunt-jsdoc');
      	grunt.loadNpmTasks("@sap/grunt-sapui5-bestpractice-build");
      	grunt.registerTask('default', [
      		'lint',
      		'clean',
      		'build',
      		'jsdoc'
      	]);
      };

      What could be the problem ?

      Regards,

      Joseph