docbrown/config/initializers/sprockets_uglifier_with_source_maps_compressor.rb

49 lines
1.8 KiB
Ruby

require "sprockets/digest_utils"
require "sprockets/uglifier_compressor"
module Sprockets
class UglifierWithSourceMapsCompressor < Sprockets::UglifierCompressor
def call(input)
data = input.fetch(:data) # Non-Uglified contents of the JS file
name = input.fetch(:name) # name of the to-be-compressed JS file.
@uglifier ||= Autoload::Uglifier.new(@options.merge({ harmony: true }))
compressed_data, sourcemap_json = @uglifier.compile_with_map(input[:data])
# Update source map according to the version 3 spec: https://sourcemaps.info/spec.html
sourcemap = JSON.parse(sourcemap_json)
sourcemap["sources"] = ["#{name}.js"]
sourcemap["sourceRoot"] = ::Rails.application.config.assets.prefix
sourcemap["sourcesContent"] = [data]
sourcemap_json = sourcemap.to_json
sourcemap_filename = File.join(
::Rails.application.config.assets.prefix,
"#{name}-#{digest(sourcemap_json)}.js.map",
)
sourcemap_path = File.join(::Rails.public_path, sourcemap_filename)
sourcemap_url = filename_to_url(sourcemap_filename)
FileUtils.mkdir_p File.dirname(sourcemap_path)
File.open(sourcemap_path, "w") { |f| f.write sourcemap_json }
# Add the source map URL to the compressed JS file.
compressed_data.concat "\n//# sourceMappingURL=#{sourcemap_url}\n"
end
def filename_to_url(filename)
url_root = ::Rails.application.config.assets.source_maps_domain
File.join url_root.to_s, filename
end
def digest(io)
Sprockets::DigestUtils.pack_hexdigest Sprockets::DigestUtils.digest(io)
end
end
end
Sprockets.register_compressor(
"application/javascript",
:uglify_with_source_maps,
Sprockets::UglifierWithSourceMapsCompressor,
)