Skip to content

Commit

Permalink
Move all watch functionality into watcher.coffee.
Browse files Browse the repository at this point in the history
  • Loading branch information
brikis98 committed May 22, 2011
1 parent a004221 commit 2e0e9fe
Show file tree
Hide file tree
Showing 27 changed files with 1,199 additions and 118 deletions.
38 changes: 38 additions & 0 deletions .gitignore
@@ -0,0 +1,38 @@
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so

# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# Logs and databases #
######################
*.log
*.sql
*.sqlite

# OS generated files #
######################
.DS_Store
ehthumbs.db
Icon?
Thumbs.db
.sass-cache
.data
mnt

68 changes: 37 additions & 31 deletions README.md
@@ -1,6 +1,6 @@
# Overview

This is project represents the skeleton of an application with [node.js](http://nodejs.org/) server-side and [backbone.js](http://documentcloud.github.com/backbone/) client-side. 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.
This is project represents the skeleton of an application with [node.js](http://nodejs.org/) server-side and [backbone.js](http://documentcloud.github.com/backbone/) client-side. All JavaScript is written using [CoffeeScript](http://jashkenas.github.com/coffee-script), all CSS is written using [Compass](http://compass-style.org/) and [SASS](http://sass-lang.com/), all templates are written using [underscore.js](http://documentcloud.github.com/underscore/) and all client-side JavaScript is packaged using [Jammit](http://documentcloud.github.com/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.

# Technologies

Expand All @@ -13,41 +13,47 @@ This is project represents the skeleton of an application with [node.js](http://

# Directory structure

* /bootstrap: client-side JS files used to bootstrap the application, e.g. create the [backbone.js](http://documentcloud.github.com/backbone/) controllers, models and views.
* /compiled: all files compiled to JavaScript - namely, all the [CoffeeScript](http://jashkenas.github.com/coffee-script) and templating code - is dumped in this directory.
* /bootstrap: client-side JS files used to bootstrap the application, e.g. setup the namespace as well as create the [backbone.js](http://documentcloud.github.com/backbone/) controllers, models and views.
* /compiled: all files compiled to JavaScript - namely, all the [CoffeeScript](http://jashkenas.github.com/coffee-script) 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](http://documentcloud.github.com/backbone/) controllers.
* /lib: 3rd party libraries, including [jQuery](http://jquery.com/), [underscore.js](http://documentcloud.github.com/underscore/) and [backbone.js](http://documentcloud.github.com/backbone/).
* /models: [backbone.js](http://documentcloud.github.com/backbone/) models.
* /node_modules: [node.js](http://nodejs.org/) modules installed via npm, including [express](http://expressjs.com/), [watch-tree](https://github.com/tafa/node-watch-tree), and [underscore.js](http://documentcloud.github.com/underscore/).
* /node_modules: [node.js](http://nodejs.org/) modules installed via npm, including [express](http://expressjs.com/), [watch-tree](https://github.com/tafa/node-watch-tree), [node-utils](https://github.com/mikeal/node-utils) and [underscore.js](http://documentcloud.github.com/underscore/).
* /public: all static content (CSS, JS, images) publicly visible to the browser gets dumped here.
* server.coffee: the main [node.js](http://nodejs.org/) server file. Gets automatically compiled into server.js using /util/watch.rb.
* server.coffee: the main [node.js](http://nodejs.org/) server file. Gets automatically compiled into server.js using /util/watcher.coffee.
* /stylesheets: [SASS](http://sass-lang.com/) stylesheets go here and are compiled when you hit save via [Compass](http://compass-style.org/) into /public/css.
* /templates: [underscore.js](http://documentcloud.github.com/underscore/) templates go here and are compiled when you hit save into /compiled.
* /util: utility classes, described below.
* /templates: [underscore.js](http://documentcloud.github.com/underscore/) 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](http://documentcloud.github.com/backbone/) views.

# Utility classes

### watch.rb

Ruby class that uses [FSSM](https://github.com/ttilley/fssm) to watch the directories above and when a change is detected:

* Compiles [CoffeeScript](http://jashkenas.github.com/coffee-script) files into .js files, putting client side ones under /compiled.
* Uses [Jammit](http://documentcloud.github.com/jammit/) to concatenate and compress all .js files under /compiled into a single file under /public/js/assets.js

Run this class while coding by executing `ruby util/watch.rb`.

### watch.js

JavaScript class that uses [watch-tree](https://github.com/tafa/node-watch-tree) to watch the /templates directory and when a change is detected in a file *foo*:

* Compiles the template into an efficient JavaScript function
* Adds this function to the templates object of server.js so it can be used server-side by calling `templates['*foo*']`
* Writes this function into /compiled/*foo*.js so that it can be included client-side and rendered by calling `window.templates['*foo*']. This step is only done during development, not during production.

This class runs automatically whenever server.js is running.

### Compass

You must install [Compass](http://compass-style.org/) separately so that it can compile your [SASS](http://sass-lang.com/) code every time you hit save. Run it using the command `compass watch -c config/config.rb`.
# /util/watcher.coffee

This class is loaded by `server.js` at startup to watch the project using [watch-tree](https://github.com/tafa/node-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:

```javascript
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 in `options.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 (which are regular expressions). The action taken depends on the `type`:
** coffee: compiles the file using [CoffeeScript](http://jashkenas.github.com/coffee-script) and puts the output into the directory specified by `out`
** template: compiles the template using [underscore.js](http://documentcloud.github.com/underscore/) and puts the output into the directory specified by `out`. Also adds this template by filename into the object specified in `options.templates`: e.g. if `foo.html` changed, `foo.js` would be created and `options.templates['foo']` would be set to the compiled function.
** If `package: true` is specified, will also run [Jammit](http://documentcloud.github.com/jammit/) using the config file specified in `options.package` and put the output in the folder specified in `options.packageOut`
2 changes: 1 addition & 1 deletion bootstrap/namespace.coffee
@@ -1 +1 @@
window.NameSpace = {} # Change "NameSpace" to an appropriate name for all your classes
window.NameSpace = {} # Change "NameSpace" to an appropriate name for all your classes
5 changes: 5 additions & 0 deletions compiled/bootstrap/bootstrap.js
@@ -0,0 +1,5 @@
(function() {
$(function() {
return console.log('Put any bootstrap code here, such as creating your backbone models, controllers and views.');
});
}).call(this);
3 changes: 3 additions & 0 deletions compiled/bootstrap/namespace.js
@@ -0,0 +1,3 @@
(function() {
window.NameSpace = {};
}).call(this);
7 changes: 7 additions & 0 deletions compiled/controllers/FooController.js
@@ -0,0 +1,7 @@
(function() {
NameSpace.FooController = Backbone.Controller.extend({
routes: {
'foo': 'bar'
}
});
}).call(this);
13 changes: 13 additions & 0 deletions compiled/lib/Foo.js
@@ -0,0 +1,13 @@
(function() {
var Foo;
Foo = (function() {
function Foo(bar) {
this.bar = bar;
}
Foo.prototype.explain = function() {
return console.log('Put your own custom libraries/classes in this package');
};
return Foo;
})();
NameSpace.Foo = Foo;
}).call(this);
7 changes: 7 additions & 0 deletions compiled/models/FooModel.js
@@ -0,0 +1,7 @@
(function() {
NameSpace.FooModel = Backbone.Model.extend({
defaults: {
foo: 'bar'
}
});
}).call(this);
4 changes: 4 additions & 0 deletions compiled/templates/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions compiled/views/FooView.js
@@ -0,0 +1,7 @@
(function() {
NameSpace.FooView = Backbone.View.extend({
events: {
'click #foo': 'bar'
}
});
}).call(this);
9 changes: 6 additions & 3 deletions config/jammit.yml
Expand Up @@ -6,7 +6,10 @@ javascripts:
- dependencies/jquery-1.6.1.min.js
- dependencies/underscore-min.js
- dependencies/backbone-min.js
- compiled/namespace.js
- compiled/bootstrap/namespace.js
- compiled/lib/*.js
- compiled/mvc/*.js
- compiled/bootstrap.js
- compiled/models/*.js
- compiled/controllers/*.js
- compiled/views/*.js
- compiled/templates/*.js
- compiled/bootstrap/bootstrap.js
3 changes: 3 additions & 0 deletions controllers/FooController.coffee
@@ -0,0 +1,3 @@
NameSpace.FooController = Backbone.Controller.extend
routes:
'foo': 'bar'
43 changes: 43 additions & 0 deletions node_modules/file/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2e0e9fe

Please sign in to comment.