- The development of Coffee-Toaster has been discontinued.
- For more info check this note.
- Looking for a similar project? Take a look at Polvo!
Minimalist build system for CoffeeScript.
Version 0.6.13
- Inheritance support across multiples files for the lazy
- Vendors management
- Automagically packaging system with namespaces
- Micro build routines
- Exports aliases
- Broken and circular-loop dependencies validation
- Live syntax-check
- Growl support
- Debug Mode
- Minify support
- Scaffolding routines
Do not hesitate to open a feature request or a bug report.
A place to talk about it, ask anything, get in touch. Luckily you'll be answered sooner than later.
NOTE: The list is active
and maintained
, though the low activity. So don't
be shy.
Minimalist build system for CoffeeScript, made for those who dare to use class definitions in CoffeeScript while being able to easily inherit from external files. The system is powered with import directives that uses wildcards facilities, exposed scopes, excluded files filter options and a packaging system that can inject your folders-as-namespaces to all your classes based on where they are under your src folder.
CoffeeToaster was created initially as a base for creating the Theoricus Framework.
- Installing
- Scaffolding
- Usage
- Import directive
- Compile
-c
- Watch
-w
- Debug
-cd
,-wd
- Autorun
-a
,-ad
- HTML inclusion
- Advanced options
- Conclusion
- Config file
- Examples
- API
- Contributing
- CHANGELOG
npm install -g coffee-toaster
There are two simple scaffolding
routines bundled with CoffeeToaster for
creating new projects structure from the scratch and also for creating the
config toaster.coffee
file for existent projects.
CoffeeToaster suggests a very simple structure for initial projects, you can customize it as you like.
toaster -n mynewapp
You will be asked for some things:
source folder
Relative folderpath to your source folder, default is src
.
release file
Relative filepath to your release file, default is www/js/app.js
http folder
The folderpath to reach your debug file through http, default is an empty string
. Imagine that the www
is your root web folder, and inside of it you
have a js
dir where you put your debug file. In this case you'd just need to
inform 'js' as the http folder. It tells toaster how to reach your debug js
file starting from the /
on your server.
This property is only for debug, your release file will not be affected.
Considering all the default values, you'll end up with a structure as such:
myawsomeapp/
├── src
├── vendors
├── www
└── js
└── toaster.coffee
4 directories, 1 file
You can also initialize an existing project with a config toaster.coffee
file
such as:
cd existing-project
toaster -i
Some of the same information (src
, release
and httpfolder
) will be
required, answer everything according to your project's structure and a config
toaster.coffee
file will be created inside of it.
Toaster help screen.
CoffeeToaster
Minimalist build system for CoffeeScript
Usage:
toaster [options] [path]
Examples:
toaster -n myawsomeapp (required)
toaster -i [myawsomeapp] (optional)
toaster -w [myawsomeapp] (optional)
toaster -wd [myawsomeapp] (optional)
Options:
-n, --new Scaffold a very basic new App
-i, --init Create a config (toaster.coffee) file
-w, --watch Start watching/compiling your project
-c, --compile Compile the entire project, without watching it.
-d, --debug Debug mode (compile js files individually)
-a, --autorun Execute the script in node.js after compilation
-j, --config Config file formatted as a json-string. [string]
-f, --config-file Path to a different config file. [string]
-v, --version
-h, --help
The import directive is known by:
#<< app/views/user_view
#<< app/utils/*
By putting #<< app/views/user_view
in your CoffeeScript file, you're telling
CoffeeToaster that there's a dependency. It's like a require
, except that you
can't save a reference of the imported file to a variable. Instead, this
directives shoud be put in the first lines of your files.
This is how you organically tells Toaster about the specific ordering options to be considered when all of your files get merged. Files imported this way will only be gracefully sorted out in your final output javascript so every file is always defined before it's needed.
Wild cards #<< app/utils/*
are also accepted as a handy option.
If you're writing a class B
that will extends the class A
, you shoud first
import the class A
so it will be available for being extended by class B
.
- src/app/a
class A
constructor:->
console.log 'Will be used as base class.'
- src/app/b
#<< app/a
class B extends A
constructor:->
console.log 'Using class A as base class'
Think of it as a glue that you use to chain all of your files appropriately.
## CompileCompile your project according your config file.
cd existing-project
toaster -c
Starts Toaster in watching'n'compiling mode:
cd existing-project
toaster -w
Any changes you make to your src
files will trigger the compile
action.
In debug mode option -d
all files will be compiled individually inside a
folder called toaster
in the same directory you've pointed your debug file,
aiming to ease the debugging process.
toaster -wd
toaster -cd
For example, if you have release/app-debug.js
, a folder will be created at
release/toaster
and all your CoffeeScript files will be compiled to Javascript
within.
Bellow is a representative directory structure after compiling in debug mode.
/usage
|-- src
| `-- app
| |-- controllers
| | `-- users_controller.coffee
| |-- models
| | `-- user_model.coffee
| `-- views
| `-- user_view.coffee
|-- www
| `-- js
| |-- app-debug.js
| |-- app.js
| `-- toaster
| `-- app
| |-- controllers
| | `-- users_controller.js
| |-- models
| | `-- user_model.js
| `-- views
| `-- user_view.js
`-- toaster.coffee
Every CoffeeScript file is compiled individually inside the www/js/toaster
directory, so you can debug it sanely.
The debug file www/js/app-debug.js
is the boot-loader responsible for loading
all these individual compiled JS files into the right order.
In autorun mode option -a
the script is recompiled after each file change and
it is executed in a node.js child process. It is possible to use autorun in
combination with debug option -d
to set the script breakpoint on the first line
toaster -a
toaster -da
of if you like the watch
option
toaster -wa
toaster -wda
to better debug your application via node.js you can use some tools like node-inspector
It is also possible to pass arguments to the compiled script
toaster -wa argument argument2 argument3
toaster -wda argument argument2 argument3
Please note that the -a
arguments has to be the last of the group in order to
make it work: toaster -ad argument
will not behave as expected and
toaster -da argument
should be used instead
So in your .html
you'll have two options:
- Include your release file.
<script src="js/app.js"></script>
- Include the toaster boot-loader (your debug mode).
<script src="js/app-debug.js"></script>
You can pass your own config file for toaster instead of the default one
toaster.coffee
, with the -f
or --config-file
option:
toaster -wdf config/mycustomconfig.coffee
NOTE: It's important that you always call this from your project base folder, otherwise the paths of your config can get messy. Remembers also that the paths in your config file shoud ideally be always relative to your project base folder.
Alternativelly, you can even pass the whole configuration as a JSON string, with
the -j
or --config
option:
toaster -wdj '{"folders":{"src":""},"expose":"window","release":"app.js","debug":"app-debug.js"}'
NOTE: The same above.
## ConlusionEvery time something changes, CoffeeToaster recompiles all of your application by:
- collecting all .coffee files and processing everything, adding namespace's declarations to class definitions based on the folder they are located
- reordering everything, always defining files and classes before they're needed
- merge all yours vendors in the given order
- declare root namespaces
- merge everything
Due to the way VIM handles files, you'll need to disable the creation of swap
and backup
files.
To do it, just put these three lines in your .vimrc
:
" for coffee-toaster
set nobackup " no backup files
set nowritebackup " only in case you don't want a backup file while editing
set noswapfile " no swap files
This will guarantee the expected behavior of Toaster and make it play nicely with VIM without any conflicts. For more info about why it's really needed, please check this thread.
# Config file ----The toaster.coffee
is the config file from where Toaster seek all information
about your app, vendores, build options and so on. There are two main usages
you can make of this file:
- 1) Single source folder:
When all your code is bellow one single source folder your set up the main
toast
call passing the folder path directly.
# src folder
toast 'src'
# excluded items (will be used as a regex)
exclude: ['folder/to/exclude', 'another/folder', '.DS_Store' ]
# packaging vendors among the code
vendors: ['vendors/x.js', 'vendors/y.js' ]
# gereral options (all is optional, default values listed)
bare: false
packaging: true
expose: '' # can be 'window', 'exports' etc
minify: false
# httpfolder (optional), release and debug (both required)
httpfolder: 'js'
release: 'www/js/app.js'
debug: 'www/js/app-debug.js'
- 2) Multi source folder:
When your code is splitted between two or more source folders you can set the
main toast
call without any path, and inform your folders right bellow it.
toast
folders:
'src/my/app/folder': 'app'
'src/my/lib/folder': 'lib'
# ...
Let's take a closer look at all properties you can have in your toaster.coffee
file and what each one of these is responsible of.
Mandatory:
no
Type:Object
Default:null
In case you have more than one src
folder, you can set an object
of
objects
containing setup information about all your source folders, in the
format 'folderpath':'folderalias'
.
The hash-key is the path
of your folder, and the hash-value is the
alias
you want to prepend to all files under that.
Pay attention to this specially when using Toaster with the '-j' option.
To give an example, the equivalent use of this config:
toast 'src'
# ...
Would be:
toast
folders:
'src': ''
NOTE: Aliases take effect only if the packaging
is set to true
.
Aliases lets you set a virtual top namespace to your source folder, if you have
src/app/app.coffee
which is a class App
, you'll usually access it using
new app.App
.
Now if you set an alias like 'src':'awesome'
the whole structure under your
source folder will be addressed under that awesome
namespace and you need
to prepend it when accessing your classes, i.e. new awesome.app.App
.
Mandatory:
no
Type:Array
Default:[]
Let's you excplicity exclude some folder, file or file type from Toaster search/process mechanism. The string you use here will effectively turn into a RegExp like that:
new RegExp '.DS_store'
new RegExp '.swp'
new RegExp 'my/folder/to/be/excluded'
Mandatory:
no
Type:Array
Default:[]
You can define vendors such as:
vendors: ['vendors/x.js', 'vendors/y.js', ... ]
It's an ordered array of all your vendor's paths. These files must be purely javascript, preferably minified ones -- Toaster will not compile or minify them, only concatenate everything.
### `bare`Mandatory:
no
Type:Boolean
Default:false
If true
, compile your CoffeeScript files without the top-level function safety
wrapper:
(function() {
console.log('My peace of code!');
}).call(this);
So you will end up with just your peace of code
:
console.log('My peace of code!');
Mandatory:
no
Type:Boolean
Default:false
When packaging is true
, Toaster will rewrite all your class
declarations.
If you have a file in src/app/models/user.coffee
with this contents:
class User
Toaster will rewrite your declaration prepending a namespace
to it, based on
the folder the class is located, resulting -- in this example -- into this:
class app.models.User
This rewriting process is saved directly into your file
. In case you move
this class to another folder, the prepended namespace
will be rewrited again,
always following your folder structure.
In other words, your don't need to worry about hardcoded namespaces in your files, because Toaster will handle all the dirty for you.
### `expose`Mandatory:
no
Type:String
Default:null
If informed, list all you packages of classes in the given scope. If you use
window
as your expose scope, your classes will be available also in the window
object -- or whatever scope you inform, suck as exports
if you're building
for NodeJS.
In the end you'll be able to access your files throught this scope where your classes was exposed.
new window.app.models.User
new exports.app.models.User
Mandatory:
no
Type:Boolean
Default:true
If true
, minify your release file using UglifyJS.
Debug files are never minified.
### `httpfolder`Mandatory:
no
Type:String
Default:''
The folder path to reach your debug file through http, in case it is not inside
your root directory. Imagine that the www
is your root folder and when you
access your webiste the /
referes to this folder.
Inside this www
folder you have another folder called js
where you put all
your compiled js, resulting from a config like this:
toast 'src'
# ...
release: 'www/js/app.js'
debug: 'www/js/app-debug.js'
Following this case you'd just need to inform js
as your http folder. Toaster
will use it to reach your debug files. For that, it will writes the
declarations inside the debug boot loader
following this location in order to
import your scripts properly when in debug mode, prepending your httpfolder
to
all file paths:
// app-debug.js
document.write('<scri'+'pt src="js/toaster/app.js"></scr'+'ipt>')
Without knowing that your JS files is under the js
folder this path would be
broken.
NOTE: Your release file will not be affected by this property.
### `release`Mandatory:
yes
Type:String
Default:null
The file path to your release file.
### `debug`Mandatory:
yes
Type:String
Default:null
The file path to your debug file.
# Examples ----You'll certainly find some useful resources in the examples provided. Examine it and you'll understand how things works more instinctively.
Install coffee-toaster, clone the usage example and try different config options, always looking for the differences in your javascript release file.
# API ----
You can use Toaster through API as well, in case you want to power up your compiling tasks or even build some framework/lib on top of it.
See the API example for further information.
Toaster = (require 'coffee-toaster').Toaster
toasting = new Toaster [basedir], [options], [skip_initial_build]
toasting.build [header_code_injection], [footer_code_injection]
Environment setup is simple achieved by:
git clone git://github.com/serpentem/coffee-toaster.git
cd coffee-toaster && git submodule update --init
npm link
Builds the release file inside the lib
folder.
make build
Starts watching/compiling using a previuos version of the CoffeeToaster itself.
make watch
Run all tests.
make test