Skip to content
This repository has been archived by the owner on Jun 10, 2018. It is now read-only.

depend_on_asset not respected for template #534

Closed
schneems opened this issue Mar 4, 2014 · 13 comments
Closed

depend_on_asset not respected for template #534

schneems opened this issue Mar 4, 2014 · 13 comments

Comments

@schneems
Copy link
Contributor

schneems commented Mar 4, 2014

Rails 4.0.3, Ruby 2.1.1: when an asset using the //= depend_on_asset directive is depending on a template, it is not re-compiled when the template changes. Below is a run-able script assuming you've got Rails 4.0.3 installed:

# Rails 4.0.3, Ruby 2.1.1
# make new rails project
rails new sprockets_template_require
cd sprockets_template_require/
mkdir app/assets/templates/

# create template
echo "FOO" > app/assets/templates/index.html

# make application.js depend on template
echo "//= depend_on_asset index.html" > app/assets/javascripts/application.js

# precompile first time, all files are generated
RAILS_ENV=production bundle exec rake assets:precompile
I, [2014-03-04T15:28:03.091523 #48383]  INFO -- : Writing /Users/schneems/Documents/projects/tmp/sprockets_template_require/public/assets/application-d0b54dd563966c42aad5fd85b1c1f713.js
I, [2014-03-04T15:28:03.093347 #48383]  INFO -- : Writing /Users/schneems/Documents/projects/tmp/sprockets_template_require/public/assets/application-d0b54dd563966c42aad5fd85b1c1f713.css
I, [2014-03-04T15:28:03.094426 #48383]  INFO -- : Writing /Users/schneems/Documents/projects/tmp/sprockets_template_require/public/assets/index-07b84af3dfebd65cbcf63d12e8f87096.html

# change index.html, since "application.js" depends on it, we should expect it to be updated as well.
echo "bar" >> app/assets/templates/index.html

RAILS_ENV=production bundle exec rake assets:precompile
I, [2014-03-04T15:28:24.596258 #48391]  INFO -- : Writing /Users/schneems/Documents/projects/tmp/sprockets_template_require/public/assets/index-3afdb0fca64563b7cb91d7377e695a3d.html

# "application.js" was not re-compiled as we expected, if it is referencing "index.html", the reference is now pointing at an old copy

Is this expected behavior or a known issue? Why doesn't sprockets re-compile my application.js file?

@vgdub
Copy link

vgdub commented Mar 7, 2014

+1 - Running in to this exact issue...thanks @schneems for the detailed explanation.

@josh
Copy link
Contributor

josh commented Mar 10, 2014

Does depend_on work?

@schneems
Copy link
Contributor Author

It doesn't look like depend_on works. Here's the runable script: https://gist.github.com/schneems/9474721

Here's the output

2.1.1  /tmp/sprockets_template_require
$ rails new sprockets_template_require
# ...
Using turbolinks (2.2.1)
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

2.1.1  /tmp
$ cd sprockets_template_require/

2.1.1  /tmp/sprockets_template_require
$ mkdir app/assets/templates/

2.1.1  /tmp/sprockets_template_require
$ echo "FOO" > app/assets/templates/index.html

2.1.1  /tmp/sprockets_template_require
$ echo "//= depend_on index.html" > app/assets/javascripts/application.js

2.1.1  /tmp/sprockets_template_require
$ RAILS_ENV=production bundle exec rake assets:precompile
I, [2014-03-10T16:28:34.820437 #3469]  INFO -- : Writing /private/tmp/sprockets_template_require/public/assets/application-d0b54dd563966c42aad5fd85b1c1f713.js
I, [2014-03-10T16:28:34.847070 #3469]  INFO -- : Writing /private/tmp/sprockets_template_require/public/assets/application-d0b54dd563966c42aad5fd85b1c1f713.css
I, [2014-03-10T16:28:34.853424 #3469]  INFO -- : Writing /private/tmp/sprockets_template_require/public/assets/index-07b84af3dfebd65cbcf63d12e8f87096.html

2.1.1  /tmp/sprockets_template_require
$ echo "bar" >> app/assets/templates/index.html

2.1.1  /tmp/sprockets_template_require
$ RAILS_ENV=production bundle exec rake assets:precompile
I, [2014-03-10T16:28:42.362342 #3479]  INFO -- : Writing /private/tmp/sprockets_template_require/public/assets/index-3afdb0fca64563b7cb91d7377e695a3d.html

Notice that application.js still not re-compiled.

@josh
Copy link
Contributor

josh commented Mar 10, 2014

Well, I guess this trivial example won't work since the MD5 of evaluating application.js is still the same. Theres nothing to recompile.

@schneems
Copy link
Contributor Author

Isn't that the point of depend_on and family? application.js shouldn't need to change to force a re-compile if one of it's dependencies has changed (index.html).

It took me a few hours of playing with a customer's code to figure out this was the behavior of sprockets, then to repro with a script and open this issue.

Btw, doing the reverse works as expected (putting a depends_on_asset in index.html that references application.js will cause index.html to re-compile when you modify the javascript file). For some reason this case doesn't work.

@schneems
Copy link
Contributor Author

Any idea where this discrepancy in behavior might come from? I've spent more time poking through internals, but i'm going in circles. Any help would be appreciated. I'm willing to submit a patch if I could better understand why this is happening.

@schneems
Copy link
Contributor Author

7 day ping. Any ideas?

@eprothro
Copy link

@josh regarding your last comment -- In my mind, if we wait on the dependent file to change, then we wouldn't need to specify the dependency explicitly in the first place, as the new digest would be used when the dependent file is re-compiled. Are we missing something here about the intended use case for depend_on_asset?

@schneems were you able to get depend_on_asset working at all? In my application I'm not experiencing the documented behavior even when calling out a dependency on an asset in the pipeline (e.g. not only when referencing a template, as in your example).

Confirmed below with your script modified for this use case:

# Rails 4.0.4, Ruby 2.1.1
# make new rails project
rails new sprockets_image_require
cd sprockets_image_require/
mkdir app/assets/images/

# create template
echo "FOO" > app/assets/images/foo.svg

# make application.css depend on image
mv app/assets/stylesheets/application.css app/assets/stylesheets/application.sass
echo "//= depend_on_asset foo.svg" > app/assets/stylesheets/application.sass

# precompile first time, all files are generated
RAILS_ENV=production bundle exec rake assets:precompile
#I, [2014-03-24T13:31:18.240160 #64685]  INFO -- : Writing /Users/eprothro/source/temp/sprockets_image_require/public/assets/foo-05dcdce71bd3ff57640d8e3d5fb58c22.svg
#I, [2014-03-24T13:31:18.246813 #64685]  INFO -- : Writing /Users/eprothro/source/temp/sprockets_image_require/public/assets/application-acddda69fde179c1dd269d4254e6d096.js
#I, [2014-03-24T13:31:18.260609 #64685]  INFO -- : Writing /Users/eprothro/source/temp/sprockets_image_require/public/assets/application-81623e5871883113819cfff5b4817514.css

# change foo.svg, since "application.css" depends on it, we should expect it to be updated as well.
echo "bar" >> app/assets/images/foo.svg

RAILS_ENV=production bundle exec rake assets:precompile
I, [2014-03-24T13:31:50.075049 #64727]  INFO -- : Writing /Users/eprothro/source/temp/sprockets_image_require/public/assets/foo-16f96ea0433dec3fc2b7586d0977b1b8.svg

# though 'foo.svg' was re-compiled, "application.css" was not re-compiled as we expected, so it points at an out of date version of the asset

@schneems
Copy link
Contributor Author

@eprothro i've not gotten it to work with any directive depend_on_asset or otherwise. You are correct it is only a problem with app/assets/templates/* files. It works as expected for all other files as you've shown. Hence why i'm having trouble finding the source of the undesired behavior. Thanks for taking a look at the issue.

@eprothro
Copy link

@schneems I think my boolean logic above miscommunicated. I'm not seeing depend_on_asset work, even for a app/assets/images/* file. In my script, I would have expected foo.svg and application.css to both have been recompiled in the last step.

That's why I mentioned you, it seemed, based on the behavior I'm seeing that the templates/* behavior you were chasing down might be a red herring and that the failure is more widespread.

In my application I'm not experiencing the documented behavior even when calling out a dependency on an asset in the pipeline (e.g. not only when referencing a template, as in your example).

Then again, it is a Monday, so I may be off base, here.

@schneems
Copy link
Contributor Author

@eprothro it looks like depend_on_asset is not a subset of depend_on. In this case you need them both. Here's my script:

cd /tmp
rm -rf sprockets_image_require
rails new sprockets_image_require
cd sprockets_image_require/


echo "FOO" > app/assets/images/foo.svg

mv app/assets/stylesheets/application.css app/assets/stylesheets/application.css.erb
echo "//= depend_on_asset foo.svg" > app/assets/stylesheets/application.css.erb
echo "//= depend_on foo.svg" >> app/assets/stylesheets/application.css.erb

echo "body { background-image: url(<%= asset_path 'foo.svg' %>) } " >> app/assets/stylesheets/application.css.erb

RAILS_ENV=production bundle exec rake assets:precompile

echo "bar" >> app/assets/images/foo.svg

RAILS_ENV=production bundle exec rake assets:precompile

At the end I get:

$ RAILS_ENV=production bundle exec rake assets:precompile
I, [2014-04-29T15:02:33.458223 #23660]  INFO -- : Writing /private/tmp/sprockets_image_require/public/assets/foo-f1efb8110be6c85de46312b436571e0f.svg
I, [2014-04-29T15:02:35.525711 #23660]  INFO -- : Writing /private/tmp/sprockets_image_require/public/assets/application-59ffd4525232837e51088483ed301f44.js
I, [2014-04-29T15:02:35.546409 #23660]  INFO -- : Writing /private/tmp/sprockets_image_require/public/assets/application-eb80508cc4e2c75fb6168a8e387dc961.css

2.1.1  /tmp/sprockets_image_require
$ echo "bar" >> app/assets/images/foo.svg

2.1.1  /tmp/sprockets_image_require
$ RAILS_ENV=production bundle exec rake assets:precompile
I, [2014-04-29T15:02:47.050295 #23680]  INFO -- : Writing /private/tmp/sprockets_image_require/public/assets/foo-f4f6f6948aa02ca9ec980a54f358ea67.svg
I, [2014-04-29T15:02:47.062482 #23680]  INFO -- : Writing /private/tmp/sprockets_image_require/public/assets/application-e4e487f540bd68a479971308dec78870.css

Can you sanity check me here?

@schneems
Copy link
Contributor Author

I'm declaring this due to #557 and closing the issue.

@eprothro
Copy link

@schneems sorry for the much delayed sanity check.

Not sure about sanity at this point, to be honest.

I followed your newest script and saw the same behavior that you did. However, it strikes me that the example has changed and is now masking what we're trying to exercise.

echo "body { background-image: url(<%= asset_path 'foo.svg' %>) } " >> app/assets/stylesheets/application.css.erb

Using that asset_path helper will cause the stylesheet to be recompiled when foo.svg changes (confirm by making the stylesheet contain only that css, change foo.svg, and precompile). So the calls to depend_on and depend_on_asset in that example don't play the role we might be thinking they are.

So, in my estimation, the issue is still open, as the following (admittedly contrived) example doesn't behave as I would expect.

cd /tmp
rm -rf sprockets_image_require
rails new sprockets_image_require
cd sprockets_image_require/

echo "FOO" > app/assets/images/foo.svg

mv app/assets/stylesheets/application.css app/assets/stylesheets/application.css.erb
echo "//= depend_on_asset foo.svg" > app/assets/stylesheets/application.css.erb
echo "//= depend_on foo.svg" >> app/assets/stylesheets/application.css.erb

echo "body { background-color: #fff } " >> app/assets/stylesheets/application.css.erb

RAILS_ENV=production bundle exec rake assets:precompile

echo "bar" >> app/assets/images/foo.svg

RAILS_ENV=production bundle exec rake assets:precompile

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants