2013-07-08 24 views
11

在Rails 3中有一個rake資源:precompile:nodigest任務,它正在編譯資產並在/ public/assets目錄中沒有摘要部分的情況下編寫它們。在Rails 4中,這已被刪除,並且默認情況下,所有資源都僅用摘要進行預編譯。出於各種原因,我還需要非消化版本的一些資產。有沒有簡單的方法來恢復舊的行爲?rake assets:precompile:nodigest in Rails 4

回答

25

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

sprocket-rails's Readme

只編譯消化的文件名。靜態非消化資產應該只是公開生活

因此,需要靜態的任何資產都可以手動放入您的public文件夾中。如果您需要複製編譯的資產,如SCSS文件等,這rake任務可以幫助(source):

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 
+0

剛剛嘗試過這個,並且像魅力一樣工作。非常感謝! – Zbyszek

+3

我建議使用正則表達式:/(? 907th

2

爲最佳答案的建議,我建議先去讀的問題充分了解故事背景,如果你不急。我最喜歡這個想法,https://github.com/rails/sprockets-rails/issues/49#issuecomment-24837265

下面是我的個人看法,基本上我從上面的答案中拿出了代碼。在我的情況下,我只有2個文件,我想不被消化,widget.js和widget.css。所以我使用鏈輪的方法來查找消化文件,然後將它符號鏈接到公用文件夾。

# 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 = [] 
    # e.g. /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| 
     # e.g. '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 
+0

謝謝你。我不得不讓Rails.configuration.assets.prefix在你的任務結束時使它適合我。 – phyzalis

8

還有一個寶石爲你做這一點:有些挑釁命名non-stupid-digest-assets

gem "non-stupid-digest-assets" 
+1

這應該是被接受的答案。謝謝@AlexC。 –

+0

即使安裝了這個寶石,我正在消化資產。 – vipin8169

+0

在development.rb文件中設置此config.assets.digest = false – vipin8169

1

我的所有可用的選項巨大的分析是在這裏:

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 
1

設置該屬性config.assets.digest = false謝謝迪倫Markow,我按照他的答案,但我發現有一個資產的多個版本(例如,應用程序-0a * .css,應用程序-9c * .css,...)時使用Capistrano,以便最新的一個應該不消化。這裏的邏輯是:

namespace :my_app do 
    task non_digested: :environment do 
    assets = Dir.glob(File.join(Rails.root, 'public/assets/**/*')) 
    regex = /(?<!manifest)(-{1}[a-z0-9]{32}\.{1}){1}/ 
    candidates = {} 

    # gather files info 
    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) 
     file_mtime = File.stat(file).mtime 
     c = candidates[non_digested] 
     if c.blank? || file_mtime > 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 

至於爲我申請第九百○七的正則表達式的評論,加上鉤讓這個任務預編譯後執行井。

+1

在Rails 4.2中,我的摘要是64個字符,所以正則表達式將是'regex = /(?<!manifest)( - {1} [a-z0- 9] {64} \ {1}){1} /' –