Introducing Bower & Gulp in Java project

by GarciaPL on Saturday 2 January 2016

In this post I would like to give you some introduction how to integrate Bower and Gulp into your Java project. On the beginning I just would like to explain briefly you what Bower and Gulp are.

Bower - package management system for client-side programming on the World Wide Web. It depends on Node.js and npm. It works with git and GitHub repositories. [Wikipedia]

Gulp - fast and intuitive streaming build tool built on Node.js.


First of all we are going to use very useful plugin called frontend-maven-plugin provided under groupId com.github.eirslett [3]. This plugin will allows us to download/install Node and NPM locally for your project, run NPM install, and then any combination of Bower, Grunt, Gulp, Jspm, Karma, or Webpack.



<plugin>
                <groupId>com.github.eirslett</groupId>
                <artifactId>frontend-maven-plugin</artifactId>
                <version>0.0.26</version>

                <executions>
                    <execution>
                        <id>install node and npm</id>
                        <goals>
                            <goal>install-node-and-npm</goal>
                        </goals>
                        <phase>generate-resources</phase>
                        <configuration>
                            <nodeVersion>v0.12.9</nodeVersion>
                            <npmVersion>2.14.14</npmVersion>
                        </configuration>
                    </execution>

                    <execution>
                        <id>npm install</id>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                        <!-- Uses package.json -->
                        <configuration>
                            <arguments>install</arguments>
                        </configuration>
                    </execution>

                    <execution>
                        <id>bower install</id>
                        <goals>
                            <goal>bower</goal>
                        </goals>
                        <!-- Uses bower.json -->
                        <configuration>
                            <arguments>install</arguments>
                        </configuration>
                    </execution>

                    <execution>
                        <id>gulp build</id>
                        <goals>
                            <goal>gulp</goal>
                        </goals>
                        <!-- Uses gulpfile.js -->
                        <configuration>
                            <arguments>default --env ${gulp.task}</arguments>
                        </configuration>
                    </execution>

                </executions>
            </plugin>

As you can see, first of all above plugin will install locally node and npm. Then npm will install all packages from package.json file. After that bower will install packages used by frontend which are defined in bower.json. The last step is gulp which performs actions defined in gulpfile.js.
Below you can find package.json file in which I have defined bower, gulp and gulp plugins versions :

{
  "name": "simple-web",
  "repository": "git@bitbucket.org:test/test.git",
  "version": "1.0.0",
  "private": true,
  "description": "Simple Web",
  "main": "index.js",
  "author": "GarciaPL",
  "dependencies": {
    "bower": "1.7.0",
    "gulp": "3.9.0",
    "gulp-concat": "2.6.0",
    "gulp-uglify": "1.5.1",
    "gulp-sourcemaps": "1.6.0",
    "gulp-less": "3.0.5",
    "gulp-minify-css": "1.2.2",
    "gulp-environments": "0.1.1"
  }
}

Then let's see what bower.json contains. You can find there defined some plugins from Bower Repository which will be downloaded and installed in bower_components directory :

{
  "name": "Simple Web",
  "version": "1.0.0",
  "private": true,
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ],
  "dependencies": {
    "jquery": "1.11.3",
    "underscore": "1.8.3",
    "autoNumeric": "1.9.25"
  }
}

And the last file is gulpfile.js. In this file you can define special actions which are going to be performed during maven build phase of your Java application. In definition of maven plugin which you might found at the beginning of this post, there is a command : <arguments>default --env ${gulp.task}</arguments>. Variable gulp.task means against what environment application should be build. This variable might be defined in root pom.xml in profile section as a property.
So, according to gulpfile.js for development phase, gulp will provide vendor.map for vendor.js - for this development() method is used. On the other side production phase will provide you uglified vendor.js (compressed) and minified CSS based on base.less - for this one production() method is used. Vendor.js will be placed in /src/main/webapp/static/js/vendor directory, but CSS file might be found in /src/main/webapp/static/css directory.

var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var less = require('gulp-less');
var minifyCSS = require('gulp-minify-css');
var environments = require('gulp-environments');
var development = environments.development;
var production = environments.production;

gulp.task('default', function () {
    console.log('Preparing vendor.js for ' + (production() ? "production" : "development"));
    gulp.start('vendorJS');
    console.log('Preparing less for ' + (production() ? "production" : "development"));
    gulp.start('less');
});

gulp.task('vendorJS', function () {
    gulp.src(['bower_components/jquery/dist/jquery.min.js',
            'bower_components/underscore/underscore-min.js',
            'bower_components/autoNumeric/autoNumeric.js'])
        .pipe(development(sourcemaps.init()))
        .pipe(concat('vendor.js'))
        .pipe(production(uglify()))
        .pipe(development(sourcemaps.write('./')))
        .pipe(gulp.dest('./src/main/webapp/static/js/vendor'));
});

gulp.task('less', function () {
    return gulp.src('src/main/webapp/static/less/base.less')
        .pipe(less())
        .pipe(production(minifyCSS()))
        .pipe(gulp.dest('./src/main/webapp/static/css'));
});





Reference :
[1] Bower.io
[2] Gulpjs.com
[3] Eirslett - frontend-maven-plugin

[4] Npmjs.com
[5] Nodejs.org