【问题标题】:Evaluating module.exports in Ruby (Rails)在 Ruby (Rails) 中评估 module.exports
【发布时间】:2021-05-15 05:12:00
【问题描述】:

目前我正在尝试从 JS 获取 Ruby 中 Hash 格式的内容。

我有一个类似这样的 JS 模块

module.exports = {
  key1: "val",
  key2: {
    key3: "val3"
  }
  ...
}

这只是一个字符串。我知道 ExecJS 在这里可能会有所帮助,但我不确定将其转换为 Hash 的最佳方法是什么。

我目前正在尝试做这样的事情

contents.prepend("var module = {exports: {}};\n")
context = ExecJS.compile contents

context.eval('module.exports').to_hash

但是当给它一个像上面这样的字符串时,我从 JSON gem 中得到一个解析错误。

【问题讨论】:

  • 是否有很多这样的文件要处理?您可以复制粘贴内容并将module.exports = 替换为一些Ruby 变量名。如果有很多文件,可以进行查找和替换。我想您可以使用 Node 评估它们,然后也将输出转储到文件中。
  • @maxpleaner 它是更大文件摄取系统的一部分,因此数量未知

标签: javascript ruby-on-rails ruby execjs


【解决方案1】:

我只是尝试将其放入脚本并运行它:

require 'execjs'

str = <<-JS
  // Note, you could just do `var module = {}` here
  var module = {exports: {}};

  module.exports = {
    key1: "val",
    key2: {
      key3: "val3"
    }
  }
JS

context = ExecJS.compile str 
puts context.eval('module.exports').to_hash
# => {"key1"=>"val", "key2"=>{"key3"=>"val3"}}

也许您收到 JSON 解析错误,因为模块包含无法序列化的内容。


这是另一种方法。

制作一个加载模块并将其导出为 JSON 的 JS 文件。

var fs = require('fs');
var hash = require('path/to/my_module.js');

fs.writeFileSync('path/to/output.json', JSON.stringify(hash), 'utf8');

使用nodejs my_script.js 运行,然后从 Ruby 中读取:

require 'json'
hash  = JSON.parse "path/to/output.json"

【讨论】:

  • 嗯,我可以看到我的源代码在其中一个键的字符串中有一些 HTML。我想知道是不是这样。
  • 我进行了更多测试,但看起来并非如此。在我的 Rails 控制台中,我正在读取文件。它大约有 2000 行不同深度的键。我正在评论某些行,当我到达一定数量的评论行时,它似乎只是工作......如果我删除这些 cmets,JSON 解析错误表面再次出现。我知道如果没有我提供源文件,很难想象这个问题......
  • 是的,只需使用注释掉的方法来缩小问题范围。需要了解更多细节以提供进一步帮助。
  • 我非常确信 JSON 的长度在某种程度上是错误的。当我注释掉不同的行时,似乎在某个限制下,我注释掉哪一行并不重要,它只是无法解析。看起来完整的 JSON 被输入,因为 ExecJS 试图评估它实际上太长了(无论出于何种原因),并且日志在堆栈跟踪中显示了一个不完整的 JSON。
  • 查看我编辑的答案,了解另一种不需要 ExecJS 的方法。显然 JSON 文件大小是有限制的,但这个限制非常大(比如 100 MB)。
【解决方案2】:

如果问题出在运行时,可以使用 mini_racer 作为 ExecJS 使用的运行时。只需包含 gem:

gem 'execjs'
gem 'mini_racer'

然后就可以运行了:

p ExecJS.runtime
# > #<ExecJS::MiniRacerRuntime:0x00007fc44ea20bd8>

然后您将首先设置上下文:

require 'execjs'

jscode = <<-JS
  module.exports = {
    key1: "val",
    key2: {
      key3: "val3"
    }
  }
JS

context = ExecJS.compile "var module = {};"
result_hash = context.eval jscode
puts result_hash["key1"]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 2015-04-16
    • 2012-02-10
    相关资源
    最近更新 更多