assets:precompile task does not detect index files #3993

Closed
rwz opened this Issue Dec 15, 2011 · 30 comments

Comments

Projects
None yet
@rwz
Contributor

rwz commented Dec 15, 2011

I'm using rails 3.1.3 and having assets packed like this:

app/assets/javascripts/my_cool_stuff/
  index.js
  file1.js.coffee
  file2.js.coffee
  ...

The index.js file contains sprockets require_tree . call.

So in development i can type javascript_include_tag 'my_cool_stuff' and it will actually include my_cool_stuff/index.js and all files from my_cool_stuff folder.

However in production it doesn't work. If you add my_cool_stuff.js to config.assets.precompile and run assets:precompile rake-task it will not compile cause rails will look for the the actual file my_cool_stuff.js and not my_cool_stuff/index.js.

I think this is pretty misleading that you can include folders with index files in development but can not get them compiled for production.

@pokonski

This comment has been minimized.

Show comment
Hide comment
@pokonski

pokonski Dec 16, 2011

Contributor

Maybe you should try doing something like that in production.rb:

config.assets.precompile += ['index.js']
Contributor

pokonski commented Dec 16, 2011

Maybe you should try doing something like that in production.rb:

config.assets.precompile += ['index.js']
@rwz

This comment has been minimized.

Show comment
Hide comment
@rwz

rwz Dec 17, 2011

Contributor

Yeah, right now the only workaround is to use javascript_include_tag 'my_cool_stuff/index' in views and add my_cool_stuff/index.js into config.assets.precompile.

Still, this is confusing that you can include folders in development and can not get this working in production.

Contributor

rwz commented Dec 17, 2011

Yeah, right now the only workaround is to use javascript_include_tag 'my_cool_stuff/index' in views and add my_cool_stuff/index.js into config.assets.precompile.

Still, this is confusing that you can include folders in development and can not get this working in production.

@pokonski

This comment has been minimized.

Show comment
Hide comment
@pokonski

pokonski Dec 17, 2011

Contributor

I'll try to debug that, anyway where did you find info about the ability to provide directory, instead of a file in javascript_include_tag? Maybe it's an undocumented and unsupported feature?

Contributor

pokonski commented Dec 17, 2011

I'll try to debug that, anyway where did you find info about the ability to provide directory, instead of a file in javascript_include_tag? Maybe it's an undocumented and unsupported feature?

@homakov

This comment has been minimized.

Show comment
Hide comment
@homakov

homakov Feb 28, 2012

Contributor

Really, it doesn't seem like supported feature. Rails isn't intended to include your index.js when you include directory that contains index.js. IMO that is not an issue

Contributor

homakov commented Feb 28, 2012

Really, it doesn't seem like supported feature. Rails isn't intended to include your index.js when you include directory that contains index.js. IMO that is not an issue

@rwz

This comment has been minimized.

Show comment
Hide comment
@rwz

rwz Feb 28, 2012

Contributor

Well, it's default sprockets behavior and it also works in views in dev env.

Contributor

rwz commented Feb 28, 2012

Well, it's default sprockets behavior and it also works in views in dev env.

@homakov

This comment has been minimized.

Show comment
Hide comment
@homakov

homakov Feb 28, 2012

Contributor

please provide some more info. what seems to be a wrong behavior in here?

the thing is - when you precompile assets in dev mode it works per request - javascript_include_tag 'my_cool_stuff' makes browser to request my_cool_stuff/index.js what is followed by compilation the whole tree ( require_tree . the bad practise btw)

but in production sprockets are "off". you request files relying solely on public/assets folder, that is precompiled by rake task using standard 'application.js'

the only way to fix the issue mentioned above. Or you could patch sprockets making them to include **/index.js but why

Contributor

homakov commented Feb 28, 2012

please provide some more info. what seems to be a wrong behavior in here?

the thing is - when you precompile assets in dev mode it works per request - javascript_include_tag 'my_cool_stuff' makes browser to request my_cool_stuff/index.js what is followed by compilation the whole tree ( require_tree . the bad practise btw)

but in production sprockets are "off". you request files relying solely on public/assets folder, that is precompiled by rake task using standard 'application.js'

