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

kei*_*tis 31 ruby-on-rails ruby-on-rails-3 sprockets

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

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

config.assets.precompile += ['*.js', '*.css']
Run Code Online (Sandbox Code Playgroud)

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

tec*_*ace 23

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

这将编译资产路径中的任何JavaScript或CSS,无论目录深度如何.通过这个答案找到.

  • 不,它不会进入深层文件夹.您必须使用['your_inner_directory_name/*.js']来编译内部文件 (3认同)

kei*_*tis 20

由于链轮使用的逻辑路径不包括底层未编译资源所在的位置,因此这项任务变得更加困难.

假设我的项目有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
}
Run Code Online (Sandbox Code Playgroud)

对于sprockets> 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)
Run Code Online (Sandbox Code Playgroud)

另见:https://github.com/rails/sprockets-rails/issues/237


elt*_*are 17

对techpeace的回答略有调整:

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

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

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


Mic*_*ade 7

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

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

哪个是使用rails指南备份的:

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

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

config.assets.precompile = [ /\A[^\/\\]+\.(ccs|js)$/i ]
Run Code Online (Sandbox Code Playgroud)


Evi*_*ong 6

我在 2017 年重温了这篇文章。

我们的产品仍然大量使用 RoR,我们一直在通过Rails.application.config.assets.precompile添加新模块来不断修改我们的预编译配置。最近我试图通过添加正则表达式模式来优化它,我发现以下 glob 模式有效:

Rails.application.config.assets.precompile += %w(**/bundle/*.js)
Run Code Online (Sandbox Code Playgroud)

但是我仍然需要排除某些模块,所以我努力使用正则表达式而不是 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)$/]
Run Code Online (Sandbox Code Playgroud)

所以我把我的代码改成:

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

哪个效果很好。