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 JavaScript 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...
The usual way to run a Node. js program is to run the globally available node command (once you install Node. js) and pass the name of the file you want to execute. While running the command, make sure you are in the same directory which contains the app.
ExecJS lets you run JavaScript code from Ruby. It automatically picks the best runtime available to evaluate your JavaScript program, then returns the result to you as a Ruby object. ExecJS supports these runtimes: therubyrhino - Mozilla Rhino embedded within JRuby.
Node. js takes more time, as you need to find the modules and follow the instruction for integrating them. Ruby on Rails seems to be faster, as you can perform some task, like database migration, with just a few commands. The learning curve is partially less than with Rails.
It's erroring out because require() is not supported by EvalJS. 'require' is undefined, and undefined is not a function. ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With