the only way to fix the issue mentioned above. Or you could patch sprockets making them to include **/index.js but why

@rwz

This comment has been minimized.

Show comment
Hide comment
@rwz

rwz Feb 28, 2012

Contributor

Right behavior for me would be applying sprockets to each config.assets.precompile file during running assets:precompile task. So including 'my_cool_stuff.js' into it will actually produce my_cool_stuff.js compile asset from folder.

In other words, provide the same logic, javascript_include_file uses.

This way it will match the development mode behavior and slightly reduce WAT-factor.

Contributor

rwz commented Feb 28, 2012

Right behavior for me would be applying sprockets to each config.assets.precompile file during running assets:precompile task. So including 'my_cool_stuff.js' into it will actually produce my_cool_stuff.js compile asset from folder.

In other words, provide the same logic, javascript_include_file uses.

This way it will match the development mode behavior and slightly reduce WAT-factor.

@rwz

This comment has been minimized.

Show comment
Hide comment
@rwz

rwz Feb 28, 2012

Contributor

On more time. I think this is wrong, when some code works cool in development, and doesn't work at all in production, because helpers use different logic in these two modes.

Contributor

rwz commented Feb 28, 2012

On more time. I think this is wrong, when some code works cool in development, and doesn't work at all in production, because helpers use different logic in these two modes.

@homakov

This comment has been minimized.

Show comment
Hide comment
@homakov

homakov Feb 29, 2012

Contributor

wait. you substitute proper behavior of sprockets with specififc behavior for javascript_include_file. When you call j_i_f it searches for proper file and founds coolstaff/index.js for you. That has nothing to do with sprockets.
That is why when you add coolstaff folder in assets.precompile array it doesn't add 'index.js' - it is different software and not supposed to work this way.

Contributor

homakov commented Feb 29, 2012

wait. you substitute proper behavior of sprockets with specififc behavior for javascript_include_file. When you call j_i_f it searches for proper file and founds coolstaff/index.js for you. That has nothing to do with sprockets.
That is why when you add coolstaff folder in assets.precompile array it doesn't add 'index.js' - it is different software and not supposed to work this way.

@homakov

This comment has been minimized.

Show comment
Hide comment
@homakov

homakov Feb 29, 2012

Contributor

really, I still didn't try it on my part so just if able to - prodive output of j_i_f 'yourfolder' in both prod and dev and what the error happens? is it 'index.js insnt preompiled'?

Contributor

homakov commented Feb 29, 2012

really, I still didn't try it on my part so just if able to - prodive output of j_i_f 'yourfolder' in both prod and dev and what the error happens? is it 'index.js insnt preompiled'?

@rwz

This comment has been minimized.

Show comment
Hide comment
@rwz

rwz Feb 29, 2012

Contributor

No, when i call javascript_include_tag 'my_cool_stuff' it uses sprockets and include my_cool_stuff/index.js and all requirements from it. But when i add my_cool_stuff.js to config.assets.precompile, it uses different logic and ends up doing nothing.

I think it should behave the same way. And use the same search/include logic. It would be sane and lead to better assets-pipeline usability.

Contributor

rwz commented Feb 29, 2012

No, when i call javascript_include_tag 'my_cool_stuff' it uses sprockets and include my_cool_stuff/index.js and all requirements from it. But when i add my_cool_stuff.js to config.assets.precompile, it uses different logic and ends up doing nothing.

I think it should behave the same way. And use the same search/include logic. It would be sane and lead to better assets-pipeline usability.

@homakov

This comment has been minimized.

Show comment
Hide comment
@homakov

homakov Feb 29, 2012

Contributor

when i call javascript_include_tag 'my_cool_stuff' it uses sprockets

I would argue with that statement. j_i_t doesnt compile anything for you. j_i_t !== sprockets method, ok?

Contributor

homakov commented Feb 29, 2012

when i call javascript_include_tag 'my_cool_stuff' it uses sprockets

I would argue with that statement. j_i_t doesnt compile anything for you. j_i_t !== sprockets method, ok?

@rwz

This comment has been minimized.

Show comment
Hide comment
@rwz

rwz Feb 29, 2012

