3

我有一个从配置文件加载 YAML 的 js.erb 文件。问题是 Rails /资产管道将缓存结果并且永远不会使缓存无效,即使我更改了 YAML 文件内容。我可以重新启动 rails 服务器,甚至重新启动机器都无济于事。到目前为止,我发现的唯一解决方法是执行“rake assets:clean”。

我想找到一种方法告诉资产管道,当 YAML 文件更改时,它需要重新计算我的 js.erb。或者,或者,告诉它它只能在 rails 服务器的生命周期内缓存 js.erb / 确保每次 rails 服务器启动或重新启动时都会以某种方式重新生成。

任何建议将不胜感激。

4

4 回答 4

4

将此添加到 config/initializers 下的文件中,它会告诉资产管道重新计算 js.erb 文件,该文件在支持 YAML 文件之一发生更改时加载 YAML 数据:

class ConstantsPreprocessor < Sprockets::Processor
  CONSTANTS_ASSET = "support/constants"

  def evaluate(context, locals)
    if (context.logical_path == CONSTANTS_ASSET)
      Constants.load_path.each do |dir|
        dir.each do |yml|
          next unless yml.end_with?".yml"
          context.depend_on("#{dir.path}/#{yml}")
        end
      end
    end

    data
  end
end

Rails.application.assets.register_preprocessor(
    'application/javascript',
    ConstantsPreprocessor)
于 2013-05-01T19:18:59.237 回答
1

如果您使用的是Sprockets 3(例如 Rails 5),您可以使用// depends_on. 例如my-constants.js.erb

//= depend_on my_constants.yml
angular
  .module('services.myConstants', [])
  .factory('myConstants', [
    function() {
      return <%= YAML::load_file(Rails.root.join('config/shared/my_constants.yml')).to_json %>;
    }
  ]);

只需确保包含的目录my_constants.yml包含在资产路径中application.rb

config.assets.paths.unshift Rails.root.join('config', 'shared').to_s
于 2018-03-13T21:31:22.927 回答
0

我认为你有两个选择:

  1. 禁用资产管道并让 Rails 随时随地进行编译(对性能不利)

  2. 创建一个与 Rails 分离的守护进程(查找 Ruby 守护进程)以查找该特定文件中的任何更改并重新编译资产。

3(额外!)。删除 js-YAML 依赖项并从对应用程序的 AJAX 调用中读取 YAML 的内容。场景是:JS 进行 AJAX 调用,控制器读取 YAML 文件并将其内容返回给 JS 文件。因此无需重新编译或观察 YAML 文件中的更改。

  • 如果您选择 3,请不要在控制器中读取 YAML,创建一个实用程序类来执行此操作,并让控制器要求该类读取文件并传递其内容。
于 2013-05-01T13:30:33.497 回答
0

您可以添加自己的处理器指令,该指令适用于目录之外的assets文件。 = depend_on仅适用于资产文件(https://github.com/rails/sprockets#depend_on

在 config/initializers/sprockets.rb 中:

Sprockets::DirectiveProcessor.class_eval do
  def process_depend_on_project_file_directive(file)
    path = Rails.root.join(file).to_s
    if File.exists?(path)
      deps = Set.new
      deps << @environment.build_file_digest_uri(path)
      @dependencies.merge(deps)
    end
  end
end

用法:

//= depend_on_project_file "config/setting.yml"

有关详细信息,请参阅 github 上的此评论:https ://github.com/rails/sprockets/issues/500#issuecomment-491043517

于 2020-09-21T20:02:16.010 回答