从 Rails 6 服务对象调用 Javascript

问题描述

我想从服务对象调用 Javascript 库。

我在 /app/javascript/packs/readability.js 中有以下 Javascript。

import Readability from '@mozilla/readability';

function articleBody(document) {
  var article = new Readability(document).parse();
  return article.content;
}

我发现 webpacker-ed 文件可通过 asset_pack_path 在视图中使用。我尝试将其添加到我的服务对象中,如下所示(使用 therubyracer gem)。

(我尝试使用 ExecJS,它似乎比 therubyracer 流行得多,但即使使用 ES5 Javascript 未处理的文件,它也只返回错误。)

cxt = V8::Context.new
cxt.load(ActionController::Base.helpers.asset_pack_path 'readability.js')
puts cxt.eval("articleBody('http://example.com/')")

这是返回 No such file or directory @ rb_sysopen - /packs/js/readability-20f57636.js

localhost:3000/packs/js/readability-20f57636.js 在浏览器中加载良好。

如何在服务对象中加载 webpacker 处理的文件

解决方法

错误是说它找不到文件,您似乎将它保存在 /javascript 中,但 webpacker 正在 js 中查找。确保您的 webpacker.yml 中有此行​​:

default: &default
   source_path: app/javascript

代替:

default: &default
   source_path: app/js
,

如果 Javascript 不在浏览器中运行,则不需要编译或转译它。您可以通过 executing a shell script from Ruby 将数据从 Rails 发送到 Node。

在服务对象(或控制器)中:

require "open3"
output,status = Open3.capture2("node ./lib/test.js",stdin_data: document)
# The `output` variable above will be returned with the content of `data` from the below script.
puts output

/lib/bin 中的脚本:

const fs = require('fs');

fs.readFile(0,'utf8',function(err,data) {
  if (err) throw err;
  // do your proccessing here...
  console.log(data);
});