From 6fdc6676d1f70678e65076b34cf0563f2864c620 Mon Sep 17 00:00:00 2001 From: Michael Misshore Date: Thu, 1 Oct 2015 20:38:06 -0500 Subject: [PATCH 1/5] Move configurations into their own class, read from a YAML file --- .rubocop_todo.yml | 4 ++-- lib/critical_path_css/configuration.rb | 23 +++++++++++++++++++++++ lib/critical_path_css_rails.rb | 10 ++++++---- lib/tasks/critical_path_css.rake | 9 ++------- 4 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 lib/critical_path_css/configuration.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 136289d..3911bed 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2015-09-19 12:37:55 -0500 using RuboCop version 0.34.1. +# on 2015-10-01 20:43:37 -0500 using RuboCop version 0.34.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -9,4 +9,4 @@ # Offense count: 2 # Configuration parameters: AllowURI, URISchemes. Metrics/LineLength: - Max: 91 \ No newline at end of file + Max: 90 diff --git a/lib/critical_path_css/configuration.rb b/lib/critical_path_css/configuration.rb new file mode 100644 index 0000000..e13829e --- /dev/null +++ b/lib/critical_path_css/configuration.rb @@ -0,0 +1,23 @@ +module CriticalPathCss + class Configuration + CONFIGURATION_FILENAME = 'critical_path_css.yml' + + def initialize + @configurations = YAML.load_file(configuration_file_path)[Rails.env] + end + + def routes + @routes ||= @configurations['routes'] + end + + def base_url + @base_url ||= @configurations['base_url'] + end + + private + + def configuration_file_path + Rails.root.join('config', CONFIGURATION_FILENAME) + end + end +end diff --git a/lib/critical_path_css_rails.rb b/lib/critical_path_css_rails.rb index 592c0dc..71b2d6d 100644 --- a/lib/critical_path_css_rails.rb +++ b/lib/critical_path_css_rails.rb @@ -2,13 +2,15 @@ module CriticalPathCss require 'phantomjs' CACHE_NAMESPACE = 'critical-path-css' - PENTHOUSE_PATH = "#{File.dirname(__FILE__)}/penthouse/penthouse.js" + PENTHOUSE_PATH = "#{File.dirname(__FILE__)}/penthouse/penthouse.js" - def self.generate(main_css_path, base_url, routes) + def self.generate(main_css_path) full_main_css_path = "#{Rails.root}/public#{main_css_path}" + config = CriticalPathCss::Configuration.new(Rails.root, Rails.env) + + config.routes.each do |route| + css = Phantomjs.run(PENTHOUSE_PATH, config.base_url + route, full_main_css_path) - routes.each do |route| - css = Phantomjs.run(PENTHOUSE_PATH, base_url + route, full_main_css_path) Rails.cache.write(route, css, namespace: CACHE_NAMESPACE) end end diff --git a/lib/tasks/critical_path_css.rake b/lib/tasks/critical_path_css.rake index 9b5c1ab..06042e8 100644 --- a/lib/tasks/critical_path_css.rake +++ b/lib/tasks/critical_path_css.rake @@ -1,15 +1,10 @@ require 'critical_path_css_rails' namespace :critical_path_css do - @base_url = Rails.env.production? ? 'http://example.com' : 'http://localhost:3000' - @routes = %w( - / - ) - desc 'Generate critical CSS for the routes defined' task generate: :environment do - @main_css_path = ActionController::Base.helpers.stylesheet_path('application.css').to_s + main_css_path = ActionController::Base.helpers.stylesheet_path('application.css').to_s - CriticalPathCss.generate(@main_css_path, @base_url, @routes) + CriticalPathCss.generate(main_css_path) end end From ab0a3e396e52e591e56f8d63a6cdea3e159bc328 Mon Sep 17 00:00:00 2001 From: Michael Misshore Date: Thu, 1 Oct 2015 20:42:38 -0500 Subject: [PATCH 2/5] Generate configuration yaml file through the install generator --- lib/config/critical_path_css.yml | 15 +++++++++++++++ .../critical_path_css/install_generator.rb | 6 ++++++ 2 files changed, 21 insertions(+) create mode 100644 lib/config/critical_path_css.yml diff --git a/lib/config/critical_path_css.yml b/lib/config/critical_path_css.yml new file mode 100644 index 0000000..798d14a --- /dev/null +++ b/lib/config/critical_path_css.yml @@ -0,0 +1,15 @@ +defaults: &defaults + routes: + - / + +development: + <<: *defaults + base_url: http://localhost:3000 + +staging: + <<: *defaults + base_url: http://staging.example.com + +production: + <<: *defaults + base_url: http://example.com diff --git a/lib/generators/critical_path_css/install_generator.rb b/lib/generators/critical_path_css/install_generator.rb index 7a24f3e..b7c221a 100644 --- a/lib/generators/critical_path_css/install_generator.rb +++ b/lib/generators/critical_path_css/install_generator.rb @@ -9,5 +9,11 @@ def copy_rake_task task_filename = 'critical_path_css.rake' copy_file "../../tasks/#{task_filename}", "lib/tasks/#{task_filename}" end + + # Copy the needed configuration YAML file for generating critical CSS + def copy_config_file + task_filename = 'critical_path_css.yml' + copy_file "../../config/#{task_filename}", "config/#{task_filename}" + end end end From d3a07c588357ea57c6de1001f8bbe1bdb552e64d Mon Sep 17 00:00:00 2001 From: Michael Misshore Date: Thu, 1 Oct 2015 20:55:57 -0500 Subject: [PATCH 3/5] Add CssFetcher --- .rubocop_todo.yml | 4 ++-- lib/critical_path_css/css_fetcher.rb | 23 +++++++++++++++++++++++ lib/critical_path_css_rails.rb | 12 +++--------- 3 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 lib/critical_path_css/css_fetcher.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 3911bed..ecd179c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,12 +1,12 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2015-10-01 20:43:37 -0500 using RuboCop version 0.34.1. +# on 2015-10-03 13:02:27 -0500 using RuboCop version 0.34.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 2 +# Offense count: 1 # Configuration parameters: AllowURI, URISchemes. Metrics/LineLength: Max: 90 diff --git a/lib/critical_path_css/css_fetcher.rb b/lib/critical_path_css/css_fetcher.rb new file mode 100644 index 0000000..881fb46 --- /dev/null +++ b/lib/critical_path_css/css_fetcher.rb @@ -0,0 +1,23 @@ +module CriticalPathCss + class CssFetcher + require 'phantomjs' + require 'critical_path_css/configuration' + + PENTHOUSE_PATH = "#{File.dirname(__FILE__)}/../penthouse/penthouse.js" + + def initialize(main_css_relative_path) + @main_css_path = "#{Rails.root}/public#{main_css_relative_path}" + @config = Configuration.new + end + + def fetch + @config.routes.map { |route| [route, css_for_route(route)] }.to_h + end + + private + + def css_for_route(route) + Phantomjs.run(PENTHOUSE_PATH, @config.base_url + route, @main_css_path) + end + end +end diff --git a/lib/critical_path_css_rails.rb b/lib/critical_path_css_rails.rb index 71b2d6d..a740ba3 100644 --- a/lib/critical_path_css_rails.rb +++ b/lib/critical_path_css_rails.rb @@ -1,16 +1,10 @@ module CriticalPathCss - require 'phantomjs' + require 'critical_path_css/css_fetcher' CACHE_NAMESPACE = 'critical-path-css' - PENTHOUSE_PATH = "#{File.dirname(__FILE__)}/penthouse/penthouse.js" - - def self.generate(main_css_path) - full_main_css_path = "#{Rails.root}/public#{main_css_path}" - config = CriticalPathCss::Configuration.new(Rails.root, Rails.env) - - config.routes.each do |route| - css = Phantomjs.run(PENTHOUSE_PATH, config.base_url + route, full_main_css_path) + def self.generate(main_css_relative_path) + CssFetcher.new(main_css_relative_path).fetch.each do |route, css| Rails.cache.write(route, css, namespace: CACHE_NAMESPACE) end end From 1ae333ae6c9aadbc0cdb6338a1cb046eab0f0805 Mon Sep 17 00:00:00 2001 From: Michael Misshore Date: Sat, 3 Oct 2015 13:34:54 -0500 Subject: [PATCH 4/5] Move CSS file path into the YAML config as well --- .rubocop_todo.yml | 6 +++--- lib/config/critical_path_css.yml | 4 ++++ lib/critical_path_css/configuration.rb | 25 ++++++++++++++++++++----- lib/critical_path_css/css_fetcher.rb | 5 ++--- lib/critical_path_css_rails.rb | 4 ++-- lib/tasks/critical_path_css.rake | 4 +--- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index ecd179c..00d139e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,12 +1,12 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2015-10-03 13:02:27 -0500 using RuboCop version 0.34.1. +# on 2015-10-03 13:56:01 -0500 using RuboCop version 0.34.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 1 +# Offense count: 2 # Configuration parameters: AllowURI, URISchemes. Metrics/LineLength: - Max: 90 + Max: 86 diff --git a/lib/config/critical_path_css.yml b/lib/config/critical_path_css.yml index 798d14a..e916570 100644 --- a/lib/config/critical_path_css.yml +++ b/lib/config/critical_path_css.yml @@ -1,4 +1,8 @@ defaults: &defaults + # If using the asset pipeline, provide the manifest name + manifest_name: application + # Else provide the relative path of your CSS file from the /public directory + # css_path: /path/to/css/from/public/main.css routes: - / diff --git a/lib/critical_path_css/configuration.rb b/lib/critical_path_css/configuration.rb index e13829e..4d6d7e0 100644 --- a/lib/critical_path_css/configuration.rb +++ b/lib/critical_path_css/configuration.rb @@ -6,18 +6,33 @@ def initialize @configurations = YAML.load_file(configuration_file_path)[Rails.env] end - def routes - @routes ||= @configurations['routes'] + def base_url + @configurations['base_url'] end - def base_url - @base_url ||= @configurations['base_url'] + def css_path + @css_path ||= begin + relative_path = @configurations['css_path'] || manifest_path + "#{Rails.root}/public#{relative_path}" + end + end + + def manifest_name + @configurations['manifest_name'] + end + + def routes + @configurations['routes'] end private def configuration_file_path - Rails.root.join('config', CONFIGURATION_FILENAME) + @configuration_file_path ||= Rails.root.join('config', CONFIGURATION_FILENAME) + end + + def manifest_path + @manifest_path ||= ActionController::Base.helpers.stylesheet_path(manifest_name) end end end diff --git a/lib/critical_path_css/css_fetcher.rb b/lib/critical_path_css/css_fetcher.rb index 881fb46..3397819 100644 --- a/lib/critical_path_css/css_fetcher.rb +++ b/lib/critical_path_css/css_fetcher.rb @@ -5,8 +5,7 @@ class CssFetcher PENTHOUSE_PATH = "#{File.dirname(__FILE__)}/../penthouse/penthouse.js" - def initialize(main_css_relative_path) - @main_css_path = "#{Rails.root}/public#{main_css_relative_path}" + def initialize @config = Configuration.new end @@ -17,7 +16,7 @@ def fetch private def css_for_route(route) - Phantomjs.run(PENTHOUSE_PATH, @config.base_url + route, @main_css_path) + Phantomjs.run(PENTHOUSE_PATH, @config.base_url + route, @config.css_path) end end end diff --git a/lib/critical_path_css_rails.rb b/lib/critical_path_css_rails.rb index a740ba3..4e8bbaf 100644 --- a/lib/critical_path_css_rails.rb +++ b/lib/critical_path_css_rails.rb @@ -3,8 +3,8 @@ module CriticalPathCss CACHE_NAMESPACE = 'critical-path-css' - def self.generate(main_css_relative_path) - CssFetcher.new(main_css_relative_path).fetch.each do |route, css| + def self.generate + CssFetcher.new.fetch.each do |route, css| Rails.cache.write(route, css, namespace: CACHE_NAMESPACE) end end diff --git a/lib/tasks/critical_path_css.rake b/lib/tasks/critical_path_css.rake index 06042e8..7f97a67 100644 --- a/lib/tasks/critical_path_css.rake +++ b/lib/tasks/critical_path_css.rake @@ -3,8 +3,6 @@ require 'critical_path_css_rails' namespace :critical_path_css do desc 'Generate critical CSS for the routes defined' task generate: :environment do - main_css_path = ActionController::Base.helpers.stylesheet_path('application.css').to_s - - CriticalPathCss.generate(main_css_path) + CriticalPathCss.generate end end From 3ff432803d298f81291059558707348acc569ba7 Mon Sep 17 00:00:00 2001 From: Michael Misshore Date: Sat, 3 Oct 2015 13:59:01 -0500 Subject: [PATCH 5/5] Increment version and update README --- README.md | 20 +++++++++++--------- lib/critical_path_css/rails/version.rb | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a61db37..b545707 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This gem uses [PhantomJS](https://github.com/colszowka/phantomjs-gem) and [Penth Add `critical-path-css-rails` to your Gemfile: ``` -gem 'critical-path-css-rails', '~> 0.1.0' +gem 'critical-path-css-rails', '~> 0.2.0' ``` Download and install by running: @@ -23,24 +23,26 @@ Download and install by running: bundle install ``` -Create the rake task that will generate your critical CSS +Run the generator to install the rake task and configuration file: ``` rails generator critical_path_css:install ``` -This adds the following file: +The generator adds the following files: +* `config/critical_path_css.yml` * `lib/tasks/critical_path_css.rake` ## Usage -First, you'll need to configue a few variables in the rake task: `lib/tasks/critical_path_css.rake` +First, you'll need to configue a few things in the YAML file: `config/critical_path_css.yml` -* `@base_url`: Change the url's here to match your Production and Development base URL, respectively. -* `@routes`: List the routes that you would like to generate the critical CSS for. (i.e. /resources, /resources/show/1, etc.) -* `@main_css_path`: Inside of the generate task, you'll need to define the path to the application's main CSS. The gem assumes your CSS lives in `RAILS_ROOT/public`. If your main CSS file is in `RAILS_ROOT/public/assets/main.css`, you would set the variable to `/assets/main.css`. +* `manifest_name`: If you're using the asset pipeline, add the manifest name. +* `css_path`: If you're not using the asset pipeline, you'll need to define the path to the application's main CSS. The gem assumes your CSS lives in `RAILS_ROOT/public`. If your main CSS file is in `RAILS_ROOT/public/assets/main.css`, you would set the variable to `/assets/main.css`. +* `routes`: List the routes that you would like to generate the critical CSS for. (i.e. /resources, /resources/show/1, etc.) +* `base_url`: Add your application's URL for the necessary environments. Before generating the CSS, ensure that your application is running (viewable from a browser) and the main CSS file exists. Then in a separate tab, run the rake task to generate the critical CSS. @@ -57,7 +59,7 @@ rake critical_path_css:generate To load the generated critical CSS into your layout, in the head tag, insert: -```html +```HTML+ERB @@ -65,7 +67,7 @@ To load the generated critical CSS into your layout, in the head tag, insert: A simple example using loadcss-rails looks like: -```html +```HTML+ERB diff --git a/lib/critical_path_css/rails/version.rb b/lib/critical_path_css/rails/version.rb index 26c3a83..0cf9675 100644 --- a/lib/critical_path_css/rails/version.rb +++ b/lib/critical_path_css/rails/version.rb @@ -1,6 +1,6 @@ module CriticalPathCSS module Rails - VERSION = '0.1.0' + VERSION = '0.2.0' PENTHOUSE_VERSION = '0.3.4' end end