Contributor

Who said anything about compiling? I know how jit works, ok?

Contributor

rwz commented Feb 29, 2012

Who said anything about compiling? I know how jit works, ok?

@rwz

This comment has been minimized.

Show comment
Hide comment
@rwz

rwz Feb 29, 2012

Contributor

https://github.com/rwz/asset_showcase

Here is the demo repo that illustrates the dev/prod inconsistency. It works in development, but fails in production.

Contributor

rwz commented Feb 29, 2012

https://github.com/rwz/asset_showcase

Here is the demo repo that illustrates the dev/prod inconsistency. It works in development, but fails in production.

@homakov

This comment has been minimized.

Show comment
Hide comment
@homakov

homakov Feb 29, 2012

Contributor

nice showcase.

config.assets.precompile += [ 'stuff.js' ]

is there such file 'stuff.js'? I didn't find one in root. but you specify sprockets to compile it

Contributor

homakov commented Feb 29, 2012

nice showcase.

config.assets.precompile += [ 'stuff.js' ]

is there such file 'stuff.js'? I didn't find one in root. but you specify sprockets to compile it

@rwz

This comment has been minimized.

Show comment
Hide comment
@rwz

rwz Feb 29, 2012

Contributor

There is obviously no such file. But the right behavior in that case would be to perform sprockets require, like j_i_t does in development, find stuff folder with index.js inside it, and compile stuff.js from it. So in production javascript_include_tag 'stuff' would actually include this compiled file, and not raise ActionView::Template::Error (stuff.js isn't precompiled)

Contributor

rwz commented Feb 29, 2012

There is obviously no such file. But the right behavior in that case would be to perform sprockets require, like j_i_t does in development, find stuff folder with index.js inside it, and compile stuff.js from it. So in production javascript_include_tag 'stuff' would actually include this compiled file, and not raise ActionView::Template::Error (stuff.js isn't precompiled)

@homakov

This comment has been minimized.

Show comment
Hide comment
@homakov

homakov Feb 29, 2012

Contributor

it doesnt seem like right behavior to me. too much of magic, assets.precompile is plain and straight array of files or masks so writing stuff.js you mean file "stuff.js" and nothing more. i try again:

  1. you call
    <%= javascript_include_tag 'stuff.js' %>
  2. it prints requiring your stuff/index.js, nice
  3. you try to precompile your folder using +='staff.js' but it fails. You expect it walk tree like j_i_t, dont u? Why, it is different method and algorythm
Contributor

homakov commented Feb 29, 2012

it doesnt seem like right behavior to me. too much of magic, assets.precompile is plain and straight array of files or masks so writing stuff.js you mean file "stuff.js" and nothing more. i try again:

  1. you call
    <%= javascript_include_tag 'stuff.js' %>
  2. it prints requiring your stuff/index.js, nice
  3. you try to precompile your folder using +='staff.js' but it fails. You expect it walk tree like j_i_t, dont u? Why, it is different method and algorythm
@rwz

This comment has been minimized.

Show comment
Hide comment
@rwz

rwz Feb 29, 2012

Contributor

Damn, i'm really tired of this shit already.

I type javascript_include_tag 'stuff' in development and it does what i want. I type the same fucking thing in production and get an not precompiled exception. And i have no way to compile it without changing the code.

I want rails either disable indexes discovery in j_i_t/s_l_t helpers in development, or provide a way to compile folders with indexes with rake assets:precompile, so fucking development and production environments behaves the same way.

Cause it's the way it should behave.

Contributor

rwz commented Feb 29, 2012

Damn, i'm really tired of this shit already.

I type javascript_include_tag 'stuff' in development and it does what i want. I type the same fucking thing in production and get an not precompiled exception. And i have no way to compile it without changing the code.

I want rails either disable indexes discovery in j_i_t/s_l_t helpers in development, or provide a way to compile folders with indexes with rake assets:precompile, so fucking development and production environments behaves the same way.

Cause it's the way it should behave.

@homakov

This comment has been minimized.

Show comment
Hide comment
@homakov

homakov Feb 29, 2012

Contributor

dude, chill out.do you have an idea what is the difference between dev and prod model in context of sprockets? i am sure you do.
у меня уже кончились слова ) когда делаешь precompile он готовит тебе твои ассеты в public/assets. когда ты в деве он делает прекомпиляцию на каждый твой запрос. хоть на /some/folder/not/listed/in/assetsprecompile . говоря совсем простым языком в проде ты работаешь с заготовленным public/assets а в деве тебе его делают по любому твоему запросу. и у тебя банально не правильно добавлена папка +='stuff.js' поэтому она не прекомпилена. я может и дебил но пропатчь спрокеты как тебе удобно и похоже я только тогда пойму твой поинт

Contributor

homakov commented Feb 29, 2012

dude, chill out.do you have an idea what is the difference between dev and prod model in context of sprockets? i am sure you do.
у меня уже кончились слова ) когда делаешь precompile он готовит тебе твои ассеты в public/assets. когда ты в деве он делает прекомпиляцию на каждый твой запрос. хоть на /some/folder/not/listed/in/assetsprecompile . говоря совсем простым языком в проде ты работаешь с заготовленным public/assets а в деве тебе его делают по любому твоему запросу. и у тебя банально не правильно добавлена папка +='stuff.js' поэтому она не прекомпилена. я может и дебил но пропатчь спрокеты как тебе удобно и похоже я только тогда пойму твой поинт

