Victor Quinn

Software Engineer, Legal Scholar, Problem Solver.

Deploy Coffeescript Node App to Heroku

So you’ve got a cool node app written in Coffeescript and you want to deploy it to Heroku?

Seems like it should be easy these days, right?

Not so much. Well, let’s be honest, we’re in the future, you don’t have to manually manage servers, etc. (Thank you Heroku!) but deploying a Coffeescript app is still no small task as there are a bunch of gotchas. Hopefully this will help.

Structure of Coffeescript node app

The following instructions assume you have the following rough structure to your application:

1
2
3
4
5
/
|-- package.json
|-- Procfile
+-- src
     |-- app.coffee

The general idea here is that your app source .coffee files will live in the /src directory and when they’re pushed to Heroku, they’ll magically be compiled into the /target directory as js files.

This is optimal as it means this compilation happens once with each push and so there is no ongoing performance hit from the server having to convert .coffee to .js on the fly.

So after pushing your app will look like this on the Heroku servers:

1
2
3
4
5
6
7
/
|-- package.json
|-- Procfile
+-- src
|    |-- app.coffee
+-- target
     |-- app.js

Where target/app.js is the compiled version of src/app.coffee

Buildpack

Heroku has things called Buildpacks which are a bundle of scripts to be run when code is pushed to Heroku. They have official Buildpacks for Node, Rails, and the other most common frameworks, but none for Coffeescript as of the time of this writing.

So some research and I found @aergonaut had a great buildpack for coffeescript.

To add this buildpack to a new node app you can use the following command to create the app:

1
% heroku create --buildpack https://github.com/aergonaut/heroku-buildpack-coffeescript.git

You can also add it to an existing app:

1
% heroku config:set BUILDPACK_URL=https://github.com/aergonaut/heroku-buildpack-coffeescript.git

Procfile

You will have to make sure your Procfile is properly configured for this as well.

It should contain the following:

Procfile
1
web: node target/app.js

Note how it’s hitting target/app.js which will be the compiled copy of your app.

Even though you may have an empty target directory on your local machine, it will get populated with the compiled app code on push to Heroku.

Development

Without compilation

During development, you can run your code locally without compilation if you’d like:

1
% coffee src/app.coffee

If you want to do this with Foreman it’s easy to create a Procfile.dev and tell Foreman to use it:

Liquid error: ClassNotFound: no lexer for alias ‘dev’ found

Then to run it:

1
% foreman start -f Procfile.dev

Manual compilation

You can also compile the code manually, just as the Buildpack will on a push to Heroku:

1
% coffee --compile --bare --output target src

Automated compilation

My favorite approach is to have all of this happen automagically, with some linting as well using Grunt Grunt to watch for changes and compile everything in the /src directory into the /target directory.

First, if you haven’t already, install the Grunt dependencies:

1
% npm install grunt grunt-cli grunt-contrib-coffee grunt-coffeelint --save-dev

Then create or edit your Gruntfile:

Gruntfile.coffee []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module.exports = (grunt) ->
  grunt.initConfig
    coffee:
      compile:
        files: [
          expand: true
          cwd: 'src'
          src: '**/*.coffee'
          dest: 'target'
          ext: '.js'
        ]
    coffeelint:
      app: 'src/**/*.coffee'
    watch:
      files: ['Gruntfile.coffee', 'src/**/*.coffee']
      tasks: ['coffeelint', 'coffee']

  grunt.loadNpmTasks 'grunt-coffeelint'
  grunt.loadNpmTasks 'grunt-contrib-coffee'
  grunt.loadNpmTasks 'grunt-contrib-watch'

  grunt.registerTask 'default', ['watch']

Then run it:

1
% grunt

Not only will that watch the directory for changes and compile it whenever a file is written, but it will also lint the files! Then the app can be run:

1
% node target/app.js

Or, since this is just the way it will look when pushed to Heroku, you can use Foreman with the normal Procfile to run it:

1
% foreman start

Note how under the coffee task I have

