2012-04-10 54 views
28

我想預編譯所有的CSS和JS文件在我的項目的app/assets文件夾中所有的CSS和JS文件。我不想預先編譯vendor/assets或lib/assets中的所有內容,只需要根據需要對我的文件進行依賴。Rails的config.assets.precompile設置來處理應用程序/資產

我嘗試以下通配符設置,但不正確的預編譯的一切。這導致大量額外的工作,甚至在使用bootstrap-sass時導致編譯失敗。

config.assets.precompile += ['*.js', '*.css'] 

什麼是唯一的過程app/assets我的文件,我最好的選擇?謝謝!

+0

可能重複的[如何使用config.assets.precompile目錄而不是單個文件?](http://stackoverflow.com/questions/12613980/how-do-i-use-config-assets-precompile -for-directories-rather-single-files) – Jason 2014-10-16 13:45:01

回答

18

這個任務是由一個事實,即鏈輪工作與不合乎邏輯的路徑變得更加困難包括底層的,未編譯的資源所在的位置。

假設我的項目有JS文件 「/app/assets/javascripts/foo/bar.js.coffee」。

鏈輪編譯器將首先確定輸出文件的擴展名,在此情況下「的.js」,然後評估是否要編譯邏輯路徑爲‘foo/bar.js’。未編譯的資源可能位於「app/assets/javascripts」,「vendor/assets/javascripts」,「lib/assets/javascripts」或gem中,因此無法根據邏輯路徑包含/排除特定文件單獨。

要確定底層資源的位置,我認爲有必要詢問鏈輪環境(通過對象Rails.application.assets可用)來解析給定邏輯路徑的資源的實際路徑。

這是我正在使用的解決方案。我是相當新的Ruby的,所以這是不是最優雅的代碼:

# In production.rb 
config.assets.precompile << Proc.new { |path| 
    if path =~ /\.(css|js)\z/ 
    full_path = Rails.application.assets.resolve(path).to_path 
    app_assets_path = Rails.root.join('app', 'assets').to_path 
    if full_path.starts_with? app_assets_path 
     puts "including asset: " + full_path 
     true 
    else 
     puts "excluding asset: " + full_path 
     false 
    end 
    else 
    false 
    end 
} 

隨着鏈輪> 3.0,這不會在生產工作,因爲Rails.application.assets將是零(假設默認:配置.assets.compile = false)。

要解決您更換full_path分配有:

@assets ||= Rails.application.assets || Sprockets::Railtie.build_environment(Rails.application) 
full_path = @assets.resolve(path) 

參見:https://github.com/rails/sprockets-rails/issues/237

+0

有人複製你的答案:http://stackoverflow.com/a/15553781/601607 – 2013-10-21 12:33:44

+0

如果你有興趣列入黑名單資產的正則表達式,請看這裏:http://stackoverflow.com/a/34801799/770670 – 2016-01-17 10:57:48

7

我發現這在Rails代碼:

@assets.precompile    = [ Proc.new{ |path| !File.extname(path).in?(['.js', '.css']) }, 
            /(?:\/|\\|\A)application\.(css|js)$/ ] 

這是備份與軌道指南:

編譯文件的默認匹配包括的application.js, application.css和所有非JS/CSS文件

如果您使用+=,則此默認值不會被重置,因此您需要覆蓋它wi一個=而不是+=。請注意,顯然,您可以將Proc或正則表達式傳遞給precompile以及擴展。我相信,如果你想preompile在頂級目錄只有文件,你必須創建這樣一個正則表達式:

config.assets.precompile = [ /\A[^\/\\]+\.(ccs|js)$/i ] 
+0

Michael我很感謝你的迴應,這讓我得到了正確的答案。我想預編譯app/assets樹中的每個css/js文件,而不僅僅是在頂層目錄中。不幸的是,傳遞到proc的路徑是一個邏輯路徑,不區分應用程序/資產,供應商/資產,庫/資產等,因此需要更多的挖掘。查看我的解答使用的答案。 – keithgaputis 2012-04-11 16:17:17

+0

現在我明白瞭如何在'Rails.application.config.assets.precompile'行中使用REGEX。我剛剛在網上搜索了一個小時以瞭解這一點。沒有記錄在別處。謝謝。 – 2017-03-15 20:07:18

23

config.assets.precompile = ['*.js', '*.css']

這將編譯JavaScript或CSS在資產路徑,無論目錄深度。通過this answer找到。

+2

不,它不會進入深層文件夾。您必須使用['your_inner_directory_name/*。js']來編譯內部文件 – 2013-07-25 04:58:24

2

我希望編譯來自/ app和/ vendor的所有資產,除了partials(其名稱從下劃線_開始)。因此,這裏是我的版本在application.rb中的條目:

config.assets.precompile << Proc.new { |path| 
    if path =~ /\.(css|js)\z/ 
    full_path = Rails.application.assets.resolve(path).to_path 
    app_assets_path = Rails.root.join('app', 'assets').to_path 
    vendor_assets_path = Rails.root.join('vendor', 'assets').to_path 

    if ((full_path.starts_with? app_assets_path) || (full_path.starts_with? vendor_assets_path)) && (!path.starts_with? '_') 
     puts "\t" + full_path.slice(Rails.root.to_path.size..-1) 
     true 
    else 
     false 
    end 
    else 
    false 
    end 
} 

此外,它輸出被編譯用於調試的文件列表...

+0

這是我花了幾天時間試用各種可能的解決方案後,唯一一個爲我工作的人。它甚至可以使用'datejs-rails'和'bootstrap-sass' gem(這會導致其他解決方案出現各種問題)。 – 2013-05-28 02:14:32

13

點小文章techpeace的回答是:

config.assets.precompile = ['*.js', '*.css', '**/*.js', '**/*.css']

我會爲他的回答添加評論,但我沒有足夠的聲望。給我一個upvote,我會在那裏!

注意:這還將預編譯通過rubygems包含的所有CSS/JavaScript。

+1

只有'='或'+ ='? – 2013-11-13 10:39:55

+1

對不起,以前沒有看到這個。你也可以使用。如果你想添加到當前選項,你將使用+ =。如果你想替換選項,那麼只需使用=。 – eltiare 2014-04-02 19:31:27

+1

你並不總是想要這個,因爲如果你使用的是scss,通常會導入子文件夾。只是根級通常就夠了。 – Pencilcheck 2015-04-13 01:21:35

0

此代碼段包含所有JS/CSS文件,不含寶石,下:應用程序/資產,供應商/資產LIB /資產,除非它們是局部的文件(例如, 「_file.sass」)。它也有一個策略,包括來自Gems的資產,這些資源並不包含在每個頁面中。

# These assets are from Gems which aren't included in every page. 
    # So they must be included here 
    # instead of in the application.js and css manifests. 
    config.assets.precompile += %w(a-gem.css a-gem.js b-gem.js) 

    # This block includes all js/css files, excluding gems, 
    # under: app/assets, vendor/assets, lib/assets 
    # unless they are partial files (e.g. "_file.sass") 
    config.assets.precompile << Proc.new { |path| 
     if path =~ /\.(css|js)\z/ 
     full_path = Rails.application.assets.resolve(path).to_path 
     aps = %w(/app/assets /vendor/assets /lib/assets) 
     if aps.any? {|ap| full_path.starts_with?("#{Rails.root}#{ap}")} && 
      !path.starts_with?('_') 
      puts "\tIncluding: " + full_path.slice(Rails.root.to_path.size..-1) 
      true 
     else 
      puts "\tExcluding: " + full_path 
      false 
     end 
     else 
     false 
     end 
    } 

雖然,你可能不希望這樣做,因爲你很可能是預編譯寶石資產的兩倍(基本上任何已在您的application.js或CSS \ = require'd)。該片段包括了所有JS/CSS文件,包括寶石,下:應用程序/資產,供應商/資產LIB /資產,除非它們是局部的文件(例如, 「_file.sass」)

# This block includes all js/css files, including gems, 
# under: app/assets, vendor/assets, lib/assets 
# and excluding partial files (e.g. "_file.sass") 
config.assets.precompile << Proc.new { |path| 
    if path =~ /\.(css|js)\z/ 
    full_path = Rails.application.assets.resolve(path).to_path 
    asset_paths = %w(app/assets vendor/assets lib/assets) 
    if (asset_paths.any? {|ap| full_path.include? ap}) && 
     !path.starts_with?('_') 
     puts "\tIncluding: " + full_path 
     true 
    else 
     puts "\tExcluding: " + full_path 
     false 
    end 
    else 
    false 
    end 
} 
3

這將得到所有的.css.scss.js包括子目錄中的所有文件。

js_prefix = 'app/assets/javascripts/' 
style_prefix = 'app/assets/stylesheets/' 

javascripts = Dir["#{js_prefix}**/*.js"].map  { |x| x.gsub(js_prefix, '') } 
css   = Dir["#{style_prefix}**/*.css"].map { |x| x.gsub(style_prefix, '') } 
scss  = Dir["#{style_prefix}**/*.scss"].map { |x| x.gsub(style_prefix, '') } 

Rails.application.config.assets.precompile = (javascripts + css + scss) 
+0

這是最優雅的,雖然我用+ =而不是= = – 2017-11-20 15:51:37

2

我重溫這篇文章在2017年

我們的產品仍大量使用回報率,我們一直在不斷地通過附加Rails.application.config.assets.precompile爲我們添加新的模塊修改我們的預編譯的配置。最近,我試圖通過增加一個正則表達式來優化這個問題,我發現以下glob模式的工作原理:

Rails.application.config.assets.precompile += %w(**/bundle/*.js) 

但是我仍然需要排除某些模塊,所以我努力地使用正則表達式,而不是水珠的。

直到我看着鏈輪源代碼:https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb#L108,我發現他們已經使用正則表達式:

app.config.assets.precompile += 
    [LOOSE_APP_ASSETS, /(?:\/|\\|\A)application\.(css|js)$/] 

所以我改變我的代碼爲:

Rails.application.config.assets.precompile += 
    [/^((?!my_excluded_module)\w)*\/bundle\/\w*\.js$/] 

效果很好。

相關問題