Конфигурация Rails.активы.настройка предварительной компиляции для обработки всех файлов CSS и JS в app/assets

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

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

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

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

8 ответов


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

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


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

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

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

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


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

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

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

Примечание: это также будет предварительно скомпилировать все CSS / JavaScript, включенные через rubygems.


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

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

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

сопоставление по умолчанию для компиляции файлов включает приложение.Яш, приложение.css и все не-JS/CSS файлы

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

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

Это все .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)

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

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


я перечитываю этот пост в 2017 году.

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

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

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

пока я не посмотрел в исходный код звездочек:https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb#L108, я обнаружил, что они уже используют regex:

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

поэтому я меняю свой код на:

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

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


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

    # 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 в вашем приложение.js или css). Этот фрагмент включает в себя все файлы JS и CSS, в том числе драгоценных камней, в разделе: app / assets,поставщик/активы, 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
}