简体   繁体   English

从Heroku Rails应用程序使用Node.js包的最简单方法

[英]Easiest way to use node.js package from heroku rails app

Hello railites and jsheads, 你好Railite和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. 我已经在heroku上开发了一个Rails应用大约一个星期,并且(当然)需求已经发生了变化。

I need to be able to use pdfkit , a node library for creating pdfs, from my rails app. 我需要能够从Rails应用程序使用pdfkit (用于创建pdf的节点库)。

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. 这里的heroku文档中,我知道heroku rails应用程序带有一个节点js运行时,但是似乎不包括npm,而且我找不到一种明显的方法来要求pdfkit。

So I followed the the lead on this blog , using ddollar's multi buildpack: 因此,我使用ddollar的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 .buildpack

https://github.com/heroku/heroku-buildpack-nodejs
https://github.com/heroku/heroku-buildpack-ruby

package.json 的package.json

{
  "name": "MoneyMaker",
  "version": "0.0.1",
  "dependencies": {
    "pdfkit": "0.5.2"
  },
  "repository": {
    "type" : "git",
    "url" : "https://github.com/mattwalters/example.git"
  }
}

Gemfile: 的Gemfile:

...
gem 'execjs'
...

test.js 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. 注意我确实将node_modules签入了源代码管理。 I pushed all of this to heroku, and tried to manually call test.js with execjs: 我将所有这些信息推送到heroku,并尝试使用execjs手动调用test.js:

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. 我认为我在execjs方面缺少一些相当重要的东西。 Can anyone enlighten me? 谁能启发我?

Then I wanted to see if I could call test.js directly from node. 然后,我想看看是否可以直接从node调用test.js。 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 非常感谢,马特

So the problem was that the default buildpack installs a version of node automatically if your application depends on execjs. 因此,问题在于,如果您的应用程序依赖于execjs,则默认的buildpack会自动安装一个版本的node。 Unfortunately this is a very old version of node -- 0.4.7 -- that is incompatible with the node libraries I need to use. 不幸的是,这是一个非常旧的节点版本-0.4.7-与我需要使用的节点库不兼容。

My solution was to fork heroku's buildpack and patch the add_node_js_binary method to never install node binaries. 我的解决方案是派生heroku的buildpack并修补add_node_js_binary方法,使其从不安装节点二进制文件。 This works as long as your multi buildpack configuration includes a node distro. 只要您的多buildpack配置包括一个节点发行版,此方法就起作用。 Check it out here: 在这里查看:

https://github.com/mattwalters/heroku-buildpack-ruby/blob/master/lib/language_pack/ruby.rb https://github.com/mattwalters/heroku-buildpack-ruby/blob/master/lib/language_pack/ruby.rb

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM