2012-04-10 28 views
28

Tôi muốn biên dịch trước tất cả các tệp CSS và JS trong thư mục app/assets của dự án của tôi. Tôi KHÔNG muốn biên dịch trước mọi thứ trong nhà cung cấp/tài sản hoặc lib/asset, chỉ phụ thuộc vào các tệp của tôi khi cần thiết.Cài đặt Rails config.assets.precompile để xử lý tất cả các tệp CSS và JS trong ứng dụng/tài sản

Tôi đã thử cài đặt ký tự đại diện sau, nhưng nó không chuẩn bị trước mọi thứ. Điều này dẫn đến nhiều công việc phụ và thậm chí gây ra lỗi biên dịch khi sử dụng bootstrap-sass.

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

Đặt cược tốt nhất của tôi chỉ để xử lý tệp của tôi ở app/assets? Cảm ơn!

+0

bản sao có thể có của [Làm cách nào để sử dụng config.assets.precompile cho thư mục thay vì tệp đơn?] (Http://stackoverflow.com/questions/12613980/how-do-i-use-config-assets-precompile -for-directories-chứ-than-single-files) – Jason

Trả lời

18

Nhiệm vụ này được thực hiện khó khăn hơn bởi thực tế là sprockets làm việc với đường dẫn logic mà không làm bao gồm vị trí nguồn cấp dữ liệu cơ bản, chưa được lưu trữ.

Giả sử dự án của tôi có tệp JS "/app/assets/javascripts/foo/bar.js.coffee".

Trình biên dịch sprockets trước tiên sẽ xác định phần mở rộng của tệp đầu ra, trong trường hợp này là ".js" và sau đó đánh giá liệu có biên dịch đường dẫn logic "foo/bar.js" hay không. Tài nguyên chưa được biên dịch có thể nằm trong "app/assets/javascripts", "vendor/assets/javascripts", "lib/assets/javascripts" hoặc gem, do đó không có cách nào để bao gồm/loại trừ một tệp cụ thể dựa trên đường dẫn logic một mình.

Để xác định vị trí của tài nguyên cơ bản, tôi tin rằng cần phải hỏi môi trường sprockets (có sẵn thông qua đối tượng Rails.application.assets) để giải quyết đường dẫn thực của tài nguyên cho đường dẫn logic.

Đây là giải pháp mà tôi đang sử dụng. Tôi khá mới với Ruby vì vậy đây không phải là mã thanh lịch nhất:

# 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 
} 

Với sprockets> 3.0, điều này sẽ không làm việc trong sản xuất vì Rails.application.assets sẽ bằng không (giả sử mặc định: config .assets.compile = false).

Để workaround bạn thay thế full_path nhượng với:

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

Xem thêm: https://github.com/rails/sprockets-rails/issues/237

+0

Ai đó đã sao chép câu trả lời của bạn: http://stackoverflow.com/a/15553781/601607 –

+0

nếu bạn quan tâm đến tài sản danh sách đen của Regex, hãy xem tại đây: http://stackoverflow.com/a/34801799/770670 –

7

Tôi thấy điều này trong mã ray:

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

nào được sao lưu với hướng dẫn ray:

Các khớp mặc định cho biên dịch các file bao gồm application.js, application.css và tất cả các tệp không phải JS/CSS

Mặc định này không được đặt lại nếu bạn sử dụng +=, vì vậy bạn cần ghi đè nó th a = thay vì +=. Lưu ý rằng, rõ ràng, bạn có thể vượt qua một Proc hoặc một regex để precompile cũng như một phần mở rộng. Tôi tin rằng, nếu bạn muốn preompile chỉ tập tin trong thư mục cấp cao nhất, bạn sẽ phải tạo ra một regex như:

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

Michael Tôi đánh giá cao câu trả lời của bạn, điều này đã đưa tôi đến câu trả lời đúng. Tôi muốn biên dịch trước mọi tệp css/js trong cây ứng dụng/tài sản, không chỉ trong thư mục cấp cao nhất. Thật không may, đường dẫn được chuyển vào proc là một đường dẫn logic không phân biệt giữa ứng dụng/tài sản, nhà cung cấp/tài sản, lib/asset, v.v., vì vậy cần phải đào nhiều hơn. Xem câu trả lời của tôi cho giải pháp được sử dụng. – keithgaputis

+0

