Rewrite gzip_assets to work as a post-build step and to leave uncompressed versions around.
This commit is contained in:
parent
cf9e59db83
commit
af605a909b
|
@ -5,6 +5,9 @@ Feature: GZIP assets during build
|
||||||
Then the following files should exist:
|
Then the following files should exist:
|
||||||
| build/javascripts/test.js.gz |
|
| build/javascripts/test.js.gz |
|
||||||
| build/stylesheets/test.css.gz |
|
| build/stylesheets/test.css.gz |
|
||||||
|
| build/index.html.gz |
|
||||||
|
| build/javascripts/test.js |
|
||||||
|
| build/stylesheets/test.css |
|
||||||
| build/index.html |
|
| build/index.html |
|
||||||
When I run `file build/javascripts/test.js.gz`
|
When I run `file build/javascripts/test.js.gz`
|
||||||
Then the output should contain "gzip"
|
Then the output should contain "gzip"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
require 'zlib'
|
require 'zlib'
|
||||||
require 'stringio'
|
require 'stringio'
|
||||||
|
require 'find'
|
||||||
|
|
||||||
module Middleman::Extensions
|
module Middleman::Extensions
|
||||||
|
|
||||||
|
@ -12,73 +13,42 @@ module Middleman::Extensions
|
||||||
# to serve your Gzipped files whenever the normal (non-.gz) filename is requested.
|
# to serve your Gzipped files whenever the normal (non-.gz) filename is requested.
|
||||||
#
|
#
|
||||||
# Pass the :exts options to customize which file extensions get zipped (defaults
|
# Pass the :exts options to customize which file extensions get zipped (defaults
|
||||||
# to .js and .css.
|
# to .html, .htm, .js and .css.
|
||||||
#
|
#
|
||||||
module GzipAssets
|
module GzipAssets
|
||||||
class << self
|
class << self
|
||||||
def registered(app, options={})
|
def registered(app, options={})
|
||||||
exts = options[:exts] || %w(.js .css)
|
exts = options[:exts] || %w(.js .css .html .htm)
|
||||||
|
|
||||||
return unless app.inst.build?
|
app.send :include, InstanceMethods
|
||||||
|
|
||||||
app.after_configuration do
|
app.after_build do |builder|
|
||||||
# Register a reroute transform that adds .gz to asset paths
|
Find.find(self.class.inst.build_dir) do |path|
|
||||||
sitemap.reroute do |destination, page|
|
next if File.directory? path
|
||||||
if exts.include? page.ext
|
if exts.include? File.extname(path)
|
||||||
destination + '.gz'
|
new_size = gzip_file(path, builder)
|
||||||
else
|
|
||||||
destination
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
use GzipRack, :exts => exts
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :included :registered
|
alias :included :registered
|
||||||
end
|
end
|
||||||
|
|
||||||
# Rack middleware to GZip asset files
|
module InstanceMethods
|
||||||
class GzipRack
|
def gzip_file(path, builder)
|
||||||
|
input_file = File.open(path, 'r').read
|
||||||
# Init
|
output_filename = path + '.gz'
|
||||||
# @param [Class] app
|
File.open(output_filename, 'w') do |f|
|
||||||
# @param [Hash] options
|
gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
|
||||||
def initialize(app, options={})
|
gz.write input_file
|
||||||
@app = app
|
gz.close
|
||||||
@exts = options[:exts]
|
|
||||||
@exts_regex = @exts.map {|e| Regexp.escape(e) }.join('|')
|
|
||||||
end
|
|
||||||
|
|
||||||
# Rack interface
|
|
||||||
# @param [Rack::Environmemt] env
|
|
||||||
# @return [Array]
|
|
||||||
def call(env)
|
|
||||||
status, headers, response = @app.call(env)
|
|
||||||
|
|
||||||
if env["PATH_INFO"].match(/(#{@exts_regex}).gz$/)
|
|
||||||
contents = case(response)
|
|
||||||
when String
|
|
||||||
response
|
|
||||||
when Array
|
|
||||||
response.join
|
|
||||||
when Rack::Response
|
|
||||||
response.body.join
|
|
||||||
when Rack::File
|
|
||||||
File.read(response.path)
|
|
||||||
end
|
|
||||||
|
|
||||||
gzipped = ""
|
|
||||||
StringIO.open(gzipped) do |s|
|
|
||||||
gz = Zlib::GzipWriter.new(s, Zlib::BEST_COMPRESSION)
|
|
||||||
gz.write contents
|
|
||||||
gz.close
|
|
||||||
end
|
|
||||||
|
|
||||||
headers["Content-Length"] = ::Rack::Utils.bytesize(gzipped).to_s
|
|
||||||
response = [gzipped]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
[status, headers, response]
|
old_size = File.size(path)
|
||||||
|
new_size = File.size(output_filename)
|
||||||
|
|
||||||
|
builder.say_status :gzip, "#{output_filename} (#{old_size - new_size} bytes smaller)"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue