Подтвердить что ты не робот

Настройка Rails config.assets.precompile для обработки всех файлов CSS и JS в приложении/активах

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

Я попробовал следующие настройки подстановочного знака, но он неправильно прекомпилирует все. Это приводит к большому количеству дополнительной работы и даже приводит к сбою компиляции при использовании bootstrap-sass.

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

Какова моя самая лучшая ставка только для обработки моих файлов в app/assets? Спасибо!

4b9b3361

Ответ 1

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

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

Компилятор sprockets сначала определит расширение выходного файла, в данном случае ".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
}

С sprockets > 3.0 это не будет работать в процессе производства, потому что Rails.application.assets будет равно nil (при условии, что default: config.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

Ответ 2

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

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

Ответ 3

Небольшая настройка для ответа Techpeace:

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

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

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

Ответ 4

Я нашел это в коде rails:

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

который подкрепляется направляющей направляющих:

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

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

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

Ответ 5

Это получит все .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)

Ответ 6

Я хотел, чтобы все активы из /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
}

Кроме того, он выводит список файлов, скомпилированных для целей отладки...

Ответ 7

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

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

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

Однако мне все еще нужно исключить определенные модули, поэтому я старался использовать регулярное выражение вместо glob.

Пока я не посмотрел исходный код звездочек: 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$/]

Это хорошо работает.

Ответ 8

Этот фрагмент включает все файлы js/css, исключая драгоценные камни, в разделе: app/assets, поставщик/активы, lib/assets если они не являются частичными файлами (например, "_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, , включая драгоценные камни, в разделе: app/assets, поставщик/активы, lib/assets, если только они не являются частичные файлы (например, "_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
}