FEATURE: source maps in production for JavaScripts
This commit is contained in:
parent
2535e22151
commit
f8fb823924
|
@ -82,7 +82,7 @@ GEM
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
eventmachine (1.0.3)
|
eventmachine (1.0.3)
|
||||||
excon (0.39.6)
|
excon (0.39.6)
|
||||||
execjs (2.2.1)
|
execjs (2.2.2)
|
||||||
exifr (1.1.3)
|
exifr (1.1.3)
|
||||||
fabrication (2.9.8)
|
fabrication (2.9.8)
|
||||||
fakeweb (1.3.0)
|
fakeweb (1.3.0)
|
||||||
|
@ -390,7 +390,7 @@ GEM
|
||||||
trollop (2.0)
|
trollop (2.0)
|
||||||
tzinfo (1.2.2)
|
tzinfo (1.2.2)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (2.5.3)
|
uglifier (2.6.0)
|
||||||
execjs (>= 0.3.0)
|
execjs (>= 0.3.0)
|
||||||
json (>= 1.8.0)
|
json (>= 1.8.0)
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
|
|
|
@ -11,6 +11,12 @@ task 'assets:precompile:before' do
|
||||||
puts "Purging temp files"
|
puts "Purging temp files"
|
||||||
`rm -fr #{Rails.root}/tmp/cache`
|
`rm -fr #{Rails.root}/tmp/cache`
|
||||||
|
|
||||||
|
if Rails.configuration.assets.js_compressor == :uglifier
|
||||||
|
ENV["UGLIFY"] = "1"
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Bundling assets"
|
||||||
|
|
||||||
# in the past we applied a patch that removed asset postfixes, but it is terrible practice
|
# in the past we applied a patch that removed asset postfixes, but it is terrible practice
|
||||||
# leaving very complicated build issues
|
# leaving very complicated build issues
|
||||||
# https://github.com/rails/sprockets-rails/issues/49
|
# https://github.com/rails/sprockets-rails/issues/49
|
||||||
|
@ -19,46 +25,44 @@ task 'assets:precompile:before' do
|
||||||
require 'sprockets'
|
require 'sprockets'
|
||||||
require 'digest/sha1'
|
require 'digest/sha1'
|
||||||
|
|
||||||
|
|
||||||
|
# monkey patch asset pipeline not to gzip, compress: false is broken
|
||||||
|
class ::Sprockets::Asset
|
||||||
|
# Save asset to disk.
|
||||||
|
def write_to(filename, options = {})
|
||||||
|
# Gzip contents if filename has '.gz'
|
||||||
|
return if File.extname(filename) == '.gz'
|
||||||
|
|
||||||
|
begin
|
||||||
|
FileUtils.mkdir_p File.dirname(filename)
|
||||||
|
|
||||||
|
File.open("#{filename}+", 'wb') do |f|
|
||||||
|
f.write to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
# Atomic write
|
||||||
|
FileUtils.mv("#{filename}+", filename)
|
||||||
|
|
||||||
|
# Set mtime correctly
|
||||||
|
File.utime(mtime, mtime, filename)
|
||||||
|
|
||||||
|
nil
|
||||||
|
ensure
|
||||||
|
# Ensure tmp file gets cleaned up
|
||||||
|
FileUtils.rm("#{filename}+") if File.exist?("#{filename}+")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
module ::Sprockets
|
module ::Sprockets
|
||||||
|
|
||||||
def self.redis
|
|
||||||
@redis ||=
|
|
||||||
(
|
|
||||||
redis_url = GlobalSetting.asset_redis_url
|
|
||||||
if redis_url.present?
|
|
||||||
uri = URI.parse(redis_url)
|
|
||||||
options = {}
|
|
||||||
options[:password] = uri.password if uri.password.present?
|
|
||||||
options[:host] = uri.host
|
|
||||||
options[:port] = uri.port || 6379
|
|
||||||
Redis.new(options)
|
|
||||||
else
|
|
||||||
DiscourseRedis.raw_connection
|
|
||||||
end
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.cache_compiled(type, data)
|
|
||||||
# add cache breaker here if uglifier options change
|
|
||||||
digest = Digest::SHA1.hexdigest(data) << "v1"
|
|
||||||
key = "SPROCKETS_#{type}_#{digest}"
|
|
||||||
if compiled = redis.get(key)
|
|
||||||
redis.expire(key, 1.week)
|
|
||||||
else
|
|
||||||
compiled = yield
|
|
||||||
redis.setex(key, 1.week, compiled)
|
|
||||||
end
|
|
||||||
compiled
|
|
||||||
end
|
|
||||||
|
|
||||||
class UglifierCompressor
|
class UglifierCompressor
|
||||||
|
|
||||||
def evaluate(context, locals, &block)
|
def evaluate(context, locals, &block)
|
||||||
::Sprockets.cache_compiled("uglifier", data) do
|
# monkey patch cause we do this later, no idea how to cleanly disable
|
||||||
Uglifier.new(:comments => :none,
|
data
|
||||||
:screw_ie8 => false,
|
|
||||||
:output => {max_line_len: 1024}).compile(data)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -79,7 +83,77 @@ task 'assets:precompile:css' => 'environment' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def assets_path
|
||||||
|
"#{Rails.root}/public/assets"
|
||||||
|
end
|
||||||
|
|
||||||
|
def compress_node(from,to)
|
||||||
|
to_path = "#{assets_path}/#{to}"
|
||||||
|
|
||||||
|
source_map_root = (d=File.dirname(from)) == "." ? "/assets" : "/assets/#{d}"
|
||||||
|
|
||||||
|
STDERR.puts `uglifyjs '#{assets_path}/#{from}' -p relative -c -m -o '#{to_path}' --source-map-root '#{source_map_root}' --source-map '#{assets_path}/#{to}.map' --source-map-url '/assets/#{to}.map'`
|
||||||
|
end
|
||||||
|
|
||||||
|
def compress_ruby(from,to)
|
||||||
|
data = File.read("#{assets_path}/#{from}")
|
||||||
|
|
||||||
|
uglified, map = Uglifier.new(comments: :none,
|
||||||
|
screw_ie8: false,
|
||||||
|
source_filename: File.basename(from),
|
||||||
|
output_filename: File.basename(to)
|
||||||
|
)
|
||||||
|
.compile_with_map(data)
|
||||||
|
dest = "#{assets_path}/#{to}"
|
||||||
|
|
||||||
|
File.write(dest, uglified << "\n//# sourceMappingURL=/assets/#{to}.map")
|
||||||
|
File.write(dest + ".map", map)
|
||||||
|
end
|
||||||
|
|
||||||
|
def gzip(path)
|
||||||
|
STDERR.puts "gzip #{path}"
|
||||||
|
STDERR.puts `gzip -f -k -9 #{path}`
|
||||||
|
end
|
||||||
|
|
||||||
|
def compress(from,to)
|
||||||
|
if @has_uglifyjs ||= !`which uglifyjs`.empty?
|
||||||
|
compress_node(from,to)
|
||||||
|
else
|
||||||
|
compress_ruby(from,to)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
task 'assets:precompile' => 'assets:precompile:before' do
|
task 'assets:precompile' => 'assets:precompile:before' do
|
||||||
# Run after assets:precompile
|
# Run after assets:precompile
|
||||||
Rake::Task["assets:precompile:css"].invoke
|
Rake::Task["assets:precompile:css"].invoke
|
||||||
|
|
||||||
|
if ENV["UGLIFY"]
|
||||||
|
puts "Compressing Javascript and Generating Source Maps"
|
||||||
|
manifest = Sprockets::Manifest.new(assets_path)
|
||||||
|
manifest.files
|
||||||
|
.select{|k,v| k =~ /\.js$/}
|
||||||
|
.each do |file, info|
|
||||||
|
|
||||||
|
path = "#{assets_path}/#{file}"
|
||||||
|
_file = (d = File.dirname(file)) == "." ? "_#{file}" : "#{d}/_#{File.basename(file)}"
|
||||||
|
_path = "#{assets_path}/#{_file}"
|
||||||
|
|
||||||
|
if File.exists?(_path)
|
||||||
|
STDERR.puts "Skipping: #{file} already compressed"
|
||||||
|
else
|
||||||
|
STDERR.puts "Compressing: #{file}"
|
||||||
|
FileUtils.mv(path, _path)
|
||||||
|
compress(_file,file)
|
||||||
|
|
||||||
|
info["size"] = File.size(path)
|
||||||
|
info["mtime"] = File.mtime(path).iso8601
|
||||||
|
gzip(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# protected
|
||||||
|
manifest.send :save
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue