What is the best way to do Dependency Management amongst CoffeeScript files if the resulting javascript files eventually need to be concatenated together for use on the client side?
For server side CoffeeScript I can just use the 'require' keyword to require other pieces of javascript. When this is piled for client side apps to have the dependency tree, based on the requires, calculated and a concatenated stand alone javascript file produced. Is there anyway to do this in a generic way?
What is the best way to do Dependency Management amongst CoffeeScript files if the resulting javascript files eventually need to be concatenated together for use on the client side?
For server side CoffeeScript I can just use the 'require' keyword to require other pieces of javascript. When this is piled for client side apps to have the dependency tree, based on the requires, calculated and a concatenated stand alone javascript file produced. Is there anyway to do this in a generic way?
Share Improve this question asked Nov 10, 2010 at 19:16 Douglas SellersDouglas Sellers 6622 gold badges7 silver badges14 bronze badges5 Answers
Reset to default 3Another option is to use CoffeeToaster, which uses another approach than implementing AMD / CJS module patterns.
Take a look: http://github./serpentem/coffee-toaster
Usually, for client-side packaging of JavaScript (and CSS), you want some sort of asset-packaging plugin. We use Jammit, but there are many other options: Sprockets, Django-Compress ... and more.
Villain (a CoffeeScript game engine for browsers) defines functions that do just that (dependency management and js concatenation).
The code for that is in these two files:
- cake.coffee, see ,
determineDependencies()
,wrapModule()
, andbundleSources()
- brequire.coffee, a require replacement for the browser, to use with
wrapModule()
I use it here (see the 'bundle'
Cake task).
Note: I just declare the 'main'
module's build directory, and Villain scans my piled JS files to build the dependency tree (starting with index.js
), then creates a JavaScript bundle file containing Villain's require
replacement and all my relevant code sorted and correctly wrapped.
Villain's author uses it in orona, a CoffeeScript game made with Villain.
For dependency management on client side, I use requirejs for javascript and coffeescript source. It'possible to use a requirejs plugin to load natively coffee files, but I prefer to "pile" into js.
requirejs also provide / work with r.js optimizer. It can be used to aggregate a set of js file into one and minified it. you don't have to specify the file to aggregate it is the dependency definition of each module require by your "main.js". (feature that match your request)
Something I like a lot with requirejs, it "promots" creating module and declare explicit dependencies.
# A.coffee
define(() ->
class A
constructor: (@c1, @c2) ->
@c2 ?= 1
m1 : () ->
"hello"
toString : () -> "#{@c1}#{@c2}"
)
# B.coffee
define(['A'], (A) ->
a = new A(33)
console.log(a, a.m1())
)
I've used (and I guess am still using) requirejs but I've started to find it to be fairly clumsy. A lot of my files end up having ~10-12 imports at the top which just take up a lot of space and don't look great.
For a new project I tried browserify. It's great! And if you use grunt (you should), you can make a watch task to browserify your code on change. grunt-browserify
also provides the ability to do a coffeescript transform.
https://github./jmreidy/grunt-browserify
So your watch task in your Gruntfile.coffee
would look something like:
watch:
files: [
"app/**/*.coffee"
]
tasks: "browserify"
browserify:
'build/app.js': ['app/**/*.coffee']
options:
transform: ['coffeeify']