1
2
3
4
5
6
7
files: [
          expand: true
          cwd: 'src'
          src: '**/*.coffee'
          dest: 'target'
          ext: '.js'
        ]

This basically instructs Grunt to recurse through every subdirectory of src/, find each .coffee file, and compile it to create a .js doppelganger under target/.

This means src/app.coffee becomes target/app.js and src/config/db.coffee becomes target/config/db.js and so on.

If you’re going to do this local auto-compilation, I suggest adding target/ to your .gitignore file. No need for that to get committed to your repo!

Push it!

Of course this is all well and good, but until you actually push it to Heroku it isn’t doing you much good!

1
% git push heroku master

You should see something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Counting objects: 11, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (9/9), 883 bytes, done.
Total 9 (delta 3), reused 0 (delta 0)

-----> Fetching custom git buildpack... done
-----> Coffeescript app detected
-----> Resolving engine versions
       Using Node.js version: 0.8.25
       Using npm version: 1.1.65
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm

       ...
       
       Dependencies installed
-----> Compiling coffee source
       Source compiled to target
-----> Building runtime environment
-----> Discovering process types
       Procfile declares types -> web

Note: I replaced all the npm dependency installation as … above for brevity

Note how it says Coffeescript app detected

This is due to the Buildpack referenced above. If it finds .coffee files in the src directory, it recognizes it as a Coffeescript app.

After it has installed the dependencies, including the coffee-script module, it will compile the coffee source from src/ into target/ and start your app.

Multi-User iOS and the Fingerprint Scanner

I came across this article about Apple acquiring AuthenTec for their fingerprint scanning technology and had a lightbulb go off.

What if, in addition to being used to enhance security, it was also used for a multi-user iOS experience?

Multi-User iOS

An iPad isn’t necessary personal like an iPhone, there are many situations where families are sharing an iPad. iOS has lagged behind this use case, offering no good multi-user experience.

This means that all browser favorites, browsing, history, mail in the default Mail app, and all data in other apps for that matter, such as game progress, documents, notes, and so on, when shared with a family, will be a mess. In an app-centric world, without multi-user capability at the OS level, it is very difficult to share a device between multiple users.

Android recently added multi-user support in 4.2 so Apple is decidedly behind the curve here.

Fingerprint Scanner

With the recent buzz about the fingerprint scanner, most people probably assume the rationale is to support better security on iOS devices. And I’m sure that’s the case.

But it could also be used to make this multi-user experience very nice.

My speculation - Fingerprint Scanner for User Differentiation

Imagine, on a family shared iPad, picking up the locked device and just sliding to unlock.

Since that device can recognize your fingerprint, it knows who you are and drops you into your personalized homescreen.

It has your wallpaper, your apps, when you open the mail program, it has your mail, open your game it has your recent settings, and so on. A true multi-user experience, and you didn’t have to do a thing to tell the system who you were, all you did was slide to unlock.

Your sister enters the room and wants to use the iPad. You simply lock the screen, hand it to her. She can just slide to unlock and since it recognized her fingerprint, it logs in as her. Again, her personalized wallpaper, apps, etc.

Wouldn’t this be neat?

Chance

I am often looking to generate random things in JavaScript. Whether in the browser or in Node, I often find myself looking to generate a random phone number or address or even number with some characteristics.

Whenever I search the web, I inevitably end up on a StackOverflow article such as this one on how to generate a random number in a specific range.

The relevant bits of which look like:

return Math.floor(Math.random() * (max - min + 1)) + min;

That’s all well and good and certainly works, but I found myself wondering, “Is there no helper library for this?”

So this past weekend I made one. I’m calling it Chance.

It’s open source, freely available, It’s got rich docs and has a whole suite of automated tests.

It’s still a work in progress in that I will continue adding generators for other things that people would find useful, but my automated tests and personal testing show that the functionality it currently has is quite solid and ready for use.

Wombat - Alfred Theme

While I’m on a roll with all these Alfred posts, I figure it makes sense to get one more out. So I’m sharing my Alfred Theme.

