Skip to content

Commit

Permalink
Makes zippable extensions configurable in site config
Browse files Browse the repository at this point in the history
  • Loading branch information
philnash committed Nov 15, 2018
1 parent 964282f commit 8468d11
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 24 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,31 @@ In your destination directory (`_site` by default) you will find gzipped version

`Jekyll::Gzip` only runs when the environment variable `JEKYLL_ENV` is set to `production` as dealing with gzipping files is unnecessary in development mode and just slows down the site build.

### Configuration

By default, `Jekyll::Gzip` will compress all files with the following extensions:

- '.html'
- '.css'
- '.js'
- '.txt'
- '.ttf'
- '.atom'
- '.stl'
- '.xml'
- '.svg'
- '.eot'

You can supply your own extensions by adding a `gzip` key to your site's `_config.yml` listing the extensions that you want to compress. For example to only compress HTML, CSS and JavaScript files, add the following to `_config.yml`:

```yml
gzip:
extensions:
- '.html'
- '.css'
- '.js
```
### Serving pre-compiled gzip files
You will likely need to adjust your web server config to serve these precomputed gzip files. See below for common server configurations:
Expand Down
27 changes: 16 additions & 11 deletions lib/jekyll/gzip.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
# frozen_string_literal: true

require "jekyll/gzip/version"
require "jekyll/gzip/compressor"
require "pathname"
require 'jekyll/gzip/version'
require 'jekyll/gzip/config'
require 'jekyll/gzip/compressor'
require 'pathname'

module Jekyll
module Gzip
end
end

Jekyll::Hooks.register :site, :after_init do |site|
config = site.config['gzip'] || {}
site.config['gzip'] = Jekyll::Gzip::DEFAULT_CONFIG.merge(config) || []
puts site.config['gzip']
end

Jekyll::Hooks.register :site, :post_write do |site|
if Jekyll.env == "production"
Jekyll::Gzip::Compressor.compress_site(site)
end
Jekyll::Gzip::Compressor.compress_site(site) if Jekyll.env == 'production'
end

begin
require "jekyll-assets"
require 'jekyll-assets'

Jekyll::Assets::Hook.register :env, :after_write do |env|
if Jekyll.env == "production"
path = Pathname.new("#{env.jekyll.config["destination"]}#{env.prefix_url}")
Jekyll::Gzip::Compressor.compress_directory(path)
if Jekyll.env == 'production'
path = Pathname.new("#{env.jekyll.config['destination']}#{env.prefix_url}")
Jekyll::Gzip::Compressor.compress_directory(path, env.jekyll)
end
end
rescue LoadError
# The Jekyll site doesn't use Jekyll::Assets, so no need to compress those
# files.
end
end
26 changes: 17 additions & 9 deletions lib/jekyll/gzip/compressor.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require "zlib"
require 'jekyll/gzip/config'
require 'zlib'

module Jekyll
##
Expand All @@ -24,7 +25,7 @@ module Compressor
'.xml',
'.svg',
'.eot'
]
].freeze

##
# Takes an instance of +Jekyll::Site+ and maps over the site files and
Expand All @@ -39,7 +40,7 @@ module Compressor
# @return void
def self.compress_site(site)
site.each_site_file do |file|
compress_file(file.destination(site.dest))
compress_file(file.destination(site.dest), zippable_extensions(site))
end
end

Expand All @@ -54,9 +55,10 @@ def self.compress_site(site)
# compression.
#
# @return void
def self.compress_directory(dir)
files = Dir.glob(dir + "**/*{#{ZIPPABLE_EXTENSIONS.join(',')}}")
files.each { |file| compress_file(file) }
def self.compress_directory(dir, site)
extensions = zippable_extensions(site).join(',')
files = Dir.glob(dir + "**/*{#{extensions}")
files.each { |file| compress_file(file, extensions) }
end

##
Expand All @@ -69,15 +71,21 @@ def self.compress_directory(dir)
# @param file_name [String] The file name of the file we want to compress
#
# @return void
def self.compress_file(file_name)
return unless ZIPPABLE_EXTENSIONS.include?(File.extname(file_name))
def self.compress_file(file_name, extensions)
return unless extensions.include?(File.extname(file_name))
zipped = "#{file_name}.gz"
Zlib::GzipWriter.open(zipped, Zlib::BEST_COMPRESSION) do |gz|
gz.mtime = File.mtime(file_name)
gz.orig_name = file_name
gz.write IO.binread(file_name)
end
end

private

def self.zippable_extensions(site)
site.config['gzip'] && site.config['gzip']['extensions'] || Jekyll::Gzip::DEFAULT_CONFIG['extensions']
end
end
end
end
end
18 changes: 18 additions & 0 deletions lib/jekyll/gzip/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Jekyll
module Gzip
DEFAULT_CONFIG = {
'extensions' => [
'.html',
'.css',
'.js',
'.txt',
'.ttf',
'.atom',
'.stl',
'.xml',
'.svg',
'.eot'
]
}.freeze
end
end
15 changes: 11 additions & 4 deletions spec/jekyll/gzip/compressor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,26 @@

RSpec.describe Jekyll::Gzip::Compressor do
let(:site) { make_site }
let(:extensions) { site.config['gzip'] && site.config['gzip']['extensions'] }
before(:each) { site.process }
after(:each) { FileUtils.rm_r(dest_dir) }

describe "given a file name" do
it "creates a gzip file" do
file_name = dest_dir("index.html")
Jekyll::Gzip::Compressor.compress_file(file_name)
Jekyll::Gzip::Compressor.compress_file(file_name, ['.html'])
expect(File.exist?("#{file_name}.gz")).to be true
end

it "doesn't create a gzip file if the extension is not present" do
file_name = dest_dir("index.html")
Jekyll::Gzip::Compressor.compress_file(file_name, [])
expect(File.exist?("#{file_name}.gz")).to be false
end

it "compresses the content of the file in the gzip file" do
file_name = dest_dir("index.html")
Jekyll::Gzip::Compressor.compress_file(file_name)
Jekyll::Gzip::Compressor.compress_file(file_name, ['.html'])
content = File.read(file_name)
Zlib::GzipReader.open("#{file_name}.gz") {|gz|
expect(gz.read).to eq(content)
Expand All @@ -26,7 +33,7 @@

it "doesn't compress non text files" do
file_name = dest_dir("images/test.png")
Jekyll::Gzip::Compressor.compress_file(file_name)
Jekyll::Gzip::Compressor.compress_file(file_name, ['.html'])
expect(File.exist?("#{file_name}.gz")).to be false
end
end
Expand All @@ -49,7 +56,7 @@

describe "given a destination directory" do
it "compresses all the text files in the directory" do
Jekyll::Gzip::Compressor.compress_directory(dest_dir)
Jekyll::Gzip::Compressor.compress_directory(dest_dir, site)
files = [
dest_dir("index.html"),
dest_dir("css/main.css"),
Expand Down

0 comments on commit 8468d11

Please sign in to comment.