Home » Nodejs » Client Side Dependency Management in CoffeeScript

Client Side Dependency Management in CoffeeScript

Posted by: admin November 30, 2017 Leave a comment

Questions:

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 compiled 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?

Answers:

Another option is to use CoffeeToaster, which uses another approach than implementing AMD / CJS module patterns.

Take a look:
http://github.com/serpentem/coffee-toaster

Questions:
Answers:

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.

Questions:
Answers:

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(), and bundleSources()
  • 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 compiled 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.

Questions:
Answers:

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 “compile” 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())
)

Questions:
Answers:

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.com/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']