Coffeescript is a syntax improvement system for javascript. Files written in coffeescript are converted to javascript and then run normally. I use coffeescript because it is more concise, easier to read and there is a good support in meteor.

For information about how to write coffeescript, refer to coffeescript.org.

The example in this post is available on github, run git clone https://github.com/RemyNoulin/coffeescript.git to download it. The git shows how to use global variables with coffeescript in meteor.

‘coffee.jsoriginal’ is the default meteor app that we get after ‘meteor create’. ‘coffee.coffeeConvertedwith_j2c_from_js’ is the result of j2c (read below for how to use j2c).

js2coffee coffee.jsoriginal > coffee.coffeeConvertedwith_j2c_from_js

Contents

  1. Install

  2. Coffeescript in node

  3. Convert javascript to coffeescript with j2c

  4. Meteor

  5. Debug in web browsers

  6. Mobile platform

  7. Tips

1. Install

To start using coffeescript, add the coffeescript package to the project. When this is not installed, the coffee files are not interpreted.

meteor add coffeescript

I also install coffeescript in node to be able to convert a coffee file to javascript from the terminal, check the scopes and make sure there are no indentation errors.

npm install -g coffee-script

2. Coffeescript in node

To run a coffeescript in node, simply run:

coffee example.coffee

To convert a coffeescript to javascript, run:

coffee --compile --print --bare --no-header example.coffee

3. Convert javascript to coffeescript with j2c

To convert javascript to coffeescript, I use j2c:

npm install --global js2coffee
js2coffee example.js > example.coffee

In the resulting coffeescript, I add empty lines and javascript comment with ‘###’.

Sometimes j2c adds extraneous variable declarations (var example), I remove them since they are already declared by coffeescript.

4. Meteor

Meteor handles coffeescript just as javascript.

To keep comments from coffeescript after conversion to javascript, I use block comments: ‘###’:

###
# a comment
###

All variables are local in coffeescript. So to declare global variable, I store them in a global object which itself is declared in javascript or in a coffee file using embedded javascript.

To declare global functions or objects, I use embedded javascript (`` for each javascript statement/block) at the end of the coffee file:

globalVarsLocal =
  example: 1
  another: 2

exampleLocal = new (Mongo.Collection)('example')
# Global declarations                                                                                     
`example = exampleLocal`
`globalVars = globalVarsLocal`

I declare the global variable in coffeescript with the suffix Local (exampleLocal above), then in the embedded javascript I assign the coffeescript variable to the global one without the suffix (example = exampleLocal).

When there is a syntax error in a client file, I sometimes get the error message in the web console.

5. Debug in web browsers

Debugging coffeescript in chrome and firefox is straightforward. I step and set breakpoints in the coffeescripts just as normal javascripts.

The javascript version of the coffee files are also available in the source list.

6. Mobile platform

The configuration for the mobile platform is stored mobile-config.js, as of today (Meteor 1.1.0.2) the mobile-config cannot be written in coffeescript. ‘mobile-config.coffee’ is not recognized by meteor, there is an issue for this on github.

7. Tips

string interpolation works with double quotes but not with single quotes:

i = 'index'
# single quote: no interpolation
console.log 'i is #{ i }'

# double quotes: interpolation
console.log "i is #{ i }"

Sometimes {} delimters are needed to seperate object parameters in function calls:

# one object
tasks.update _id: document._id, $set: type: 'task'

# two objects
tasks.update {_id: document._id}, $set: type: 'task'
// one object
tasks.update({
  _id: document._id,
  $set: {
    type: 'task'
  }
});

// two objects
tasks.update({
  _id: document._id
}, {
  $set: {
    type: 'task'
  }
});