Heroku – Deploy Java App with Yeoman scaffold-ed client

I have a Java application configured with Maven. I have all my model and web services in this application (backend). In a Java app normally you would have your web client code in src/main/webapp (frontend). I scaffold-ed the client application with yeoman, so it uses grunt to build and bower to manage dependencies. Great! well, not so much, it runs perfectly in my local environment (I can run bower install, then grunt build and it would generate a “dist” folder with all my sources compiled and minified) but it doesn’t work on heroku’s platform.

The problem is heroku detects my app only as Java application so it doesn’t run bower install nor grunt build.

I tried to use heroku-buildpack-multi with some issues, I even created my own patched version that allows to specify a base path for each buildpack. With that I can push to heroku and it runs mvn package and then npm install for the node buildpack. I’ve added a postinstall script to run both bower install and grunt build, which in turn you need to add as dependencies in your package.json.

  "name": "webapp",
  "version": "0.0.0",
  "dependencies": {
    "grunt": "^0.4.1",
    "grunt-cli": "~0.1.13",
    "bower": "~1.3.9",
    "grunt-autoprefixer": "^0.7.3",
    "grunt-concurrent": "^0.5.0",
    "grunt-contrib-clean": "^0.5.0",
    "grunt-contrib-compass": "^0.7.2",
    "grunt-contrib-concat": "^0.4.0",
    "grunt-contrib-connect": "^0.7.1",
    "grunt-contrib-copy": "^0.5.0",
    "grunt-contrib-cssmin": "^0.9.0",
    "grunt-contrib-htmlmin": "^0.3.0",
    "grunt-contrib-imagemin": "^0.7.0",
    "grunt-contrib-jshint": "^0.10.0",
    "grunt-contrib-uglify": "^0.4.0",
    "grunt-contrib-watch": "^0.6.1",
    "grunt-filerev": "^0.2.1",
    "grunt-google-cdn": "^0.4.0",
    "grunt-karma": "^0.8.3",
    "grunt-newer": "^0.7.0",
    "grunt-ngmin": "^0.0.3",
    "grunt-svgmin": "^0.4.0",
    "grunt-usemin": "^2.1.1",
    "grunt-wiredep": "^1.7.0",
    "jshint-stylish": "^0.2.0",
    "karma": "^0.12.17",
    "karma-jasmine": "^0.1.5",
    "karma-phantomjs-launcher": "^0.1.4",
    "load-grunt-tasks": "^0.4.0",
    "time-grunt": "^0.3.1"
  "engines": {
    "node": ">=0.10.0"
  "scripts": {
    "test": "grunt test",
    "postinstall": "./node_modules/bower/bin/bower install && ./node_modules/grunt-cli/bin/grunt build"

It effectively run bower install and then grunt build, but it failed because my scaffold-ed client uses compass which in turn requires ruby, arrrgh! This is where I stopped looking into this path, I’ve decided to build on my local computer and include the “dist” folder on source control (against all my principles), as suggested by various websites, for now.