2012-04-10 1 views
28

Я хочу предварительно скопировать все файлы CSS и JS в папку моего проекта app/assets. Я НЕ хочу прекомпилировать все в поставщиках/активах или lib/assets, а только зависимости моих файлов по мере необходимости.Rails config.assets.precompile настройка для обработки всех файлов CSS и JS в приложении/активах

Я пробовал следующие настройки подстановочного знака, но он неправильно прекомпилирует все. Это приводит к большому количеству дополнительной работы и даже приводит к сбою компиляции при использовании 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-than-single-files) – Jason

ответ

18

Эта задача осложняется тем, что Звездочки работают с логическими путями, которые не включают, где находится лежащий в основе, некомпилированный ресурс.

Предположим, что в моем проекте есть JS-файл «/app/assets/javascripts/foo/bar.js.coffee».

Компилятор звездочек сначала определяет расширение выходного файла, в данном случае «.js», а затем оценивает, следует ли компилировать логический путь «foo/bar.js». Некомпилированный ресурс может быть в «app/assets/javascripts», «vendor/assets/javascripts», «lib/assets/javascripts» или драгоценном камне, поэтому нет способа включить/исключить конкретный файл на основе логического пути в одиночестве.

Чтобы определить, где находится базовый ресурс, я полагаю, что необходимо спросить среду sprockets (доступную через объект 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).

Чтобы обойти замены Полный_путь назначение:

@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 –

+0

, если вы заинтересованы в черном списке активов по Regex, см. Здесь: http://stackoverflow.com/a/34801799/770670 –

7

Я нашел это в коде рельсах:

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

, который обеспечивается с направляющими рельсами:

по умолчанию согласовани для компиляции файлов включает application.js, application.css и все файлы, не относящиеся к JS/CSS

Это значение по умолчанию не сбрасывается, если вы используете +=, поэтому вам необходимо переопределить его wi th a = вместо +=. Обратите внимание, что, по-видимому, вы можете передать Proc или regex на precompile, а также на расширение. Я считаю, если вы хотите preompile только файлы в каталоге верхнего уровня, вам придется создать регулярное выражение, как:

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

Michael Я ценю ваш ответ, который привел меня к правильному ответу. Я хочу прекомпилировать каждый файл css/js в дереве приложений/активов, а не только в каталоге верхнего уровня. К сожалению, путь, пройденный в proc, является логическим путем, который не различает приложения/активы, вендоры/активы, lib/активы и т. Д., Поэтому необходимо больше копать. См. Мой ответ для используемого решения. – keithgaputis

+0

Теперь я понимаю, как использовать REGEX в строке 'Rails.application.config.assets.precompile'. Я только что обыскал сеть в течение часа, чтобы понять это. Не задокументировано в другом месте. Спасибо. –

23

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

Это будет компилировать любой JavaScript или CSS в вашем пути активов, независимо от того каталога глубина. Найдено через this answer.

+2

Нет, это не будет в глубокой папке. Вы должны использовать ['your_inner_directory_name/*. Js'] для компиляции внутренних файлов. –

2

Я хотел, чтобы все активы из// app и/vendor были скомпилированы, за исключением частичных (название начинается с подчеркивания _). Так вот моя версия записи в 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' (что вызовет всевозможные проблемы с другими решениями). –

13

Небольшой твик для ответа techpeace в:

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

Я бы добавил комментарий к его ответу, но у меня пока нет достаточной репутации. Дайте мне верх, и я буду там!

ПРИМЕЧАНИЕ: это также прекомпилирует весь CSS/JavaScript, включенный через rubygems.

+1

это только '=' или '+ ='? –

+1

Извините, не видел этого раньше. Вы также можете использовать. Если вы хотите добавить к текущим параметрам, вы будете использовать + =. Если вы хотите заменить параметры, просто используйте =. – eltiare

+1

вы не всегда этого хотите, потому что, если вы используете scss, вложенные папки обычно импортируются. Обычно уровня корня достаточно. – Pencilcheck

0

Этот фрагмент кода включает в себя все файлы JS/CSS, за исключением драгоценных камней под: приложение/активов, поставщика/активы, Lib/активы, если они не являются частичными файлы (например, "_file.sass"). Он также имеет стратегию включения активов из драгоценных камней, которые не включены в каждую страницу.

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

Хотя, вы, вероятно, не хотели бы, чтобы это сделать, так как вы, вероятно, будете Прекомпиляция драгоценных активов в два раза (в основном все, что уже \ = require'd в вашем application.js или CSS). Этот фрагмент кода включает в себя все 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

это было самое элегантное, хотя я использовал + = вместо просто = –

2

Я пересматривают этот пост в 2017 году

Наш продукт по-прежнему сильно используя RoR, мы постоянно изменяя наши конфигурации прекомпиляции путем добавления Rails.application.config.assets.precompile, как мы добавляем новые модули. Недавно я пытался оптимизировать, добавив регулярное выражение, я обнаружил, что следующая картина Глоба работой:

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$/] 

, который работает хорошо.

Смежные вопросы