apachenode.jscgicoffeescriptenv

CoffeeScript in a shell script -- run by Apache (as CGI)


Following the advice here I can get a shell script in JavaScript that runs under node.js and prints a bit of hello world html:

test.cgi
-------
#!/usr/local/bin/node

console.log("Content-Type: text/html; charset=utf-8\n");
console.log("<html><body><h1>hello node.js world</h1></body></html>");
-------

And running it:

$ ./test.cgi
Content-Type: text/html; charset=utf-8

<html><body><h1>hello node.js world</h1></body></html>

It also works as expected in Apache and displays the expected HTML in the browser.

Now on to CoffeeScript (note the lovely triple-quoted here docs, Python-style):

ctest.cgi
-------
#!/usr/bin/env coffee

console.log("Content-Type: text/html; charset=utf-8\n");
console.log('''<html><body><h1>hello CoffeeScript world
</h1></body></html>''');
-------

This works when run locally:

$ ./ctest.cgi
Content-Type: text/html; charset=utf-8

<html><body><h1>hello CoffeeScript world
</h1></body></html>

But not in Apache:

Internal Server Error

Why doesn't this work?


Solution

  • I attempted to fix this by reverse engineering command.js from CoffeeScript and running my coffee script (ctest.cgi above) directly, via the following JavaScript node.js shell script:

    drip
    -------
    #!/usr/local/bin/node
    
    var fs = require('fs');
    var cs = require('/usr/local/lib/coffee-script/lib/coffee-script');
    var args = process.argv;
    var fname = args[2];
    if (fname)
    {
        fs.readFile(fname, function (err, data) {
          if (err) throw err;
          var text = data.toString(); //console.log(data.toString());
          cs.run(text, {'filename':fname, 'bare':undefined});
        });
    }
    -------
    

    I put this in /usr/local/bin/drip and now I can run ctest.cgi with a small change to the top line:

    #!/usr/bin/env /usr/local/bin/drip
    

    Now I can hack CoffeeScript CGI scripts and simply hit reload in my browser instead of having to manually invoke the CoffeeScript compiler when I change the .coffee files.