12

我有一个需要运行节点脚本的 Rails 应用程序。我想使用 ExecJS gem 是从 Rails 应用程序运行 JavaScript 的最干净的方法。然而,到目前为止,事实证明 ExecJS 使用起来非常令人沮丧。

这是我需要运行的脚本:

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

从我的 Rails 控制台,我尝试这个:

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

请注意,我可以使用“node test.js”成功运行此脚本,并且还可以使用 Ruby 提供的反引号语法运行该脚本:

`node test.js`

但这感觉就像一个黑客......

4

4 回答 4

3

它出错是因为 EvalJS 不支持 require() 。'require' 是未定义的,并且 undefined 不是函数。;)

于 2015-10-23T05:46:35.733 回答
2

我不确定答案,但也许您需要将 exec_js_runtime 环境变量精确到节点。

类似的东西ENV['EXECJS_RUNTIME'] = 'Node'你可以尝试把它放在 config/boot.rb 或者只是在你的环境中定义 EXECJS_RUNTIME ,比如export EXECJS_RUNTIME=Node

希望能帮助到你

于 2014-04-04T02:04:52.797 回答
2

ExecJS 人说使用commonjs.rb https://github.com/cowboyd/commonjs.rb

为什么我不能在 ExecJS 中使用 CommonJS require()?

ExecJS 为任何 JavaScript 运行时提供了最低公分母接口。当您的代码在哪个 JavaScript 解释器中运行无关紧要时,请使用 ExecJS。如果您想访问 Node API,您应该检查另一个库,例如 commonjs.rb,旨在提供一致的接口。

但这基本上不起作用。这些require行为完全不正常 - 我必须在两者npm -g install pdfkit fs之间env =执行env.require

require 'v8'
require 'commonjs'
env = CommonJS::Environment.new(V8::Context.new, path: ::Rails.root )
env.require 'script'

为了使模块查找工作 Oo,如果我尝试指向pathnode_modules文件夹,那么 gem 将无法找到script(更不用说#newandrequire基本上是唯一记录在案的方法 - 只有方法 afaik - 并且#new被错误记录:P)

据我所知,您的选择:

  1. system(node ...)- 你可以使用Cocaine来逃避一些问题(管道输出、错误处理、性能调整......)并运行更简洁的语法 - 这并不像看起来那么糟糕 - 这就是回形针进行图像后处理的方式(imagemagick系统包 + cocaine)所以我想它非常稳定并且非常可行
  2. 暴露给 web api 并在免费的 heroku dyno 上运行一个单独的工作程序,例如执行此操作以及您想要对节点库执行的类似操作
  3. 使用prawn:)
于 2015-12-15T18:17:46.743 回答
-2

摆脱 ExecJS 和任何依赖 ExecJS 的东西。我尝试了所有其他建议,但这实际上解决了它。

ES6 自 2015 年以来一直存在。任何值得使用的工具现在都支持它。MICROSOFT EDGE 现在支持它。严重地。

于 2019-08-20T18:00:39.887 回答