I have a rails application that needs to run a node script. i imagine that using the ExecJS gem is the cleanest way to run js from a rails app. However, so far, ExecJS has proved to be very frustrating to use.
here is the script I need to run:
// Generated by CoffeeScript 1.7.1
(function() {
var PDFDocument, doc, fs;
fs = require("fs");
PDFDocument = require('pdfkit');
doc = new PDFDocument;
doc.pipe(fs.createWriteStream('output.pdf'));
doc.addPage().fontSize(25).text('Here is some vector graphics...', 100, 100);
doc.save().moveTo(100, 150).lineTo(100, 250).lineTo(200, 250).fill("#FF3300");
doc.scale(0.6).translate(470, -380).path('M 250,75 L 323,301 131,161 369,161 177,301 z').fill('red', 'even-odd').restore();
doc.addPage().fillColor("blue").text('Here is a link!', 100, 100).underline(100, 100, 160, 27, {
color: "#0000FF"
}).link(100, 100, 160, 27, 'http://google.com/');
doc.end();
}).call(this)
From my rails console, I try this:
[2] pry(main)> file = File.open('test.js').read
[3] pry(main)> ExecJS.eval(file)
ExecJS::ProgramError: TypeError: undefined is not a function
from /Users/matt/.rvm/gems/ruby-2.1.0/gems/execjs-2.0.2/lib/execjs/external_runtime.rb:68:in `extract_result'
Note that I can run this script successfully using 'node test.js' and I am also able to run run the script using the backtick syntax ruby offers:
`node test.js`
But that feels like a hack...
Any takers?
ExecJS people say use
commonjs.rb
https://github.com/cowboyd/commonjs.rbBut this doesn't work basically. The
require
acts completely erratically - I had to executenpm -g install pdfkit fs
betweenenv =
andenv.require
infor the module lookup to work O.o and if I tried pointing
path
to thenode_modules
folder then it would be impossible for the gem to findscript
(not to mention that the#new
andrequire
are basically the only documented methods - only methods afaik - and#new
is misdocumented :P)Your options as far as I can tell:
system(node ...)
- you can use Cocaine to escape some gotcha's (piping output, error handling, performance tweaks, ...) and run a cleaner syntax - this is not as bad as it looks - this is how paperclip does image postprocessing (imagemagick
system package +cocaine
) so I guess it's very stable and very doableprawn
:)It's erroring out because require() is not supported by EvalJS. 'require' is undefined, and undefined is not a function. ;)
I'm not sure of the answer but maybe you need to precise the exec_js_runtime environment variable to be node.
Something like
ENV['EXECJS_RUNTIME'] = 'Node'
You can try to put it in the config/boot.rb or just to define the EXECJS_RUNTIME in your environment, something likeexport EXECJS_RUNTIME=Node
Hope it helps