compiler-constructioncoffeescriptpreprocessorcoffeescript-resources

Custom pre-processing steps for coffeescript?


Is there a way to add preprocessing steps to the coffee compiler in a modular way?

Say, for example, that I wanted to augment the functionality of a all arrays and objects with underscore functions, allowing me to do something like testArray.first() and have it compile to _.first(testArray)

This is something which would be very dangerous to do in plain javascript, as I would have to extend the Array.prototype and might break functionality of the array in other libraries. It seems like it would be safe and fun to do with coffee-script, though.

It would be great if there was a way to do this in a way which is

  1. Modular - I could add multiple pre-processing steps, pulling from different projects which make programming more easy and elegant in different ways
  2. Integrated - I want to be able to change something in the configuration files of coffeescript so that I don't have to use a custom binary and replace the command in every single development tool which is calling the coffee compiler (for live compilation, etc).

Does this exist built into coffeescript? If not, it seems like it should. I'll bring it up with the developers if no-one has heard of it.


Solution

  • CoffeeScript does not have a plugin system. There is no easy way out if you want to customize it. You can fork the CoffeeScript repo, and modify the compiler according to your requirement. However, that means you have to maintain your fork of the compiler by regularly pulling updates from main repo.

    See the following code from CoffeeScript compiler repo (https://github.com/jashkenas/coffeescript/blob/master/lib/coffee-script/coffee-script.js#L195) :

    ....
      o[k] = v;
    }
    o.bare = true;
    js = compile(code, o);
    if (sandbox === global) {
      return vm.runInThisContext(js);
    } else {
      return vm.runInContext(js, sandbox);
    }
    ....
    

    you can add a new method to this file

    precompile = function (code) {
        // do pre-processing here
    }
    

    and make

    js = compile(precompile(code), o);
    

    I haven't attempted this, so you may hit some walls while doing it. Although the changes you want are simple enough not to worry about lexer.

    Although, you may write your own parser for making these changes in any language and use grunt/gulp to combine coffee compilation and a precompilation step. I would recommend this method.