rake资产:预编译:Rails中的nodigest 4

在Rails 3中有一个rake资产:预编译:nodigest任务,它编译资产并在/ public / assets目录中编写没有摘要部分的资源。 在Rails 4中,这已被删除,默认情况下,所有资产都只使用摘要进行预编译。 由于各种原因,我还需要一些资产的非消化版本。 有没有简单的方法来启用旧的行为?

Rails 4.0.0中使用的sprockets-rails版本不再支持非摘要资产。

Per sprocket-rails的自述文件 :

仅编译摘要文件名。 静态非消化资产应该只是公开生活

因此,任何需要静态的资产都可以手动放入公用文件夹。 如果您需要复制编译资产(如SCSS文件等),此rake任务可能会有所帮助( 来源 ):

 task non_digested: :environment do assets = Dir.glob(File.join(Rails.root, 'public/assets/**/*')) regex = /(-{1}[a-z0-9]{32}*\.{1}){1}/ assets.each do |file| next if File.directory?(file) || file !~ regex source = file.split('/') source.push(source.pop.gsub(regex, '.')) non_digested = File.join(source) FileUtils.cp(file, non_digested) end end 

还有一个gem可以为你做这件事:有点挑衅性地命名为非愚蠢的消化资产 。

 gem "non-stupid-digest-assets" 

作为建议的最佳答案,我建议首先阅读问题,以充分了解背景故事,如果你不赶时间。 我最喜欢这个想法, https://github.com/rails/sprockets-rails/issues/49#issuecomment-24837265 。

以下是我的个人看法,基本上我从上面的答案中获取了代码。 在我的情况下,我只有2个我想要消化的文件,widget.js和widget.css。 所以我使用sprockets方法查找已消化的文件,然后将其符号链接到公用文件夹。

 # config/environments/production.rb config.assets.precompile += %w[v1/widget.js v1/widget.css] # lib/tasks/assets.rake namespace :assets do desc 'symlink digested widget-xxx.js and widget-xxx.css to widget.js and widget.css' task symlink_widget: :environment do next if Rails.env.development? || Rails.env.test? digested_files = [] # eg /webapps/myapp/public/assets assets_path = File.join(Rails.root, 'public', Rails.configuration.assets.prefix) %w(v1/widget.js v1/widget.css).each do |asset| # eg 'v1/widget-b61b9eaaa5ef0d92bd537213138eb0c9.js' logical_path = Rails.application.assets.find_asset(asset).digest_path digested_files << File.join(assets_path, logical_path) end fingerprint_regex = /(-{1}[a-z0-9]{32}*\.{1}){1}/ digested_files.each do |file| next unless file =~ fingerprint_regex # remove fingerprint & '/assets' from file path non_digested = file.gsub(fingerprint_regex, '.') .gsub(Rails.configuration.assets.prefix, '') puts "Symlinking #{file} to #{non_digested}" system "ln -nfs #{file} #{non_digested}" end end end 

我对所有可用选项的巨大分析如下:

https://bibwild.wordpress.com/2014/10/02/non-digested-asset-names-in-rails-4-your-options/

我决定添加一个自定义rake任务,使用自定义配置来确定要生成非消化版本的某些资产,并使用Sprockets清单查找已消化的资产并使用非消化名称复制它们。

https://github.com/team-umlaut/umlaut/blob/5edcc609389edf833a79caa6f3ef92982312f0c5/lib/tasks/umlaut_asset_compile.rake

 # Rails4 doesn't create un-fingerprinted assets anymore, but we # need a couple for umlaut's API. Let's try to hook in and make # symlinks. # # list of what file(globs) need non-digest-named copies is kept in # Umlaut::Engine.config.non_digest_named_assets # defined in lib/umlaut.rb, but app can modify it if desired. require 'umlaut' require 'pathname' # Every time assets:precompile is called, trigger umlaut:create_non_digest_assets afterwards. Rake::Task["assets:precompile"].enhance do Rake::Task["umlaut:create_non_digest_assets"].invoke end namespace :umlaut do # This seems to be basically how ordinary asset precompile # is logging, ugh. logger = Logger.new($stderr) # Based on suggestion at https://github.com/rails/sprockets-rails/issues/49#issuecomment-20535134 # but limited to files in umlaut's namespaced asset directories. task :create_non_digest_assets => :"assets:environment" do manifest_path = Dir.glob(File.join(Rails.root, 'public/assets/manifest-*.json')).first manifest_data = JSON.load(File.new(manifest_path)) manifest_data["assets"].each do |logical_path, digested_path| logical_pathname = Pathname.new logical_path if Umlaut::Engine.config.non_digest_named_assets.any? {|testpath| logical_pathname.fnmatch?(testpath, File::FNM_PATHNAME) } full_digested_path = File.join(Rails.root, 'public/assets', digested_path) full_nondigested_path = File.join(Rails.root, 'public/assets', logical_path) logger.info "(Umlaut) Copying to #{full_nondigested_path}" # Use FileUtils.copy_file with true third argument to copy # file attributes (eg mtime) too, as opposed to FileUtils.cp # Making symlnks with FileUtils.ln_s would be another option, not # sure if it would have unexpected issues. FileUtils.copy_file full_digested_path, full_nondigested_path, true end end end end 

谢谢Dylan Markow,我按照他的回答,但我发现使用Capistrano有一些资产的版本(例如application-0a * .css,application-9c * .css,…),所以最新版本应该是非消化。 这里的逻辑是:

 namespace :my_app do task non_digested: :environment do assets = Dir.glob(File.join(Rails.root, 'public/assets/**/*')) regex = /(? c[:mtime] candidates[non_digested] = {orig: file, mtime: file_mtime} end end # genearate for non_digested, val in candidates do FileUtils.cp(val[:orig], non_digested) end end end Rake::Task['assets:precompile'].enhance do Rake::Task['my_app:non_digested'].invoke end 

除此之外,我应用了907th的正则表达式注释,并添加了钩子,让这个任务在预编译后执行。

在`development.rb’文件中设置此属性config.assets.digest = false