Cannot configure assets via pipeline on local prod

2019-08-17 07:42发布

问题:

This month, I upgraded from Rails 3.0 to Rails 3.1 - this week I tried to launch the server in production mode - today I have hit a wall !

I am unable to get my production environment server to serve up my public assets (JavaScript and CSS) via the asset pipeline, unless I set config.assets.compile = truein my environment.rb file, which for speed reasons I obviously don't want to do.

I have a large number of JS and CSS files, each of which tends to get used on one or two different pages. This means creating a single "manifest" file doesn't fit my usage, as each page wants something slightly different. I also expect some of the CSS won't sit together nicely. Therefore I have gone down the approach of "just get it working", looking to tidy up the large quantity of CSS / JS later.

Here is the production.rb file:

Implicit::Application.configure do
  ...

  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  # I set this to true, as I am testing this locally, just running a local Thin server
  config.serve_static_assets = true

  config.assets.compress = true

  # Setting this to false removes the issue - but is SLOW
  config.assets.compile = true

  config.assets.digest = true

  # This is overkill - but does get EVERYTHING precompiled for now
  config.assets.precompile += %w( *.css *.js )

  config.action_dispatch.x_sendfile_header = nil
  ...
end

This is quite a new area for me, and so I've spent much of today toggling these booleans and stop/starting the local Thin / Rails server to try them out. But the only value that's made a solid difference is the compile flag.

My application.rb file is pretty much standard, and has config.assets.enabled = true and config.assets.initialize_on_precompile = false in it, the latter from a heroku post (and a guess, again).

I have a fully populated public/assets directory, created with the bundle exec rake assets:precompile command, that takes about 20 mins to run on my oldish laptop (5 years), probably something to do with that "catch all" precompile regex, although with that line commented it still takes over 10 mins (!)

With the compile flag set to true, I can see copies of these assets getting created in my /tmp/cache directory - this is clearly the application creating it's own "compiled copy" of the assets.

With the compile flag set to false, I am confronted with the error message (in the logs, unless I set requests to local, then I see it on the rendered error page) of jquery.reveal isn't precompiled. However, when I go to http://localhost:3000/assets/jquery.reveal.js the javascript file is served up.

The line of my application layout causing this is:

<%= javascript_include_tag "application", "jquery.reveal" %>

I have tried changing that jquery.reveal to jquery.reveal.js with no change. Removing it fixes the index page, except that the jquery.reveal functionality is gone of course ! So clearly the application.js is being served up correctly. I just can't figure out why jquery.reveal isn't, as I can see the precompiled files in the public/assets directory.

回答1:

This is an interesting issue, and I think there may be two bugs - the one you've linked and another: the file is being being compiled to the wrong name. It might be worth trying to generate a minimal test case that you can submit with a bug report.

The workaround for this - and I suspect that this is why few people seem to have the problem - is to use a secondary manifest (linking libraries only via a manifest seems to be an evolving best-practice).

Create one called home.js and require just that one file to it.

This isn't a bad approach overall. These extra manifests have to be added to the precompile array (see the guide), and allow multiple libraries to be shared over several pages or sections without having to link them each time.



回答2:

Answering my own question here, but looks like it might be a bug in parsing assets with "periods" such as jquery.reveal

An issue report (https://github.com/rails/rails/issues/3398) reports this and highlights a commit (https://github.com/sstephenson/sprockets/commit/4ba5b32764a9073671df5e77355df6ed2bb3d3c9) which occurs just after Sprockets 2.0.3 - the default version that rails 3.1.3 relies upon. Upgrading Sprocket would therefore involve moving onto 3.2-stable rails - a bit bleeding edge for this newbie !

But the bug report does say this only occurs when config.assets.compile = true - and I did see whilst that was the case in my code that jquery.reveal was being dynamically compiled to jquery-8fu...8g.reveal.js (instead of jquery.reveal-8fu...8g.js).

So perhaps this ISN'T the answer. At least I hope it isn't. But will certainly continue to look at this period issue, as the "non-period" containing CSS / JS files are being served up just fine, as far as I can tell.