diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 136289d..00d139e 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-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 @@ -9,4 +9,4 @@ # Offense count: 2 # Configuration parameters: AllowURI, URISchemes. Metrics/LineLength: - Max: 91 \ No newline at end of file + Max: 86 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/config/critical_path_css.yml b/lib/config/critical_path_css.yml new file mode 100644 index 0000000..e916570 --- /dev/null +++ b/lib/config/critical_path_css.yml @@ -0,0 +1,19 @@ +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: + - / + +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/critical_path_css/configuration.rb b/lib/critical_path_css/configuration.rb new file mode 100644 index 0000000..4d6d7e0 --- /dev/null +++ b/lib/critical_path_css/configuration.rb @@ -0,0 +1,38 @@ +module CriticalPathCss + class Configuration + CONFIGURATION_FILENAME = 'critical_path_css.yml' + + def initialize + @configurations = YAML.load_file(configuration_file_path)[Rails.env] + end + + def base_url + @configurations['base_url'] + end + + 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 + @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 new file mode 100644 index 0000000..3397819 --- /dev/null +++ b/lib/critical_path_css/css_fetcher.rb @@ -0,0 +1,22 @@ +module CriticalPathCss + class CssFetcher + require 'phantomjs' + require 'critical_path_css/configuration' + + PENTHOUSE_PATH = "#{File.dirname(__FILE__)}/../penthouse/penthouse.js" + + def initialize + @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, @config.css_path) + end + end +end 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 diff --git a/lib/critical_path_css_rails.rb b/lib/critical_path_css_rails.rb index 592c0dc..4e8bbaf 100644 --- a/lib/critical_path_css_rails.rb +++ b/lib/critical_path_css_rails.rb @@ -1,14 +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, base_url, routes) - full_main_css_path = "#{Rails.root}/public#{main_css_path}" - - routes.each do |route| - css = Phantomjs.run(PENTHOUSE_PATH, base_url + route, full_main_css_path) + def self.generate + CssFetcher.new.fetch.each do |route, css| Rails.cache.write(route, css, namespace: CACHE_NAMESPACE) end end 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 diff --git a/lib/tasks/critical_path_css.rake b/lib/tasks/critical_path_css.rake index 9b5c1ab..7f97a67 100644 --- a/lib/tasks/critical_path_css.rake +++ b/lib/tasks/critical_path_css.rake @@ -1,15 +1,8 @@ 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 - - CriticalPathCss.generate(@main_css_path, @base_url, @routes) + CriticalPathCss.generate end end