Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails 3.1 asset pipeline: ignore assets from a gem

I'm not quite sure what the actual behavior is, so my first question is:
Are assets (e.g. javascripts) from a gem (in my case Spree) always compiled? I don't use Spree's javascripts, and therefore don't want them to be compiled. I don't require them in my application.js or any other javascript file, but

rake assets:precompile

compiles them nonetheless. I just don't want them lying around in my public/assets folder.

So I guess my question is, is there a way to disable compiling javascripts from a gem?

like image 654
Marian Theisen Avatar asked Aug 23 '11 15:08

Marian Theisen


People also ask

How do you Precompile an asset?

To compile your assets locally, run the assets:precompile task locally on your app. Make sure to use the production environment so that the production version of your assets are generated. A public/assets directory will be created. Inside this directory you'll find a manifest.

How does Rails asset pipeline work?

The asset pipeline provides a framework to concatenate and minify or compress JavaScript and CSS assets. It also adds the ability to write these assets in other languages such as CoffeeScript, Sass and ERB. Prior to Rails 3.1 these features were added through third-party Ruby libraries such as Jammit and Sprockets.

What does rake assets Precompile do?

rake assets:precompile. We use rake assets:precompile to precompile our assets before pushing code to production. This command precompiles assets and places them under the public/assets directory in our Rails application. Let's begin our journey by looking at the internals of the Rails Asset Pipeline.


2 Answers

Rails 4.X

It didn't work on Rails 4.X, a possible (dirty) workaround is:

require 'sprockets/railtie'

Bundler.require(:default, Rails.env)

module Sprockets
  module Paths
    SKIP_GEMS = ["rails-assets-jquery", "rails-assets-bootstrap"]

    def append_path_with_rails_assets(path)
      append_path_without_rails_assets(path) unless SKIP_GEMS.any? { |gem| path.to_s.start_with?(Gem.loaded_specs[gem].full_gem_path) }
    end

    alias_method_chain :append_path, :rails_assets
  end
end

Update for Rails 5.X

alias_method_chain is deprecated since Rails 5.X. Here is an updated version using prepend, and overriding the Sprockets::Environment module instead of Sprockets::Paths.

module SprocketsPathsOverride
  SKIP_GEMS = ["rails-assets-jquery", "rails-assets-bootstrap"]

  def append_path(path)
    should_skip = SKIP_GEMS.any? do |gem|
      path.to_s.start_with?(Gem.loaded_specs[gem].full_gem_path)
    end
    super(path) unless should_skip
  end
end

Sprockets::Environment.prepend(SprocketsPathsOverride)
like image 196
knoopx Avatar answered Sep 22 '22 13:09

knoopx


I guess there is a smart way to achieve your goal using sprockets. Maybe some require_directory instead of require_tree.

But the most direct thing would be to remove theses assets from your assets paths. To achieve this, add this at the very end of your application.rb file (doesn't work in an initializer):

class Engine < Rails::Engine
   initializer "remove assets directories from pipeline" do |app|
     app.config.assets.paths = app.config.assets.paths - app.config.assets.paths.grep(/nice_regexp_here_to_match_the_dir_where_the_unwanted_files_live/)
   end
end

Just tried a hack: put the code in an initializer but require it at the end of your application.rb:

require "config/initializers/your_file'

I prefer very specific code to be visible this way.

like image 27
apneadiving Avatar answered Sep 23 '22 13:09

apneadiving