Precompiling assets on the production server is very slow. So I have decided to recompile them on the development machine and upload assets to the Amazon S3 by jammit. Everything's done but I have some negative problems:
I have to include public/assets directory to git control. Because if public/assets directory is empty on the production server fails
If I precompile assets on the development machine application.js includes in the HTML as compressed and that way I have duplicated js code. Changing js doesn't make any effect because precompiled application.js interrupts this code.
That way my development process includes following steps:
Remove precompiled assets if I'm going to change js or css
Do some changes
Precompile assets
Upload assets to S3 by jammit-s3
Do commit and push my changes including assets to the git server
Deploy by capistrano
My questions are:
Is it possible to configure development environment don't include compressed application.js if I have it in public/assets directory?
Is it possible to configure production environment to work with empty public/assets directory? Assets will only be on the S3 server.
For question one I don't know a permanent solution other than running:
bundle exec rake assets:clean
before you switch back to development mode. I'd be interested to see if you can just ignore the assets in development without turning the entire assets pipeline off.
In production.rb there is an option for your second question:
# Enable serving of images, stylesheets, and JavaScripts from an asset server
config.action_controller.asset_host = "http://assets.example.com"
It should then ignore your assets directory since it relies on the remote host.
Hope that helps.
I resolved this problem by including assets dir in gitignore and exclude only one file - public/assets/manifest.yml and production server works correctly now, i.e. config.action_controller.asset_host = "http://assets.example.com" works. It requires only manifest.yml file
Related
I am developing Rails 5 application and use assets pipeline.
It work well in development mode, but if I try to run it in production mode, it can't load images & styles correctly.
I checked and found that it is because
config.assets.compile = false
in config/environments/production.rb
Unless I set it true, it doesn't work at all.
I know live compilation isn't good for production, what is solution?
There are two options related to serving assets within a Rails server:
Asset compilation
config.assets.compile = true
refers to asset compilation. That is, whether Rails should recompile the assets when it detects that a new version of the source assets is there. In development, you want to have it set to true, so that your styles get compiled when you edit the css files. With the next request, Rails will automatically recompile the assets. On production, you usually want to set it to false and handle asset compilation during deployment. For this, you have to run
RAILS_ENV=production bin/rails assets:precompile
Usually, if you deploy using Capistrano, it takes care of that.
Asset serving
The second option related to assets is
config.public_file_server.enabled
This describes whether it is Rails that should serve the compiled files from the public/assets directory. In development, you want that, so it's true by default. In production, you usually don't want to fire up your web server to serve the logo image or a css file, so you probably compile the assets and then host them separately (for example, on a CDN like cloudfront). If you still want them to be served in production, you can launch Rails with:
RAILS_SERVE_STATIC_FILES=true RAILS_ENV=production bin/rails server
Precompile your assets first.
Run RAILS_ENV=production rake assets:precompile to generate your stylesheets and js files in your public directory.
rake assets:precompile currently spits everything into my public/assets directory when I was under the impression (after setting up S3) that it would push up to Amazon. I am utilizing asset_sync as outlined here
Currently I have this in my application.rb:
class Application < Rails::Application
config.assets.enabled = true
config.assets.digest = true
end
Then in my development.rb I have:
config.action_controller.asset_host = "//#{ENV['FOG_DIRECTORY_DEV']}.s3.amazonaws.com"
config.action_mailer.asset_host = "http://#{ENV['FOG_DIRECTORY_DEV']}.s3.amazonaws.com"
config.assets.initialize_on_precompile = false
What am I doing wrong here?
You must appreciate that asset_sync is there to sync your assets (not replace them)
Asset Sync
The gem itself will let Rails publish your assets "locally" (to /public/assets), and then it will essentially push them all to your S3 bucket, replicating them.
As described by the gem's documentation:
Synchronises Assets between Rails and S3.
Asset Sync is built to run with the new Rails Asset Pipeline feature
introduced in Rails 3.1. After you run bundle exec rake
assets:precompile your assets will be synchronised to your S3 bucket,
optionally deleting unused files and only uploading the files it needs
to.
--
Fix
In regards to your problem, I'm sure that by default, development assets are served dynamically - meaning that if you want to run them as static (precompiled), you'll have to tweak some of the settings which define this:
#config/environments/development.rb
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = false #true
This should enable you to use the precompiled assets locally (in development), which will in turn allow you to use S3
Production serves static assets by default, meaning the most applicable way to test asset_sync is literally by deploying to your production environment. However, you should be able to use the code above to get it to work in development, too
I precompiled assets on my dev environment (by mistake!) now any changes done on js/css files are not reflecting on browsing site locally.
I removed assets folder from public directory but then no css/js was available.
How do I get rid of this?
As a temporary solution I just cloned project into new directory and it works.
The question is: why do you need asset precompilation in the development environment? It's not meant to work like this.
The asset pipeline allows working in development with the uncompressed, unminified versions of your JS files. It also reloads them each time you refresh your browser, so you can develop your application with ease.
In production, though, the asset pipeline precompiles the JS files / assets you have into one single, minified file. This allows for better performance on the client as the files are smaller and are fetched in one single request.
So precompiling assets in development makes no sense at all.
In case if I understood you correctly, generally, when you precompile by default assets directory is being created inside public directory. To get your assets back, you can precompile again.
There is also a cache in tmp directory that you might consider removing.
Later you could use a $ (bundle exec) rake assets:precompile in combination with $ (bundle exec) rake assets:clean instead of $ rm -r public/assets so that new assets would be in effect rake way.
A one line command to look at new changes after your commits in environment would be
$ RAILS_ENV=(environment) rake assets:clean assets:precompile
but generally in development assets are not meant to be served as in production mode, so running previous with RAILS_ENV=production and starting a local server in production mode would be considered as a way to check (but not to make sure) if your assets would be served upon deployment in real production.
I went into the exact same problem and resolved it following #dashi's advice: 'remove directory assets in public, then start server in development mode.' everything is back to normal.
I recently deployed a first iteration of a project to Heroku. Because I precompiled, all of my assets used during development are now in the public/assets and public/system folders.
I am aware of two options for accessing my assets during development. The default option seems to be to allow the public/assets files to override my app/assets files. However, if I do this, any CSS changes I make in app/assets is not reflected.
The alternative option is to access ONLY the app/assets folder through:
config.serve_static_assets = false
However, by doing this, I can't see any of my images during development, as they have already been precompiled and moved to public/system
Is there a way to access my CSS/JS files from app/assets, yet still load my images from public/system?
Or am I supposed to do all of my CSS/JS development out of the public/assets folder? Any feedback would be much appreciated.
After a deploy I like to run
rake assets:clean
to get rid of the compiled/compressed assets in public/assets. This let's Rails look back to my app/assets directory in development mode since none of my assets are in public/assets anymore.
Also, unless your circumstances are special, you should be putting your images into app/assets/images, not public/system. rake assets:precompile pushes images into public/assets too. When doing this, you need to use image_path(...) within your ___.css.scss file(s) to allow the paths to be updated properly with the hashed filename generated for the image assets during precompile.
Finally, it seems reading through this Rails Guide would do you a lot of good.
I prefer not to concatenate JavaScript files in development mode, but serve them as individual files. So I configured:
development.rb:
config.assets.compress = false
config.assets.debug = true
config.assets.compile = true
In my /app/assets/javascript directory I have:
reviews.js
reviews/
foo.js
bar.js
reviews.js:
//= require jquery
//= require jquery_ujs
//= require_tree ./reviews
I include the JavaScript using <%= javascript_include_tag "reviews" %> in my layout. The generated page correctly references the three scripts individually and reviews.js is essentially empty. So far so good.
Now when I precompile my assets for production using rake assets:precompile the three JavaScript files are concatenated into reviews.js. This is all fine for production but now, in development mode, the concatenated reviews.js is served in addition to the two individual files.
Of course, this leads to all kinds of nasty bugs when developing because now, the content of foo.js and bar.js is served twice, one of them in a potentially older version in reviews.js.
How can I make sure Rails doesn't use the precompiled assets in development mode?
In config/environments/development.rb set:
config.assets.prefix = "/assets_dev"
so that in development mode Rails will look there (but it will not find anything, as you will not compile assets in development (this is indeed what you are trying to do -- not compile assets)).
When precompiling for production, use
RAILS_ENV=production rake assets:precompile
so it compiles into the default assets folder, public/assets.
It sounds like you are precompiling locally. Because the files exist in the expected location they are being served by your dev server, and the requests are not going to Sprockets.
The only way to stop this is delete the compiled files.
Normally you do not need to compile locally. It is expected that in almost all cases the precompile task will be run during deployment of the app. There is a Capistrano recipe for this on the asset pipeline guide page.
If you do need to have those files locally committed to your repo you could use a branch to avoid the problem. Reserve your master branch for production code, and make a second branch for dev. Only compile and commit assets on master. When you switch to dev, they will be gone. Merge dev into master as required.
Edit: Make sure you force your browser to update (control + F5) or you may find the old assets used from the browser cache!
in config/environments/development.rb set:
config.serve_static_assets = false
and no files from /public will be served
I tried this and it worked. rake assets:precompile RAILS_ENV=production
I observed that the new version of assets pipeline does this when you run rake assets:precompile does rake assets:precompile:all