It is cold, but · we have Sake · and the hot spring
Sake is a build tool and task runner for JavaScript. Sake features an extensible core and support for modern JS. Inspired by Cake, Sake is the perfect DSL for building projects.
npm install sake-core --save-dev
Typically Sake is used via it's command line interface which can be installed
with npm install -g sake-cli
. Once the sake
command is
available, you can begin writing a Sakefile
and defining available tasks in
your project.
Sake will search for a Sakefile with tasks defined for your current project. Sakefiles can be written in ES2015 JavaScript and support modules natively.
Optionally, you can write your Sakefile in CoffeeScript, which allows a very nice DSL-ish experience.
Async tasks are easy to declare, any task with an obvious callback will be
treated as asynchronous. Add an additional argument called callback
, cb
,
done
or next
and use it to indicate when your task is finished executing.
task 'compile:js', 'compile js', (done) ->
exec 'coffee -bc app.coffee', done
task 'minify:js', 'minify js', (done) ->
exec 'uglify-js --compress --mangle app.js > app.min.js', done
You can also return a promise from your task and sake will automatically
wait for it to resolve. Since executive
returns a promise, this works too:
task 'compile:js', 'compile js', ->
exec 'coffee -bc app.coffee'
You can manually invoke tasks and string them together with callbacks:
task 'build', 'build project', ->
invoke 'compile:js', ->
invoke 'minify:js'
Dependencies can be declared by adding an array of task names after your task's description.
task 'build', 'build project', ['compile:js', 'minify:js']
You can also pass an array of tasks invoke
and it will execute them in order
for you:
task 'build', 'build project', (done) ->
invoke ['compile:js', 'minify:js'], done
...or more explicitly using invoke.serial
.
If you want to execute tasks in parallel you can use invoke.parallel
.
task 'compile', 'compile css & js', (done) ->
invoke.parallel ['compile:css', 'compile:js'], done
You can check for running tasks using the running
helper.
task 'watch', 'watch for changes and re-compile js', ->
exec 'coffee -bcmw -o lib/ src/'
task 'watch:test', 'watch for changes and re-run tests', (options) ->
invoke 'watch'
require('vigil').watch __dirname, (filename, stats) ->
return if running 'test'
if /^test/.test filename
invoke 'test', test: filename
if /^src/.test filename
invoke 'test'
You can also use yield
to wait for the value of a promise and eschew the use
of callbacks.
task 'compile:js', 'compile js', ->
yield exec 'coffee -bc app.coffee'
task 'minify:js', 'minify js', ->
yield exec 'uglify-js --compress --mangle app.js > app.min.js'
This really pays dividends with more complicated tasks:
task 'package', 'Package project', ->
yield exec '''
mkdir -p dist
rm -rf dist/*
'''
yield exec.parallel '''
cp manifest.json dist
cp -rf assets dist
cp -rf lib dist
cp -rf views dist
'''
yield exec '''
zip -r package.zip dist
rm -rf dist
'''
You can upgrade any Cakefile into a Sakefile by requiring sake-core
at the top
of your Cakefile.
You can peruse Sake's Sakefile for a real world example.