How do I use Node and Express with coffeescript and requirejs?


Here's what I want.

  • A node application using the express webserver
  • Using coffeescript on the server and more importantly the client
  • Using require.js on the client (and eventually on the server)

The recommended way I've been able to find of hooking up coffeescript for the client is to use connect-assets. This seems to require using jade helpers to actually compile coffeescript eg.


seems to compile and generate the correct <script> tag. Now I want to use require.js and here I stumble. How do I ensure that connect-assets compiles everything correctly without using the jade helpers?

Here's my fairly simple app.js:


var express = require('express')
  , http = require('http')
  , path = require('path')
  , connectAssets = require('connect-assets');

var publicDir = path.join(__dirname, 'public');

var app = express();

  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');


  app.use( connectAssets() );
  app.use('/public', express.static(publicDir));


app.configure('development', function(){
    dumpExceptions: true,
    showStack: true

app.get('/', require('./routes').index);
app.get('/monalisa', require('./routes/monalisa').monalisa);

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
Problem courtesy of: George Mauer


I've created a package to help solve this problem; it's called connect-assets-jspaths.

From the readme:


npm install connect-assets-jspaths

  • Note, there is a dependency on CoffeeScript.

Server Side Usage

assets = require "connect-assets"
jsPaths = require "connect-assets-jspaths"

# Snip ...

app.use assets()
# Exports the global function exportPaths() and jsUrl(); see below in View Helpers.
jsPaths assets

# Optionally, pass a log function to see progress
# jsPaths assets, console.log

Watch changes and re-compile

Now you can pass some additional callbacks in and it will monitor your connect assets directories for changes.

fileChangedCallback = (err, filePath) ->
    console.log "File Changed: #{filePath}"

jsPaths assets, console.log, fileChangedCallback, (err, watcher) ->
    console.log "Watcher initialized"

NOTE You'll probably want to disable this for production mode.

View Usage

This module exports two global functions exportPaths() and jsUrl().

// Using this in your view
!= exportPaths("jsPaths")

// Turns into this when rendered in production
<script type="text/javascript">
    var jsPaths = { "main", "/builtAssets/js/main.13819282742.js" /* snip all the other file paths */ };

// Using this in your view
- var mainJsPath = jsUrl("/js/main.js")
script(type="text/javascript", data-main="#{mainJsPath}", src="//")    

// Turns into this when rendered in production
<script type="text/javascript" data-main="/builtAssets/js/main.13819282742.js" src="//"></script>

Dynamic RequireJS Paths

Now that we have a variable with our requireJS friendly paths in it, we can set those paths in the RequireJS config

# Example file in /assets/js folder

requirePaths =
    jquery: "//"
    underscore: "//"
    backbone: "//"
    text: "/js/lib/text"
    handlebars: "/js/lib/handlebars"

if jsPaths
  for own key, value of jsPaths
    # Fix up the lib references
    key = key.slice 4 if key.slice(0, 4) == "lib/"
    requirePaths.paths[key] = value 

  paths: requirePaths.paths

      exports: "$"
      exports: "_"
      deps: ["underscore", "jquery"]
      exports: "Backbone"

require ['app'], (App) ->
    new App().initialize()
Solution courtesy of: Jacob


Try mimosa, it'll help you with each one of those things out of the box.

mimosa new [name] will give you a starter project with all of it.

Discussion courtesy of: David Bashford

Sorry for the new answer, but I decided to go make an account. =)

Mimosa will give you a small Express application if you choose Express as part of the mimosa new workflow. And if you choose CoffeeScript it'll give you an Express app in CoffeeScript. And it'll have RequireJS included in the scaffolded application. So you should not need to rewrite anything. You just need to plug your stuff in. If anything the Express app it gives you will serve as an example for you to do it yourself without using Mimosa.

Discussion courtesy of: David Bashford

This recipe can be found in it's original form on Stack Over Flow.