我目前正在实现一个运行时模块,它创建一个 sass 文件,从中生成一个 css 文件,删除 sass 并继续其生命。我在链轮上的轨道上。我一直在研究内部结构,并发现了它的 static_compiler 类。所以,我一步一步正在做的是:
现在,我很难使用 sass“image-url”方法和 png。我在 sass 文件上使用它,如下所示:
image-url("image.png")
image-url("image.svg")
指向 app/assets 下的正确子目录。摘要 image.svg 文件的名称是正确生成的,即 css 文件上的摘要密钥与文件中的摘要密钥相匹配。但同样的情况不会发生在 png 上,css 文件中的摘要键与文件中的摘要键不匹配。我很难调试这个,因为不太清楚“image-url”助手的声明位置。有谁知道为什么这只发生在 png 上和/或 image-url 方法在哪里定义? (我只知道它不是 sass 文件,所以它一定是 Rails 依赖项)。
编辑:
这是我的脚本示例:
bundled_sass = Sprockets::BundledAsset.new(Rails.application.assets, "random_name.css", sassfile_path)
bundled_svg = Sprockets::StaticAsset.new(Rails.application.assets, "sprite.svg", svgfile_path)
bundled_png = Sprockets::StaticAsset.new(Rails.application.assets, "sprite.png", pngfile_path)
compiler = Sprockets::StaticCompiler.new(Rails.application.assets,
destination_path,
Rails.application.config.assets.precompile,
#:manifest_path => Rails.application.config.assets.manifest,
:digest => Rails.application.config.assets.digest,
:manifest => true)
compiler.write_asset(bundled_svg)
compiler.write_asset(bundled_png)
compiler.write_asset(bundled_sass)
将 config.assets.digest 选项设置为 true,svg 和 png 会被复制到目标路径文件夹(通常是 public/assets),并且它们的名称会获得摘要密钥。编译 sass 文件时,为 svg url 生成的密钥是正确的。用于 png url 的摘要密钥与文件上的摘要密钥不同。
解析器从
"image_url"
中的 "image-url"
生成 @name
:
https://github.com/sass/ruby-sass/blob/3.7.4/lib/sass/script/tree/funcall.rb#L177
def ruby_name
@ruby_name ||= @name.tr('-', '_')
end
然后调用
image_url
方法。
https://github.com/rails/sprockets/blob/v3.7.3/lib/sprockets/sass_processor.rb#L154
def image_url(path)
asset_url(path, type: :image)
end
image_url
致电 asset_url
,asset_url
致电 asset_path
:
https://github.com/rails/sprockets/blob/v3.7.3/lib/sprockets/sass_processor.rb#L120-L129
def asset_path(path, options = {})
path = path.value
path, _, query, fragment = URI.split(path)[5..8]
path = sprockets_context.asset_path(path, options)
query = "?#{query}" if query
fragment = "##{fragment}" if fragment
Autoload::Sass::Script::String.new("#{path}#{query}#{fragment}", :string)
end
解析器是用C实现的,所以我找不到定义,但是
image_url
是在链轮中定义的:
https://github.com/rails/sprockets/blob/v3.7.3/lib/sprockets/sass_processor.rb#L153C40-L156C10
def image_url(path)
asset_url(path, type: :image)
end
image_url
呼叫 asset_url
,asset_url
呼叫 asset_path
。它在 sassc-rails 中定义:
https://github.com/sass/sassc-rails/blob/v2.1.2/lib/sassc/rails/template.rb#L86-L95
def asset_path(path, options = {})
path = path.value
path, _, query, fragment = URI.split(path)[5..8]
path = sprockets_context.asset_path(path, options)
query = "?#{query}" if query
fragment = "##{fragment}" if fragment
::SassC::Script::Value::String.new("#{path}#{query}#{fragment}", :string)
end
image-url
不再定义。您可以使用 url
代替。
url("image.png")
url("image.svg")
sprockets-rails 3.3 或更高版本将用摘要路径替换参数:
https://github.com/rails/sprockets-rails/blob/v3.5.1/lib/sprockets/rails/asset_url_processor.rb
module Sprockets
module Rails
# Resolve assets referenced in CSS `url()` calls and replace them with the digested paths
class AssetUrlProcessor
REGEX = /url\(\s*["']?(?!(?:\#|data|http))(?<relativeToCurrentDir>\.\/)?(?<path>[^"'\s)]+)\s*["']?\)/
def self.call(input)
context = input[:environment].context_class.new(input)
data = input[:data].gsub(REGEX) do |_match|
path = Regexp.last_match[:path]
"url(#{context.asset_path(path)})"
end
context.metadata.merge(data: data)
end
end
end
end