【问题标题】:Easiest way to use node.js package from heroku rails app从 heroku rails app 使用 node.js 包的最简单方法
【发布时间】:2014-05-15 20:24:30
【问题描述】:

你好 railites 和 jsheads,

我是一个 ruby​​ 人,对节点的事情还很陌生,但我正在学习,到目前为止我真的很喜欢它。我已经在 Heroku 上开发一个 Rails 应用程序大约一周了,而且(当然)需求已经发生了变化。

我需要能够从我的 rails 应用程序中使用 pdfkit,这是一个用于创建 pdf 的节点库。

最终,我追求的是最简单的方法来实现这一点。这是我迄今为止尝试过的:

从heroku 文档here 中,我知道heroku rails 应用程序带有node js 运行时,但似乎不包括npm,而且我找不到需要pdfkit 的明显方法。

所以我在这个blog 上率先使用了 ddollar 的多构建包:

heroku config:add BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git

这里是相关文件的 sn-ps(如果我遗漏了什么,请告诉我;))

.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"
  }
}

宝石文件:

...
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)

注意,我确实将 node_modules 签入了源代码管理。 我将所有这些推送到heroku,并尝试使用execjs手动调用test.js:

matt$ heroku run rails c
heroku-irb> ExecJS.eval(File.open('test.js').read)

我收到以下错误:

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>'

我试图简化并运行:

heroku - irb> ExecJS.eval("require('pdfkit')")

但我得到了同样的错误。我想我在 execjs 方面遗漏了一些非常重要的东西。谁能赐教?

然后我想看看我是否可以直接从节点调用 test.js。请注意,这适用于我的本地开发环境。

matt$ heroku run bash
heroku$ node test.js

但我明白了:

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)

所以现在我举手,希望社区的智慧可以帮助我。如果您想了解更多信息,请告诉我。

非常感谢, 马特

【问题讨论】:

    标签: javascript ruby-on-rails ruby node.js heroku


    【解决方案1】:

    所以问题是如果你的应用程序依赖于 execjs,默认的 buildpack 会自动安装一个 node 版本。不幸的是,这是一个非常旧的节点版本——0.4.7——与我需要使用的节点库不兼容。

    我的解决方案是分叉 heroku 的 buildpack 并修补 add_node_js_binary 方法以从不安装节点二进制文件。只要您的多 buildpack 配置包含节点发行版,这将有效。在这里查看:

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

    【讨论】:

    • 太棒了,我遇到了这个确切的问题。正如您所说,/app/bin 首先位于环境 PATH 变量中,并且它具有节点 0.4.7,而 PATH 后面的另一个目录具有 package.json 中指定的节点版本。超级烦人——去分叉你的回购并开心。谢谢!
    • 顺便说一句,我仍然无法让 ExecJS 正常运行......请在此处查看我的 SO 问题:stackoverflow.com/q/22852086/1396827 有什么想法吗?
    • 我不知道如何解决这个问题——我实际上是在尝试让一个 gem 工作(browserify-rails),它在资产编译期间使用 Heroku 上的节点模块。
    猜你喜欢
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 2010-09-19
    • 2014-02-03
    • 2018-07-15
    相关资源
    最近更新 更多