我有一个从配置文件加载YAML的js.erb文件。问题是Rails /资产管道将缓存结果,并且永远不会使该缓存失效,即使我更改了YAML文件内容。我可以重启rails服务器甚至重启机器无济于事。到目前为止,我发现的唯一解决方法是做一个“耙资产:干净”。
我想找到一种方法告诉资产管道,当YAML文件发生变化时,需要重新计算我的js.erb。或者,或者告诉它它只能在rails服务器的生命周期中缓存js.erb /确保每次rails服务器启动或重新启动时都会重新生成。
任何建议都将不胜感激。
答案 0 :(得分:4)
将其添加到config / initializers下的文件中,它将告诉资产管道重新计算每当其中一个支持YAML文件发生更改时加载YAML数据的js.erb文件:
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)
答案 1 :(得分: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
答案 2 :(得分:0)
我认为你有两个选择:
禁用资产管道,让Rails随时随地进行编译(对性能不利)
创建一个守护程序进程,与Rails分开(查找Ruby守护程序)以查找该特定文件中的任何更改并重新编译资产。
3(额外!)。删除js-YAML依赖项并从对应用程序的AJAX调用中读取YAML的内容。场景是:JS进行AJAX调用,控制器读取YAML文件并将其内容返回给JS文件。因此无需重新编译或监视YAML文件中的更改。
答案 3 :(得分: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