yasc

Yet Another Script Compiler: A system to watch directories for specific files and compile them with a given engine.

npm install yasc
4 downloads in the last month

YASC - Yet Another Script Compiler

YASC will monitor directories and compile or transform files based on a given regex and pack name.

It's kind of like Grunt or Guard, but it's stupid simple and easy to use.

Installation

You know the spiel. npm install -g yasc

Usage (Command Line)

yasc --config=/path/to/config

If a config file isn't passed, it will look for a file called yasc.json in the current directory. If it can't find yasc.json, it explodes and yells at you.

API

It's really simple. require('yasc') exports 5 methods.

  • yasc.config() can be passed an object that will act as the configuration for YASC.
  • yasc.parseConfig() takes 2 arguments, loc (location) and cb (callback), checks that the given configuration file exists, then reads it, and once finished calls the callback with the config as the argument.
  • yasc.newWorker() will wait until it's safe to spawn a worker, spawn one, and once it's online, call the callback you pass it with the worker as the argument.
  • yasc.perform() takes 2 arguments, cnf (config) and file. It will spawn a new worker and perform an action on the given file, based on the given config block.
  • yasc.watch() fires up the watch loop. No arguments.

You'll probably never need to use yasc.newWorker() or yasc.perform() unless you're insane.

It's really easy to fire up an instance of YASC from within a script.

var yasc = require('yasc');

yasc.config({
    '/path/to/scss' : {
        'use' : 'sass',
        'for' : '\\.scss$',
        'out' : '{{name}}.css'
    }
});

yasc.parseConfig();
yasc.watch();

Cofiguration

{
    "/path/to/less" : {
        "use" : "less",
        "for" : "\\.less$",
        "out" : "{{name}}.css"
    }
}

This config will monitor /path/to/less, and upon any file change or creation, if that file ends with .less, it will use the "less" pack to compile it to the original filename's name, but instead of .less it'd become .css.

It supports multiple engines too, in a sense.

If you have something such as CoffeeScript that you want compiled but also minified, you can do the following:

{
    "/path/to/coffeescript" : {
        "use" : "coffeescript",
        "for" : "\\.coffee$",
        "out" : "{{name}}.js",
        "then" : {
            "use" : "uglify",
            "out" : "{{name}}.min.js"
        }
    }
}

This config will monitor /path/to/coffeescript, and compile any changed files that are .coffee to the same name, with .js as the extension. Afterwards, it will use the uglify pack to minify the resulting js file to .min.js. If the original file was script.coffee, the resulting files created would be script.js and script.min.js.

It is recursive, so you can have a then directive inside of another then directive.

Warning

If you want to perform multiple actions on a file, such as compiling then minifying, it's best to use then directives. The system is asynchronous, and can act on multiple files at once using workers. then directives are synchronous, so anything inside of a then block will happen only after the encapsulating block has finished.

How it Works

This is probably a good thing to know, especially if you plan on implementing it in a server or the likes.

YASC uses workers to perform actions on files. First, it gets the number of CPUs in your system. The master process monitors directories based on the config, and when an action needs to be taken, spawns a worker process to do it. If, at any point, there are as many workers spawned as there are CPUs, it will not spawn any more workers until one has died. The number of workers will never exceed the number of processors. At some point, likely 0.2, I'll be adding the ability to choose whether or not workers are spawned.

If, at any point, a file is being acted upon by a worker and is modified again, triggering another action, the current worker acting upon it will be killed in favor of the new one to be spawned. This ensures that no superfluous workers are alive at any point in time.

YASC knows of any files that it has created. This means that if you have a directory that searches for files ending in .js to minify them, any resulting minified files created by YASC will not be acted upon.

Packs

YASC comes currently with 5 preinstalled packs:

  • Coco
  • Coffeescript
  • LessCSS
  • SASS/SCSS
  • Uglify.JS

Creating Packs

Creating packs is ridiculously simple (no seriously). All you need to do is add the dependencies inside of package.json, then create a file, pack_name.js, inside of the packs directory. This file needs one method only: module.exports.compile. All that needs to do is take incoming data (the contents of the file being worked on) and a callback function. Once it's finished doing what it needs to do to the data, the resulting data should be passed to the callback function. Seriously. Look at the other packs. It's ridiculously easy.

Feel free to send any pull requests for any packs you wish to add in.

npm loves you