lib/sprockets/add_source_map_comment_to_asset_processor.rb



# frozen_string_literal: true
require 'sprockets/uri_utils'
require 'sprockets/path_utils'

module Sprockets
  # This is a processor designed to add a source map "comment"
  # to the bottom of a css or JS file that is serving a source
  # map. An example of a comment might look like this
  #
  #    //# application.js-80af0efcc960fc2ac93eda2f7b12e3db40ab360bf6ea269ceed3bea3678326f9.map
  #
  # As an asset is built it gets source map information added
  # to the `asset.to_hash[:metadata][:map]` key. This contains all the
  # information that is needed to build a source map file.
  #
  # To add this comment we must have an asset we can link to.
  # To do this we ensure that the original asset is loaded, then
  # we use a use a special mime type. For example `application/js-sourcemap+json`
  # for a JS source map.
  #
  # This will trigger a new asset to be loaded and generated by the
  # `SourceMapProcessor` processor.
  #
  # Finally once we have that file, we can generate a link to it
  # with it's full fingerprint. This is done and then
  # added to the original asset as a comment at the bottom.
  #
  class AddSourceMapCommentToAssetProcessor
    def self.call(input)

      case input[:content_type]
      when "application/javascript"
        comment = "\n//# sourceMappingURL=%s"
        map_type = "application/js-sourcemap+json"
      when "text/css"
        comment = "\n/*# sourceMappingURL=%s */"
        map_type = "application/css-sourcemap+json"
      else
        fail input[:content_type]
      end

      env = input[:environment]

      uri, _ = env.resolve!(input[:filename], accept: input[:content_type])
      asset = env.load(uri)

      uri, _ = env.resolve!(input[:filename], accept: map_type)
      map = env.load(uri)

      uri, params = URIUtils.parse_asset_uri(input[:uri])
      uri = env.expand_from_root(params[:index_alias]) if params[:index_alias]
      path = PathUtils.relative_path_from(PathUtils.split_subpath(input[:load_path], uri), map.digest_path)

      asset.metadata.merge(
        data: asset.source + (comment % path) + "\n",
        links: asset.links + [asset.uri, map.uri]
      )
    end
  end
end