Вопрос по ruby-on-rails, ruby-on-rails-3 – Настройка Rails config.assets.precompile для обработки всех файлов CSS и JS в app / assets

30

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

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

<code>config.assets.precompile += ['*.js', '*.css']
</code>

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

возможный дубликатHow do I use config.assets.precompile for directories rather than single files? Jason

Ваш Ответ

8   ответов
23

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

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

Нет, это не будет входить в глубокую папку. Вы должны использовать [& apos; your_inner_directory_name / *. Js & apos;] для компиляции внутренних файлов
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
}

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

Это единственное, что сработало для меня, потратив пару дней, пробуя всевозможные возможные решения. Работает даже сdatejs-rails а такжеbootstrap-sass драгоценные камни (которые могут вызвать всевозможные проблемы с другими решениями).
0

Этот фрагмент включает в себя все файлы JS / CSS,excluding gemsпод: приложение / активы,vendor/assets, lib/assetsесли только они не являются частичными файлами (например, "_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
    }

Хотя вы, вероятно, не захотите этого делать, так как вы, вероятно, будете дважды компилировать ресурсы gem (в основном все, что уже \ = require & d; d в вашем application.js или css). Этот фрагмент включает в себя все файлы JS / CSS,including gemsпод: приложение / активы,vendor/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
}
19

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

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

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

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

Со звездочками & gt; 3.0, это не будет работать в рабочей среде, поскольку Rails.application.assets будет иметь значение nil (при условии, что по умолчанию: 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

если вы заинтересованы в занесении в черный список активов Regex, смотрите здесь:stackoverflow.com/a/34801799/770670
Кто-то скопировал ваш ответ:stackoverflow.com/a/15553781/601607
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)
это было самым элегантным, хотя я использовал + = вместо просто =
7

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

Которая подкреплена направляющей рельсов:

The default matcher for compiling files includes application.js, application.css and all non-JS/CSS files

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

config.assets.precompile = [ /\A[^\/\\]+\.(ccs|js)$/i ]
Майкл, я ценю твой ответ, который привел меня к правильному ответу. Я хочу предварительно скомпилировать каждый файл css / js в дереве app / assets, а не только в каталоге верхнего уровня. К сожалению, путь, передаваемый в proc, является логическим путем, который не различает приложение / активы, поставщика / активы, lib / assets и т. Д., Поэтому было необходимо больше копать. Смотрите мой ответ для используемого решения. keithgaputis
Теперь я понимаю, как использовать REGEX вRails.application.config.assets.precompile линия. Я только что искал в сети в течение часа, чтобы понять это. Не документировано в другом месте. Спасибо.
14

Небольшое изменение в ответе techpeace:

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

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

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

это только= или же+= ?
Извините, не видел этого раньше. Вы можете использовать либо. Если вы хотите добавить к текущим параметрам, вы будете использовать + =. Если вы хотите заменить опции, просто используйте =.
Вы не всегда хотите этого, потому что, если вы используете scss, вложенные папки обычно импортируются. Просто корневого уровня обычно достаточно.
3

Я возвращаюсь к этому сообщению в 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$/]

Который работает хорошо.

Похожие вопросы