Domino, Extlib, GRUNT, JSON and Yeoman
TL:TR
With a few tweaks and clever setup, you can have web developers deliver front-ends for Domino without ever touching it.Contemporary web development workflows separate front-end and back-end through a JSON API and HTTP (that's 21st century 3270 for you). The approach in these workflows is to treat the webserver as source of static files (HTML, CSS, JS) and JSON payload data being shuffled back and forth. This article describes how my development setup makes all this work with Domino and Domino designer.
The full monty
The front-end tools I use are:- Node.js: a JavaScript runtime based on Google's V8 engine. It provides all runtime for all the other tools. If you don't have a node.js installation on your developer workstation, where were you hiding the last 2 years?
- Bower: a dependency manager for browser files like CSS, JS with their various frameworks. You add a depencency (e.g. Bootstrap) to the
bower.json
file and Bower will find the right version for you - Grunt: a task runner application, used for assembly of web sites/applications (or any other stuff). Configured using a
Gruntfile.js
: it can do all sorts of steps like: copy files, combine and minify, check code quality, run tests etc. - Yeoman: A application scaffolding tool. It puts all the tools and needed configurations together. It uses generators to blueprint different applications from classic web, to reveal application to mobile hybrid apps. The site lists hundreds of generators and you are invited to modifiy them or roll your own
- GIT: the version control system
My general directory layout starts with a project folder that has entries for code, documentation, nsf and a misc. folder. I only put the
code
folder into the GIT version control.
The front-end developer doesn't need any of the Domino components available to create user interface and interaction models. The back-end developer will use exclusively the REST controls from the Domino XPages Extension library (which is part of a default current Domino server install). The two directory structures are linked in a GIT project, but that isn't mandatory. One step that made my live much easier: take the
dist
directory and link it to WebContent
. This saves me the step to copy things around. The fine-tuning of the setup is where the fun starts.But first things first:
Installation
You follow the Node.js instructions for your platform to get a running node.js version (v4.2.1 as time of writing). Thereafter you install as admin (sudo
for Linux/Mac) Bower, Grunt and Yeoman:
npm install -g bower
npm install -g grunt-cli
npm install -g yo
npm install -g generator-karma generator-angular
I use the generator-angular, but looking very promising is mcfly. Go and checkout the Yeoman website for the many more options you have for generators.
Change to the Frontend directory and initialize your new front-end application using
yo angular myAwesomeApp
You get walked through a series of questions, node.js does some magic (requires internet connection) and you have a basic Angular.js application ready. There are tons of tutorials how to use Yeoman, Bower, Grunt and Angular.js, so go google them, I'll limit myself to the tweaks I made to make my Domino live easier.
Once the
yo
magic work concludes, you can use
grunt serve
to have a first look at your new frontend in action (by default on port 9000). As long as that grunt task is running, any change you save will automatically reload the browser and show you the new result (praise to the second monitor).
Tweaks
- All my JSON controls live on an XPage with the name
api.xsp
.
I create a directory under the app directory named api.xsp and add one file each that matches the path property in the XPages REST controls (api.xsp/people, api.xsp/setup.json etc). These files contain sample JSON of what the Domino REST control eventually will return. - To prevent that directory to be copied into the NSF (when
grunt build
runs), I edit theGruntfile.js
and change the copy:dist:files:src array to include'!api.xsp'
.
If you use more XPages you could use a wildcard. Be careful to include the exclamation mark which stands for not - With the file open, I adjust the clean section where I add
'!<%= yeoman.dist %>/WEB-INF{,*/}*'
toclean:dist:files:src
.
Again don't forget the exclamation mark. This allows me to keep WebContent and dist linked and the build task won't wipe out the WEB-INF directory.
Now we can make JSON calls (in Angular services/providers) to our REST endpoints without having anything Domino installed (which allows you to use a Mac or Linux for this part of the exercise). The only missing step: posting things back. - This part is
a little trickiereasy when you ask the right people:
in a frontend dev environment you don't want to fully simulate the server, a static reply or just echo the submitted JSON does suffice.
The default configuration of the Gruntfile.js only caters to GET requests, but I wasn't the first to ask, so there's precedence. It turned out, that it is just a few lines of changes at the top of your Gruntfile.js (and 2 lines down):var bodyParser = require("body-parser"); var postResponder = function(request, response, next) { if (request.method === 'POST') { console.log(request.method+" "+request.url); response.setHeader('Content-Type', 'application/json'); response.statusCode = 200; response.end(JSON.stringify(request.body)); } else { next(); } };
and to theconnect.livereload.options.middleware
object:
function (connect) { return [ connect().use('/api.xsp', bodyParser.json()), connect().use('/api.xsp', postResponder), connect.static('.tmp'), connect().use('/bower_components', connect.static('./bower_components')), connect().use('/app/styles', connect.static('./app/styles')), connect.static(appConfig.app) ]; }
Note: You only add the first two lines after the return statement, the others are already there.
As usual YMMV!
Posted by Stephan H Wissel on 30 October 2015 | Comments (3) | categories: XPages