class Pakyow::Assets::Asset
Represents an asset.
Instances are created when booting in all environments, meaning the app is guaranteed access to these objects. Contents are loaded and processed eagerly. This is expected to happen under two scenarios:
1. In development, an asset is loaded and processed when it's requested. 2. In production, when assets are precompiled during a deployment.
Attributes
dependencies[R]
logical_path[R]
mime_suffix[R]
mime_type[R]
Public Class Methods
inherited(asset_class)
click to toggle source
@api private
Calls superclass method
# File lib/pakyow/assets/asset.rb, line 52 def inherited(asset_class) @__types << asset_class super end
load()
click to toggle source
Implemented by subclasses to load any libraries they need.
# File lib/pakyow/assets/asset.rb, line 47 def load # intentionally empty end
new(local_path:, config:, dependencies: [], source_location: "", prefix: "/", related: [])
click to toggle source
# File lib/pakyow/assets/asset.rb, line 91 def initialize(local_path:, config:, dependencies: [], source_location: "", prefix: "/", related: []) @local_path, @config, @source_location, @dependencies, @related = local_path, config, source_location, dependencies, related @logical_path = self.class.update_path_for_emitted_type( String.normalize_path( File.join(prefix, local_path.sub(source_location, "")) ) ) @public_path = String.normalize_path( File.join(config.prefix, @logical_path) ) @mime_type = case File.extname(@public_path) when ".js" # Resolves an issue with mini_mime returning `application/ecmascript` # "application/javascript" else MiniMime.lookup_by_filename(@public_path)&.content_type.to_s end @mime_prefix, @mime_suffix = @mime_type.split("/", 2) @source_map_enabled = config.source_maps @mutex = Mutex.new end
new_from_path(path, config:, source_location: "", prefix: "/", related: [])
click to toggle source
# File lib/pakyow/assets/asset.rb, line 31 def new_from_path(path, config:, source_location: "", prefix: "/", related: []) asset_class = @__types.find { |type| type.__extensions.include?(File.extname(path)) } || self asset_class.load; asset_class.new( local_path: path, source_location: source_location, config: config, prefix: prefix, related: related ) end
update_path_for_emitted_type(path)
click to toggle source
@api private
# File lib/pakyow/assets/asset.rb, line 58 def update_path_for_emitted_type(path) if @__emits path.sub(File.extname(path), @__emits) else path end end
Private Class Methods
emits(type)
click to toggle source
Defines the emitted asset type (e.g. sass
emits css
).
# File lib/pakyow/assets/asset.rb, line 84 def emits(type) @__emits = ".#{type}" end
extension(extension)
click to toggle source
Registers extension
for this asset.
# File lib/pakyow/assets/asset.rb, line 70 def extension(extension) extensions(extension) end
extensions(*extensions)
click to toggle source
Registers multiple extensions for this asset.
# File lib/pakyow/assets/asset.rb, line 76 def extensions(*extensions) extensions.each do |extension| @__extensions << ".#{extension}" end end
Public Instance Methods
bytesize()
click to toggle source
# File lib/pakyow/assets/asset.rb, line 148 def bytesize ensure_content(&:bytesize) end
disable_source_map()
click to toggle source
# File lib/pakyow/assets/asset.rb, line 195 def disable_source_map tap do @source_map_enabled = false end end
each(&block)
click to toggle source
# File lib/pakyow/assets/asset.rb, line 134 def each(&block) ensure_content do |content| StringIO.new(post_process(content)).each(&block) end end
fingerprint()
click to toggle source
# File lib/pakyow/assets/asset.rb, line 152 def fingerprint [@local_path].concat(dependencies).each_with_object(Digest::MD5.new) { |path, digest| digest.update(Digest::MD5.file(path).hexdigest) }.hexdigest end
fingerprinted_filename()
click to toggle source
# File lib/pakyow/assets/asset.rb, line 158 def fingerprinted_filename extension = File.extname(@public_path) File.basename(@public_path, extension) + "__" + fingerprint + extension end
freeze()
click to toggle source
Overriding and freezing after content is set lets us eagerly process the content rather than incurring that cost on boot.
Calls superclass method
# File lib/pakyow/assets/asset.rb, line 123 def freeze @freezing = true unless @freezing public_path end if instance_variable_defined?(:@content) && (!@config.fingerprint || instance_variable_defined?(:@fingerprinted_public_path)) super end end
public_path()
click to toggle source
# File lib/pakyow/assets/asset.rb, line 163 def public_path if @config.fingerprint unless instance_variable_defined?(:@fingerprinted_public_path) @fingerprinted_public_path = File.join( File.dirname(@public_path), fingerprinted_filename ) freeze end @fingerprinted_public_path else @public_path end end
read()
click to toggle source
# File lib/pakyow/assets/asset.rb, line 140 def read String.new.tap do |asset| each do |content| asset << content end end end
source_map()
click to toggle source
# File lib/pakyow/assets/asset.rb, line 184 def source_map if source_map? SourceMap.new( source_map_content, file: File.basename(public_path) ) else nil end end
source_map?()
click to toggle source
# File lib/pakyow/assets/asset.rb, line 180 def source_map? respond_to?(:source_map_content) end
Private Instance Methods
embed_mapping_url(content)
click to toggle source
# File lib/pakyow/assets/asset.rb, line 242 def embed_mapping_url(content) content + SourceMap.mapping_url(path: public_path, type: @mime_suffix) end
ensure_content() { |content| ... }
click to toggle source
# File lib/pakyow/assets/asset.rb, line 203 def ensure_content @mutex.synchronize do unless frozen? || instance_variable_defined?(:@content) @content = load_content; freeze end end yield @content if block_given? end
external?()
click to toggle source
# File lib/pakyow/assets/asset.rb, line 246 def external? File.dirname(@local_path) == @config.externals.path end
load_content()
click to toggle source
# File lib/pakyow/assets/asset.rb, line 213 def load_content content = process(File.read(@local_path)).to_s if mime_suffix == "css" || mime_suffix == "javascript" # Update references to related assets with prefixed path, fingerprints. # Do this here rather than in post-processing so that the source maps reflect the changes. # @related.each do |asset| if asset != self && content.include?(asset.logical_path) content.gsub!(asset.logical_path, File.join(@config.host, asset.public_path)) end end end content end
post_process(content)
click to toggle source
# File lib/pakyow/assets/asset.rb, line 234 def post_process(content) if @source_map_enabled && source_map? embed_mapping_url(content) else content end end
process(content)
click to toggle source
# File lib/pakyow/assets/asset.rb, line 230 def process(content) content end