It’s based on Wombat color scheme for Emacs from this Github gist which itself is based on a Vim color scheme created by someone named Lars Nielsen who I don’t know, but whose color scheme I’ve spent the past few years of my life staring at while building awesome things in Emacs.

Now Alfred’s wearing the same outfit.

Download my Wombat Alfred Theme

Volume Adjust Alfred V2 Workflow

I had written a handy Extension to Alfred v1 awhile back to help me very quickly adjust my system volume with simple keyboard commands.

Well, with the release of Alfred v2, this Extension no longer worked. So I’ve now updated it as an Alfred v2 workflow.

Download it here

Commands for the v1 Extension still work, reference here

Alfred 2 and Emacs

Long story short, Alfred 2 and Emacs installed via Homebrew don’t exactly play along nicely. Alfred 2 doesn’t like to follow symlinks so it won’t open Emacs.

For more info, see here

I had just posted on GetSatisfaction then realized that the new (awesome!) workflows would allow me to fix this myself before they intervened.

Note, this workflow assumes that you’ve installed the latest Emacs from Homebrew with the cocoa flag (24.3 as of this writing):

Install Emacs from Homebrew
1
brew install emacs --cocoa

If you’ve got Emacs but the wrong version, update it with:

Install Emacs from Homebrew
1
2
brew update
brew upgrade emacs --cocoa

Or simply edit my workflow and update it to use the latest path.

Download my Alfred 2 workflow here

Backbone CrossDomain Library

The Problem: Microsoft and their own Cross Domain Request object

I recently came across a situation at work where I needed to do a cross domain POST on IE. We have these complex forms loaded entirely in client-side js using Backbone which we want loadable on any page but which need to submit their data directly to our API servers using CORS.

This turned out to be a non-trivial problem.

See it turns out that instead of using the XMLHttpRequest object used by jQuery or Zepto’s $.ajax(), when doing a cross domain request (such as a POST from a site served off of http://foo.com to the endpoint http://bar.com) Microsoft decided it made sense to create an entirely different request object called XDomainRequest. More details here

#comeonmicrosoft

Practically speaking, this means that neither jQuery nor Backbone work with CORS requests out of the box on IE 7, 8, and 9. Thankfully Microsoft came to their senses in IE 10 and XMLHttpRequest works fine (and so thus do jQuery and Backbone) but for earlier versions it didn’t work and sadly my company cannot yet ignore the IE populace.

The XDomainRequest functions similarly to the XMLHttpRequest object, but just different enough to be a pain.

The Solution: I created the Backbone.CrossDomain library

Our app infrastructure is all in Backbone, so I was able to write the code to handle this once and never think about it.

In my library I simply overwrote Backbone.sync which allowed the rest of our code to stay exactly the same. Things that just threw errors before on IE now just work. Like magic.

I wrote with AMD support baked in because RequireJS rocks and I tried hard to make it a drop-in replacement for the standard Backbone.sync and it still defers to Backbone.sync on every normal modern browser, but will use this XDomainRequest object when necessary.

This project is open-source and available:

On Github at https://github.com/victorquinn/Backbone.CrossDomain

and

On npm as backbone-crossdomain

Moving From Grunt 0.3.x to 0.4.x

Just moved from GruntJS version 0.3.x to 0.4.x so I could use some newer Grunt modules.

Most of the changes are covered well on the wiki though one odd thing I ran into was that after moving from Grunt 0.3.x to Grunt 0.4.x, the command line command “grunt” no longer worked for me. I kept getting the following error:

1
zsh: command not found: grunt

To cut a long story short, it appears in the move from Grunt 0.3.x to 0.4.x the folks who built Grunt felt it was a good idea to remove the cli piece.

I applaud this decision though I confess I glanced at the docs quickly and, at my first pass, didn’t notice that it had been stripped out. I was confused as to why I kept getting the grunt command not found when the package was clearly installed. Uninstalling 0.4.x and re-installing 0.3.x brought it back and the inverse killed it.

The solution

The solution ended up being quite easy, simply install the grunt-cli package to get the grunt command back:

1
% npm install -g grunt-cli