Bây giờ tôi hiểu cách sử dụng REGEX trong dòng 'Rails.application.config.assets.precompile'. Tôi đã tìm kiếm trên mạng trong một giờ để hiểu điều này. Không được ghi lại ở nơi khác. Cảm ơn bạn. –

23

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

Điều đó sẽ biên dịch bất kỳ JavaScript hoặc CSS trên đường đi tài sản của bạn, bất kể mục chiều sâu. Tìm thấy qua số this answer.

+2

Không, nó sẽ không đi vào một thư mục sâu. Bạn phải sử dụng ['your_inner_directory_name/*. Js'] để biên dịch các tệp bên trong –

2

Tôi muốn tất cả nội dung từ cả ứng dụng và/nhà cung cấp sẽ được biên soạn, ngoại trừ partials (tên bắt đầu từ dấu gạch dưới _). Vì vậy, đây là phiên bản của tôi về một mục trong 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 
} 

Bên cạnh đó nó ra danh sách các tập tin được biên soạn cho mục đích gỡ lỗi ...

+0

Đây là tài liệu duy nhất làm việc cho tôi, sau khi dành vài ngày để thử tất cả các giải pháp có thể có. Nó hoạt động ngay cả với đá quý 'datejs-rails' và' bootstrap-sass' (sẽ gây ra tất cả các loại vấn đề với các giải pháp khác). –

13

Một tinh chỉnh nhẹ vào câu trả lời của techpeace:

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

Tôi đã thêm nhận xét vào câu trả lời của anh ấy nhưng tôi chưa có đủ danh tiếng. Hãy cho tôi một upvote và tôi sẽ ở đó!

LƯU Ý: điều này cũng sẽ biên dịch trước tất cả CSS/JavaScript được đưa vào thông qua rubygems.

+1

chỉ là '=' hoặc '+ ='? –

+1

Xin lỗi, không thấy điều này trước đây. Bạn cũng có thể sử dụng. Nếu bạn muốn thêm vào các tùy chọn hiện tại, bạn sẽ sử dụng + =. Nếu bạn muốn thay thế các tùy chọn thì chỉ cần sử dụng =. – eltiare

+1

bạn không phải lúc nào cũng muốn điều này bởi vì nếu bạn đang sử dụng scss các thư mục con thường được nhập khẩu. Chỉ cần cấp độ gốc là đủ. – Pencilcheck

0

đoạn này bao gồm tất cả js/file css, trừ đá, dưới: ứng dụng/tài sản, vendor/tài sản, lib/tài sản, trừ khi họ là các tập tin một phần (ví dụ "_file.sass"). Nó cũng có một chiến lược để bao gồm cả tài sản từ Gems mà không được bao gồm trong mỗi trang.

# 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 
    } 

Mặc dù, bạn có thể không muốn làm điều này vì bạn có thể sẽ biên dịch trước tài sản đá quý hai lần (về cơ bản mọi thứ đã được \ = yêu cầu trong application.js hoặc css). đoạn này bao gồm tất cả js/file css, bao gồm đá quý, dưới: ứng dụng/tài sản, vendor/tài sản, lib/tài sản, trừ khi họ là các tập tin một phần (ví dụ: "_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

Điều này sẽ nhận được tất cả .css.scss.js bao gồm tất cả các tệp trong thư mục con.

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

đây là thanh lịch nhất mặc dù tôi đã sử dụng + = thay vì chỉ = –

2

Tôi đang xem xét lại bài này vào năm 2017.

sản phẩm của chúng tôi vẫn còn rất nhiều sử dụng RoR, chúng tôi đã liên tục thay đổi các cấu hình precompile của chúng tôi bằng cách phụ thêm Rails.application.config.assets.precompile như chúng ta đang thêm các module mới. Gần đây tôi đã cố gắng để tối ưu hóa này bằng cách thêm một mô hình regex, tôi thấy rằng mô hình glob sau hoạt động:

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

Tuy nhiên tôi vẫn cần phải loại trừ các module nào đó, vì vậy tôi cố gắng hết sức để sử dụng regex thay vì glob.

Cho đến khi tôi nhìn vào mã nguồn sprockets: https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb#L108, tôi thấy rằng họ đã sử dụng regex:

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

Vì vậy, tôi thay đổi mã của tôi vào:

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

nào hoạt động tốt.

Các vấn đề liên quan