This is project represents the skeleton of an application with node.js server-side and backbone.js client-side. All JavaScript is written using CoffeeScript, all CSS is written using Compass and SASS, all templates are written using underscore.js and all client-side JavaScript is packaged using Jammit. A utility class is provided that automatically recompiles & packages all of these pre-processor languages every time you hit save, so you can iterate quickly: make a code change, hit refresh. It is primarily for my own personal use as I develop projects using these technologies, but may be handy for others too. I will gradually evolve and improve this structure as I become more familiar with these JavaScript tools.
gem install compass
npm install glob
- Add the NODE_ENV=development to your environment variables (e.g. add
export NODE_ENV=development
to.bash_profile
) - Run with
node server.js
(orsupervisor server.js
to get "hot redeploy") - Go to http://localhost:8003
- Make changes to the code and watch the CoffeeScript, SASS and templates get recompiled as soon as you hit save
- Server: node.js + express
- Client-side MVC: backbone.js
- Templating: underscore.js
- Preprocessor: CoffeeScript
- Client-side library: jQuery
- Stylesheets: Compass and SASS
- Config: node-settings
- /bootstrap: client-side JS files used to bootstrap the application, e.g. setup the namespace as well as create the backbone.js controllers, models and views.
- /compiled: all files compiled to JavaScript - namely, all the CoffeeScript and templating code - is dumped in this directory. You should never need to change anything in here by hand.
- /config: configuration settings for the project.
- /controllers: backbone.js controllers.
- /lib: 3rd party libraries, including jQuery, underscore.js and backbone.js.
- /models: backbone.js models.
- /node_modules: node.js modules installed via npm, including express, watch-tree, node-utils and underscore.js.
- /public: all static content (CSS, JS, images) publicly visible to the browser gets dumped here.
- server.coffee: the main node.js server file. Gets automatically compiled into server.js using /util/watcher.coffee.
- /stylesheets: SASS stylesheets go here and are compiled when you hit save via Compass into /public/css.
- /templates: underscore.js templates go here and are compiled when you hit save into /compiled/templates.
- /util: utility class that auto-recompiles and packages all the JavaScript and CSS.
- /views: backbone.js views.
This class is loaded by server.js
at startup to watch the project using watch-tree and recompile and package files as necessary so that you can iterate quickly. The goal is to support "make a change, hit reload" style development even though this project uses a number of pre-processors that require "compilation". It works reasonably well already and as I improve, I'll likely break this off into its own Github/NPM project.
Sample usage:
var Watcher = require('./util/watcher').watcher;
var options = {
compass: 'config/config.rb',
verbose: true,
templates: templates,
package: 'config/jammit.yml',
packageOut: 'public/js',
paths: {
'server.coffee': {type: 'coffee', out: '.'},
'templates/**/*.html': {type: 'template', out: 'compiled/templates', package: true},
'views/**/*.coffee': {type: 'coffee', out: 'compiled/views', package: true}
}
};
var watcher = new Watcher(options);
watcher.watch();
Executing the watch()
function does the following:
- Runs
compass watch
if a config file is specified inoptions.compass
- Watches over the root directory (as specified in
options.root
or'.'
by default) and takes action any time a file changes that matches one of the keys (globs processed using node-glob). The action taken depends on thetype
:- coffee: compiles the file using CoffeeScript and puts the output into the directory specified by
out
- template: compiles the template using underscore.js and puts the output into the directory specified by
out
. Also adds this template by filename into the object specified inoptions.templates
: e.g. iffoo.html
changed,foo.js
would be created andoptions.templates['foo']
would be set to the compiled function. - If
package: true
is specified, will also run Jammit using the config file specified inoptions.package
and put the output in the folder specified inoptions.packageOut
- coffee: compiles the file using CoffeeScript and puts the output into the directory specified by