@Mange

This comment has been minimized.

Show comment
Hide comment
@Mange

Mange Apr 17, 2012

I'm with you @rwz.

Let's see if we can get everyone on the same page here.

@homakov:

Sprockets have this great feature that notices when a file you reference is a directory and picks the index.<extension> file from it. It's all documented in the Rails guide for the Asset pipeline. This is documented behavior, and also the way I group top-level files that I want to include in layouts.

Let's apply the discrepancy on another feature (Hypothetical; it actually does work like expected)

When I include "foo.js" in my layout; it discovers the file "foo.js.coffee" and uses that one in development, but when I do this in production mode, it fails

I have "foo.js" in my precompile list but it isn't precompiled at all, just ignored

Well, precompile only looks at the file names on disk. You should put "foo.js.coffee" in the precompile list instead of just "foo.js"

Then I shouldn't be able to just include "foo.js" in development mode either. The precompile list should work the same as the view helper

I hope this highlights why there's a problem in the first place.

Mange commented Apr 17, 2012

I'm with you @rwz.

Let's see if we can get everyone on the same page here.

@homakov:

Sprockets have this great feature that notices when a file you reference is a directory and picks the index.<extension> file from it. It's all documented in the Rails guide for the Asset pipeline. This is documented behavior, and also the way I group top-level files that I want to include in layouts.

Let's apply the discrepancy on another feature (Hypothetical; it actually does work like expected)

When I include "foo.js" in my layout; it discovers the file "foo.js.coffee" and uses that one in development, but when I do this in production mode, it fails

I have "foo.js" in my precompile list but it isn't precompiled at all, just ignored

Well, precompile only looks at the file names on disk. You should put "foo.js.coffee" in the precompile list instead of just "foo.js"

Then I shouldn't be able to just include "foo.js" in development mode either. The precompile list should work the same as the view helper

I hope this highlights why there's a problem in the first place.

@jpaas

This comment has been minimized.

Show comment
Hide comment
@jpaas

jpaas Apr 30, 2012

I'm with @rwz on this too. It's a bug. The docs clearly state that I can use <%= javascript_include_tag 'stuff.js' %> and that should resolve to javascripts/stuff/index.js. This works in dev but not in production.

jpaas commented Apr 30, 2012

I'm with @rwz on this too. It's a bug. The docs clearly state that I can use <%= javascript_include_tag 'stuff.js' %> and that should resolve to javascripts/stuff/index.js. This works in dev but not in production.

@homakov

This comment has been minimized.

Show comment
Hide comment
@homakov

homakov May 1, 2012

Contributor

@Mange you highlighted different problem - precompile paths lookup is different from include_tag lookup. I'm not sure if it should work in a similar way - they have completely different goals - but if you care it's OK to fix it. I don't think it will impact on existing apps anyhow.

Contributor

homakov commented May 1, 2012

