我希望预编译项目app/assets
文件夹中的所有 CSS 和 JS 文件。我不想预编译 vendor/assets 或 lib/assets 中的所有内容,只需要根据需要预编译我的文件的依赖项。
我尝试了以下通配符设置,但它错误地预编译了所有内容。这会导致大量额外工作,甚至在使用 bootstrap-sass 时导致编译失败。
config.assets.precompile += ['*.js', '*.css']
我最好的选择是只处理我的文件app/assets
?谢谢!
我希望预编译项目app/assets
文件夹中的所有 CSS 和 JS 文件。我不想预编译 vendor/assets 或 lib/assets 中的所有内容,只需要根据需要预编译我的文件的依赖项。
我尝试了以下通配符设置,但它错误地预编译了所有内容。这会导致大量额外工作,甚至在使用 bootstrap-sass 时导致编译失败。
config.assets.precompile += ['*.js', '*.css']
我最好的选择是只处理我的文件app/assets
?谢谢!
config.assets.precompile = ['*.js', '*.css']
这将编译资产路径中的任何 JavaScript 或 CSS,无论目录深度如何。通过这个答案找到。
由于 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
}
对于 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)
对 techpeace 的回答稍作调整:
config.assets.precompile = ['*.js', '*.css', '**/*.js', '**/*.css']
我会在他的回答中添加评论,但我还没有足够的声誉。给我一个upvote,我会在那里!
注意:这也将预编译通过 rubygems 包含的所有 CSS/JavaScript。
我在rails代码中找到了这个:
@assets.precompile = [ Proc.new{ |path| !File.extname(path).in?(['.js', '.css']) },
/(?:\/|\\|\A)application\.(css|js)$/ ]
这是由rails指南支持的:
编译文件的默认匹配器包括 application.js、application.css 和所有非 JS/CSS 文件
如果使用 ,则不会重置此默认值+=
,因此您需要使用 a=
而不是覆盖它+=
。请注意,显然,您可以将 Proc 或正则表达式传递给precompile
扩展名。我相信,如果您只想预编译顶级目录中的文件,则必须创建一个正则表达式,例如:
config.assets.precompile = [ /\A[^\/\\]+\.(ccs|js)$/i ]
我在 2017 年重温这篇文章。
我们的产品仍然大量使用 RoR,我们一直在通过Rails.application.config.assets.precompile
添加新模块来不断修改我们的预编译配置。最近我试图通过添加一个正则表达式模式来优化它,我发现以下 glob 模式有效:
Rails.application.config.assets.precompile += %w(**/bundle/*.js)
但是我仍然需要排除某些模块,所以我努力使用正则表达式而不是 glob。
在我查看 sprockets 源代码: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$/]
哪个效果很好。
这将获取所有.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 的所有资产,除了部分(名称以下划线 _ 开头)。所以这是我在 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
}
此外,它还输出为调试目的而编译的文件列表...
此片段包括所有 js/css 文件,不包括 gems,位于: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 中已经 \=require'd 的东西)。此片段包括所有 js/css 文件,包括 gems,位于: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
}