51 lines
1.9 KiB
Ruby
51 lines
1.9 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",
|
|
)
|
|
# rubocop:disable Rails/RootPathnameMethods
|
|
sourcemap_path = File.join(::Rails.public_path, sourcemap_filename)
|
|
# rubocop:enable Rails/RootPathnameMethods
|
|
sourcemap_url = filename_to_url(sourcemap_filename)
|
|
|
|
FileUtils.mkdir_p File.dirname(sourcemap_path)
|
|
File.write(sourcemap_path, 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,
|
|
)
|