@Mange you highlighted different problem - precompile paths lookup is different from include_tag lookup. I'm not sure if it should work in a similar way - they have completely different goals - but if you care it's OK to fix it. I don't think it will impact on existing apps anyhow.

@route

This comment has been minimized.

Show comment
Hide comment
@route

route May 1, 2012

Contributor

I totally agree with guys it is issue.

Contributor

route commented May 1, 2012

I totally agree with guys it is issue.

@Mange

This comment has been minimized.

Show comment
Hide comment
@Mange

Mange May 2, 2012

@homakov

@Mange you highlighted different problem - precompile paths lookup is different from include_tag lookup.

No, it is the problem. I'm trying to explain it.

Mange commented May 2, 2012

@homakov

@Mange you highlighted different problem - precompile paths lookup is different from include_tag lookup.

No, it is the problem. I'm trying to explain it.

@jeremy jeremy closed this in df84577 May 2, 2012

carlosantoniodasilva pushed a commit to carlosantoniodasilva/rails that referenced this issue May 3, 2012

Merge pull request #6095 from route/assets_precompile_task
Fix that asset precompile didn't respect the index.js convention. Fixes #3993.

route added a commit to route/rails that referenced this issue May 4, 2012

@emersonrp

This comment has been minimized.

Show comment
Hide comment
@emersonrp

emersonrp Jun 7, 2012

The merged commit, SHA: df84577, changes the behavior in exactly the opposite of the desired way -- it changes 'index' paths to point at their enclosing directories, instead of changing directory paths to look for the index files inside them. This has not fixed the original bug, and has introduced a new one.

I've submitted a pull request, #6655, that explains this in more detail, backs out the new bug, and actually fixes this bug.

The merged commit, SHA: df84577, changes the behavior in exactly the opposite of the desired way -- it changes 'index' paths to point at their enclosing directories, instead of changing directory paths to look for the index files inside them. This has not fixed the original bug, and has introduced a new one.

I've submitted a pull request, #6655, that explains this in more detail, backs out the new bug, and actually fixes this bug.

This was referenced Jun 7, 2012

@paulingalls

This comment has been minimized.

Show comment
Hide comment
@paulingalls

paulingalls Jun 21, 2012

I'm currently trying to add a "static_pages/index.js" to config.assets.precompile and it gets totally ignored. Related?

I'm currently trying to add a "static_pages/index.js" to config.assets.precompile and it gets totally ignored. Related?

@rwz

This comment has been minimized.

Show comment
Hide comment
@rwz

rwz Jun 22, 2012

Contributor

@paulingalls yes, but more to #6737 rather than this.

Contributor

rwz commented Jun 22, 2012

@paulingalls yes, but more to #6737 rather than this.

@jeremy

This comment has been minimized.

Show comment
Hide comment
@jeremy

jeremy Oct 2, 2012

Member

Fixed @ 19987b6

Member

jeremy commented Oct 2, 2012

Fixed @ 19987b6

@ilyakatz

This comment has been minimized.

Show comment
Hide comment
@ilyakatz

ilyakatz Jan 4, 2013

Contributor

I maybe late to the party here, but I came across this today and it makes me think that there is a bit of inconsistency - it would be great to see similar errors in development mode (without precompile) and staging/qa/production (with precompile). if index files are ignored in precompile it will cause a problem in qa/prod but will not be a problem in development. wouldn't it be nice to have similar behavior in both modes. Excluding index is fine as long as it is the same compilation-on-the-fly mode

Contributor

ilyakatz commented Jan 4, 2013

I maybe late to the party here, but I came across this today and it makes me think that there is a bit of inconsistency - it would be great to see similar errors in development mode (without precompile) and staging/qa/production (with precompile). if index files are ignored in precompile it will cause a problem in qa/prod but will not be a problem in development. wouldn't it be nice to have similar behavior in both modes. Excluding index is fine as long as it is the same compilation-on-the-fly mode

@nikhilvij

This comment has been minimized.

Show comment
Hide comment
@nikhilvij

nikhilvij Jun 16, 2014

encountered the same issue. Was this ever fixed?

encountered the same issue. Was this ever fixed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment