2014-04-04 17 views
8

Tôi có ứng dụng đường ray cần chạy tập lệnh. tôi tưởng tượng rằng sử dụng đá quý ExecJS là cách sạch nhất để chạy js từ một ứng dụng đường ray. Tuy nhiên, cho đến nay, ExecJS đã tỏ ra rất bực bội khi sử dụng.Gọi tập lệnh Node.js từ ứng dụng Rails bằng ExecJS

đây là kịch bản tôi cần phải chạy:

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

Từ đường ray giao diện điều khiển của tôi, tôi cố gắng này:

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

Lưu ý rằng tôi có thể chạy kịch bản này sử dụng thành công 'test.js nút 'và tôi cũng có thể chạy chạy kịch bản bằng cách sử dụng cú pháp ruby ​​backtick cung cấp:

`node test.js` 

Nhưng mà cảm thấy giống như một hac k ...

Bất kỳ người dùng nào?

+1

Âm thanh như một trường hợp sử dụng tuyệt vời cho microservices. Yêu cầu máy chủ Node.js tham dự các yêu cầu được thực hiện từ máy chủ Rails! – vemv

+0

Điều này không liên quan đến câu hỏi, nhưng có liên quan đến mã. Nếu bạn đang cố gắng để tạo một pdf từ một ứng dụng đường ray, tại sao không sử dụng thư viện ruby ​​như 'tôm'? – hamitron

Trả lời

2

Tôi không chắc chắn về câu trả lời nhưng có thể bạn cần phải xác định biến môi trường exec_js_runtime chính xác thành nút.

Something như ENV['EXECJS_RUNTIME'] = 'Node' Bạn có thể thử để đặt nó trong config/boot.rb hoặc chỉ để xác định EXECJS_RUNTIME trong môi trường của bạn, một cái gì đó giống như export EXECJS_RUNTIME=Node

Hy vọng nó giúp

+0

Tôi không nghĩ đó là vấn đề. Tôi chắc chắn có một cài đặt nút làm việc và tôi có thể chạy 'ExecJS.eval ("1 + 1")' mà không có bất kỳ vấn đề. Dù sao cũng cảm ơn bạn. –

+0

Vâng, nhưng bạn có chắc chắn rằng exec js đang sử dụng nút và không phải là một thời gian chạy khác? – Oxynum

+0

Kết quả của 'ExecJS.runtime' là gì? – Oxynum

3

Nó erroring ra bởi vì yêu cầu () không được EvalJS hỗ trợ. 'require' là không xác định, và undefined không phải là một hàm. ;)

1

ExecJS people say sử dụng commonjs.rbhttps://github.com/cowboyd/commonjs.rb

Tại sao tôi không thể sử dụng CommonJS require() bên ExecJS?

ExecJS cung cấp giao diện mẫu số chung thấp nhất cho bất kỳ thời gian chạy JavaScript nào. Sử dụng ExecJS khi không có vấn đề gì với JavaScript thông dịch viên mã của bạn. Nếu bạn muốn truy cập API nút, bạn nên kiểm tra thư viện khác như commonjs.rb được thiết kế để cung cấp giao diện nhất quán .

Nhưng điều này không hoạt động về cơ bản. Các require hành vi hoàn toàn thất thường - Tôi đã phải thực hiện npm -g install pdfkit fs giữa env =env.require trong

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

cho việc tra cứu module để làm việc Oo và nếu tôi cố gắng chỉ path vào thư mục node_modules sau đó nó sẽ không thể cho đá quý để tìm script (chưa kể rằng #newrequire là về cơ bản là phương pháp ghi nhận chỉ - chỉ phương pháp afaik - và #new được misdocumented: P)

lựa chọn của bạn như xa như tôi có thể nói:

  1. system(node ...) - bạn có thể sử dụng Cocaine để thoát khỏi một số của Gotcha (sản lượng đường ống, xử lý lỗi, tinh chỉnh hiệu suất, ...) và chạy một cú pháp rõ ràng hơn - đây không phải là hình thức xử lý ảnh kém - đây là cách xử lý hậu xử lý hình ảnh (imagemagick gói hệ thống + cocaine) vì vậy tôi đoán nó rất ổn định và rất có thể thực hiện được
  2. tiếp xúc với api trên web và chạy riêng người lao động trên một Dyno Heroku miễn phí ví dụ để làm điều này và các công cụ tương tự như bạn muốn làm gì với libs nút
  3. sử dụng prawn :)
Các vấn đề liên quan