sprockets-rails
sprockets-rails copied to clipboard
gem including a file named `application.js` in a subfolder messes up everything
I think this may be a re-file of the previously closed issue #218, I'm refiling it which I hope this story will be prove justified.
I spent a couple hours hunting this down before discovering the closed #218. Still not sure exactly what's going on, but, with Rails 5.0.0, sprockets 3.7.0, sprockets-rails 3.1.1:
- the rails-assets bower-converted gem rails-assets-jquery-sortable happens to include a file at
app/assets/javascripts/jquery-sortable/application.js
- This isn't actually a useful file, I think it's maybe part of the source code for the jquery-sortable 'demo' page on the web, it's sort of been included in the converted-to-gem source 'accidentally', because of the bower source I guess -- but it shouldn't cause a problem to be there even though it's not needed.
- I would expect that in order to actually include this file in the sprockets pipeline, I'd have to
require 'jquery-sortable/application'
, since it is properly subfolder-namespaced. I would also expect that merely including the gem (without any requires in any manifest) should do nothing to my pipeline. - In fact, it seems that merely by including this gem, in development
javascript_tag 'application'
seems to resolve to (and trigger the sprockets compilation of?) this file, rails-assets-jquery-sortable'sapp/assets/javascripts/jquery-sortable/application.js
, instead of my own local appapplication.js
. - I don't entirely understand why. Even if the gem included it's own
app/assets/javascripts/application.js
(not namespace-subfoldered), I'd expect my own application'sapplication.js
to take priority because it's earlier in the load path. And since the gem source file is in fact at the subfolder-namespacedjquery-sortable/application.js
, I wouldn't expect it to be a problem at all at all. - I think #218 is reporting the same problem. There, the reporter @scashin133 suggests that the problem is "The default precompile logic https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb#L69 causes all application css and js files to be precompiled which was not the desired effect for this library." (that URL to line 69 no longer points to a relevant line in current master, not sure what SHA/version the reporter was looking at when it did).
- In #218, @josh, who was apparently maintaining at the time (and maybe still?) said that he agreed it was a bug, when he tried to fix it he discovered some people were depending on the buggy behavior, so he wasn't going to fix it, "But I'm planning to have it locked down in the next major release 3.x which can have backwards incompatible changes"
- I am still running into something that looks like this bug, so I'm thinking it did not in fact end up getting fixed in sprockets-rails 3.0+.
- I think this is a terrible bug. It makes it impossible not only to use
rails-assets-jquery-sortable
, but also to use any gem that depends on it -- most of which are probably rails-asset bower-converted ones, sure, so that is it's impossible to use any bower-converted-to-gem package that depends on jquery-sortable. But also in general, it means any gem that includes anapplication.js
orapplication.[s]css
, even properly namespaced in a subfolder, breaks sprockets. It makes sprockets an unpredictable monster. - Even without a major version with backwards-breaking-changes, I think this is a bug, which needs to be fixed. If there is a worry about some people depending on the broken behavior, perhaps there can be a feature-flag that switches between correct or buggy behavior. Personally I think the default should be correct behavior, but even if I had to opt-in to correct behavior at least that would give me a way to use rails-assets gems that depend on jquery-sortable. As it is, any such gem can not be used via rails-assets, it will break sprockets.
It seems like @josh maybe had a solution before, but chose not to apply it. @josh if you're still around and wanted to share it, it would probably be a useful starting point for anyone who does want to actually fix it -- or even monkey-patch it into Sprockets locally to workaround the bug preventing the use of any rails-assets gem that depends on jquery-sortable (or any other hypothetical gem with an application.js
or application.css
.
Sorry this got lengthy, it's confusing and I wanted to lay it all out, thanks so much to anyone who reads this.
@jrochkind https://github.com/rails/sprockets-rails/blob/27c644140b0f14737c6dfb9f5e0cfba71599b21e/lib/sprockets/railtie.rb#L69 is what I was linking to originally. I believe now the offending line would be https://github.com/rails/sprockets-rails/blob/e135984ee2b07e1a67c3fa57f799f40b0830e99a/lib/sprockets/railtie.rb#L108 but am not totally sure.
I've run into a variation of this with webpacker. Running rails assets:precompile
in Rails 6.0.0.beta1 generates packs for several example JS files from node_modules
:
-
webpacker/lib/install/examples/stimulus/application.js
-
webpacker/lib/install/javascript/packs/application.js
-
webpacker/test/test_app/app/javascript/packs/application.js
Steps to reproduce:
- create a new Rails 6.0.0.beta1 app
- run
rails assets:precompile
- alternatively, run
rails console
and check the value ofRails.application.precompiled_assets
My current workaround is to add the following to config/initializers/assets.rb
:
Rails.application.config.after_initialize do
Rails.application.config.assets.precompile.reject! {|asset| asset.is_a?(Regexp)}
end