node package manager


Javascript build tools based on coffee-script & cake


Flour is a set of simple build tools for your Cakefiles.


Add flour and your required pre-processors/compilers to your package.json:

  "name": "dancingrobot",
  "dependencies": {
    "flour": "",
    "uglify-js": "",
    "coffee-script": ""

Then run npm install, and require 'flour' at the top of your Cakefile. A few methods are available in the global scope.

This is what a typical Cakefile could look like:

require 'flour'

task 'build:coffee', ->
    compile 'coffee/', 'js/app.js'

task 'build:less', ->
    compile 'less/main.less', 'css/main.css'

task 'build:plugins', ->
    bundle [
    ], 'js/plugins.js'

task 'build', ->
    invoke 'build:plugins'
    invoke 'build:coffee'
    invoke 'build:less

task 'watch', ->
    invoke 'build:less'
    invoke 'build:coffee'

    watch 'less/*.less', -> invoke 'build:less'
    watch 'coffee/', -> invoke 'build:coffee'

task 'lint', 'Check javascript syntax', ->
    lint 'js/feature.js'

(if the global pollution hurts your feelings you can remove them with flour.noConflict(). That will bring the global object back to it's previous state)

Each of these functions accepts either a file path or a list of files. Simple wildcard paths (*.xxx) are allowed. For example:

watch [
], -> invoke 'build:less'

You can also access the resulting output by passing a callback:

compile 'coffee/', (output) ->
    # do something with the compiled output
    mail.send subject: 'Project file', to: '', body: output

# verify the CoffeeScript compiler output
compile 'coffee/', 'js/app.js', -> lint 'js/app.js'

These are the current adapters and the required modules:

  • CoffeeScript: coffee-script
  • LESS: less
  • Stylus: stylus
  • Javascript: uglify-js
  • Javascript: 'jshint'

Creating new adapters is very easy, take a look at the adapters/ folder for guidance.

Compile CoffeeScript, LESS, Stylus, Handlebars templates:

compile(file, [destination], [callback])
compile '', 'app.js'

compile '', 'app.js', (output) ->
    console.log 'Done!'

compile '', (output) ->
    console.log output.transform()

Some compilers may accept options that will get proxied to their respective libraries. For example, you can disable compression for LESS or Stylus with

flour.compilers.less.compress = false
flour.compilers.styl.compress = false

Or customize the LESS include path with

flour.compilers.less.paths = ['/path/to/my/less/libs/']

Compile, minify and join a set of files:

bundle(files, destination)
// preservers the list order
bundle [
], 'js/bundle.js'

// system-dependent order
bundle 'js/*.js', 'js/all.js'

Watch files for changes:

watch(files, action)
watch 'src/', ->
    compile 'lib/app.js'

# best used with predefined tasks:

task 'build', ->
    bundle '*.coffee', 'app.js'

task 'watch', ->
    watch [
    ], ->
        invoke 'build'

# or simply
task 'watch', ->
    watch '*.coffee', -> invoke 'build'

Check file syntax (uses JSHint):

lint(file, [options], [globals]) # see
task 'lint', ->

    lint 'scripts/*.js'

Minify files (currently only Javascript using UglifyJS):

minify(file, [destination], [callback])

You can add new minifiers and compilers to flour:

flour.minifiers['dumb'] = (file, cb) -> (code) ->
        cb code.replace(/\s*/, '')

flour.compilers['odd'] = (file, cb) ->
    odd = require 'odd-lib' (code) ->
        cb odd.compile code
task 'watch', ->
    flour.minifiers.disable 'js'

    watch 'scripts/*.coffee', -> invoke 'build'
flour.compilers['mustache'] = (file, cb) ->
    hogan = require 'hogan.js' (code) ->
        cb "App.templates['#{file.base}']=${hogan.compile code, asString: true};"

task 'build:templates', ->
    bundle 'views/*.mustache', 'resources/views.js'

While Grunt, brewerjs, H5BP-build-script, Yeoman and other similar projects have the same (and some more advanced) capabilities, they are increasingly complex to setup.

The goal of Flour is to provide a small and simple API that caters for the most common build tasks, without requiring you to adjust your project structure, install command-line tools or create long configuration files.

  • fixes for CoffeeScript v1.7
  • enable options forwarding for minifiers
  • fix bundle behaviour when no output path given
  • coffeescript sourcemap support
  • pass through all options to adapters. white-listing is not mantainable.
  • add markdown compiler
  • flour.minifiers.disable('js'), enables/disables all if no argument given
  • compile handlebars *.hbs templates
  • expand paths containing patterns inside bundle() array argument (#22)
  • mkdir_p on compile (#20)
  • compatibility fix for CoffeeScript 1.5.0
  • fix lint callback arguments
  • breaking change: call callback only once when watching multiple files. each file is a key in the results object
  • add yuicompress option for LESS compiler
  • output to multiple files with flour.compile 'src/*.coffee', '*' and variations
  • handle single file path as input for bundle()
  • better handling of wildcard paths using minimatch
  • add back support for uglify-js < 2.0
  • tests!
  • fix file buffer bug
  • accept options for adapters, enables disabling compression for LESS and Stylus
  • bugfixes
  • add node-hound as a dependency for file watching
  • watch whole directory trees: watchsrc/`, -> invoke 'build' (listens for new files and deletes too)
  • fix error handlers leak
  • fix extension handling bug
  • flour doesn't install it's adapter dependencies anymore, it's up to you to add them to your project's package.json