Rails config.assets.precompile设置用于处理app / assets中的所有CSS和JS文件

时间:2012-04-10 23:41:14

标签: ruby-on-rails ruby-on-rails-3 sprockets

我希望在项目的app/assets文件夹中预编译所有CSS和JS文件。我不想在供应商/资产或lib / assets中预编译所有内容,只需要根据需要预先编译我的文件的依赖项。

我尝试了以下通配符设置,但它错误地预编译了所有内容。这导致了大量的额外工作,甚至在使用bootstrap-sass时导致编译失败。

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

我最好只在app/assets处理我的文件?谢谢!

8 个答案:

答案 0 :(得分:23)

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

无论目录深度如何,这都将编译资产路径中的任何JavaScript或CSS。通过this answer找到。

答案 1 :(得分:19)

由于sprockets使用的逻辑路径不包含底层未编译资源所在的位置,因此该任务变得更加困难。

假设我的项目有JS文件“/app/assets/javascripts/foo/bar.js.coffee”。

sprockets编译器将首先确定输出文件扩展名,在本例中为“.js”,然后评估是否编译逻辑路径“foo / bar.js”。未编译的资源可能位于“app / assets / javascripts”,“vendor / assets / javascripts”,“lib / assets / javascripts”或gem中,因此无法根据逻辑路径包含/排除特定文件单独

要确定底层资源的位置,我认为有必要询问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
}

使用链轮&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

答案 2 :(得分:15)

对techpeace的回答稍作调整:

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

我会在他的回答中添加评论,但我还没有足够的声誉。给我一个upvote,我会在那里!

注意:这也将预编译通过rubygems包含的所有CSS / JavaScript。

答案 3 :(得分:7)

我在rails代码中找到了这个:

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

使用导轨指南进行备份:

  

编译文件的默认匹配器包括application.js,   application.css和所有非JS / CSS文件

如果您使用+=,则不会重置此默认设置,因此您需要使用=而不是+=覆盖它。请注意,显然,您可以将Proc或正则表达式传递给precompile以及扩展名。我相信,如果你只想在顶级目录中预编译文件,你将不得不创建一个像这样的正则表达式:

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

答案 4 :(得分: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)

答案 5 :(得分: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$/]

效果很好。

答案 6 :(得分:2)

我希望编译来自/ app和/ vendor的所有资产,除了partials(名称从下划线_开始)。所以这是我在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 :(得分:0)

此代码段包含所有js / css文件,不包括宝石,位于:app / assets, 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资产进行两次预编译(基本上任何已经在您的application.js或css中已经需要的东西)。此代码段包含所有js / css文件,包括宝石,位于:app / assets, 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
}