Hello railites and jsheads,
I'm a ruby guy and pretty new to the node thing, but I'm learning and so far I really like it. I've been developing a rails app on heroku for a week or so, and (of course) the requirements have evolved.
I need to be able to use pdfkit, a node library for creating pdfs, from my rails app.
Ultimately, I am after the simplest way to accomplish just that. This is what I've tried so far:
From the heroku docs here, I know that heroku rails apps come with a node js runtime, but it seems that npm is not included, and I could not find an obvious way to require pdfkit.
So I followed the the lead on this blog, using ddollar's multi buildpack:
heroku config:add BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git
Here are snippets form the relevant files (let me know if I am missing something ;) )
.buildpack
https://github.com/heroku/heroku-buildpack-nodejs
https://github.com/heroku/heroku-buildpack-ruby
package.json
{
"name": "MoneyMaker",
"version": "0.0.1",
"dependencies": {
"pdfkit": "0.5.2"
},
"repository": {
"type" : "git",
"url" : "https://github.com/mattwalters/example.git"
}
}
Gemfile:
...
gem 'execjs'
...
test.js
// 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)
Note I did check node_modules into source control. I pushed all of this to heroku, and tried to manually call test.js with execjs:
matt$ heroku run rails c
heroku-irb> ExecJS.eval(File.open('test.js').read)
I get the folloring error:
ExecJS::ProgramError: TypeError: undefined is not a function
from /app/vendor/bundle/ruby/2.1.0/gems/execjs-2.0.2/lib/execjs/external_runtime.rb:68:in `extract_result'
from /app/vendor/bundle/ruby/2.1.0/gems/execjs-2.0.2/lib/execjs/external_runtime.rb:28:in `block in exec'
from /app/vendor/bundle/ruby/2.1.0/gems/execjs-2.0.2/lib/execjs/external_runtime.rb:41:in `compile_to_tempfile'
from /app/vendor/bundle/ruby/2.1.0/gems/execjs-2.0.2/lib/execjs/external_runtime.rb:27:in `exec'
from /app/vendor/bundle/ruby/2.1.0/gems/execjs-2.0.2/lib/execjs/external_runtime.rb:19:in `eval'
from /app/vendor/bundle/ruby/2.1.0/gems/execjs-2.0.2/lib/execjs/runtime.rb:40:in `eval'
from /app/vendor/bundle/ruby/2.1.0/gems/execjs-2.0.2/lib/execjs/module.rb:23:in `eval'
from (irb):3
from /app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/commands/console.rb:90:in `start'
from /app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/commands/console.rb:9:in `start'
from /app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/commands.rb:62:in `<top (required)>'
from /app/bin/rails:4:in `require'
from /app/bin/rails:4:in `<main>'
I tried to simplify and just run:
heroku - irb> ExecJS.eval("require('pdfkit')")
But I get the same error. I think I am missing something pretty major when it comes to execjs. Can anyone enlighten me?
Then I wanted to see if I could call test.js directly from node. Note this works in my local dev environment.
matt$ heroku run bash
heroku$ node test.js
But I get:
node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: Cannot find module 'zlib'
at Function._resolveFilename (module.js:320:11)
at Function._load (module.js:266:25)
at require (module.js:348:19)
at Object.<anonymous> (/app/node_modules/pdfkit/js/reference.js:12:10)
at Object.<anonymous> (/app/node_modules/pdfkit/js/reference.js:101:4)
at Module._compile (module.js:404:26)
at Object..js (module.js:410:10)
at Module.load (module.js:336:31)
at Function._load (module.js:297:12)
at require (module.js:348:19)
So now I'm throwing my hands up and hoping the wisdom of the community can help me. Please let me know if you'd like additional information.
Thanks very much, Matt