rails producing separate css files in production - ruby-on-rails

I'm using Rails version 6.0.3.2, but I started to notice that when precompiling asset:
rails assets:precompile RAILS_ENV=production
I get my public/assets filled with all my css files separated (as they are in development) and minified in addition to application.css
Is this something new or there is something wrong? I have no idea why this is happening!!

As far as I know it will always build them independently, then assemble them into a unified file if so requested. It doesn't trim the individual files after. The individual files are just a byproduct of the compilation process.
You only need the combined asset pack for deployment, the individual files can be ignored.

Related

heroku precompile assets is it necessary

I've started learning rails and I've already built two apps, one simple blog app and one store app. Now I ran into a term precompile assets when uploading to heroku, can someone explain it to me is that necessary when deploying an app to production, because i've uploaded my store app to heroku without any problems?
Assets is your css + JS. Precompile assets mean that they get joined into single .css and another single .js. file (to load it in one HTTP request). And special mechanism of minifying get applied to both these files (to make them smaller). Rails by default is setup in a way, that it uses average files in dev and compiled files in prod. You can easily change this in configs, but you shouldn't do this unless you really know what you do.
If you want you can compile this files locally running rake assets:precompile and then put it into git. I think that you can disable/enable precompile during heroku deploy in heroku config. But, in general, I would stick with the very defaults.
More info on asset pipeline: http://guides.rubyonrails.org/asset_pipeline.html
Rails has an assets pipeline which consists of Sprockets and the assets helpers.
The assets pipeline will concat and minify your CSS and javascript and takes care of setting the correct paths to images and other assets. This is known as compiling the assets.
In development this is done on the fly for each request which lets you immediately see changes.
In production this would be far to slow so instead the assets should be compiled once at deploy time. Heroku does this automatically for you in a post-commit hook.
Pre-compiling is when you run rake assets:precompile locally and then upload or push the result to a server. This is done if you are deploying to a server without the support for the assets pipeline. For example if the production server does not have a javascript runtime which is required to run uglifier.
It adds tons of noise to the git change history and manually doing anything is a common source of user error. So pretty much it sucks and you only do it if you have to.

What is the difference between shared/public/assets on production server and pre-compiled assets on rails public/assets on source code?

I pre-compiled my assets i.e CSS,javascript and fonts files in order to reduce the file size. Using RAILS_ENV=production rake assets:precompile.
I already have compressed assets on the server in the following path:
shared/public/assets
But anyway I went ahead and pre-compiled them again on my local and they got generated inside public/assets folder. I noticed that the compressed files are exactly as same as the ones on server shared/public/assets. But the tester in my team is been testing it on some online tools. And they all say "Your java script files need to be minified." So, would this "minifying" issue be solved if I push these locally pre-compiled assets to production source code?
You should not push locally pre-compiled assets to production source code, no.
Your build process should include precompiling assets for production during a deploy. If you're using Rails 5 then that is already turned on by default. As long as the production environment has a proper environment variable (again, by default, the environment variable 'production' takes care of all these things), the assets will be precompiled.
You say that your compressed files, after running rake assets:precompile, are exactly the same as the ones on the server. That means your javascript should have and should be minified and uglified (again, default for Rails 5). To confirm that's the case, open dev tools in chrome, hard-reload (ctrl+shift+r) and check with JS files are being loaded under "network" tab. If the asset pipeline was used as it should be, you should only see minified and uglified js files here. If you open them up, they should already be minified and uglified. If that's not the case then either the asset pipeline wasn't used for fetching the JS files or your build process has been changed.
If most of these JS files are minified and uglified with - check those which aren't. Is some library being added outside of asset pipeline? Are those files minified?
If all of your JS files are actually minified, then tell your tester to use a different tool ;)

Rails not precompiling images in the app/assets/images folder?

I have some images (svg) in my app/assets/images folder. According to the Rails Guides, all the files in the assets folder should be automatically precompiled.
However, when I reference the the image using image_tag('filename'), it shows me an Sprockets::Rails::Helper::AssetNotPrecompiled error
Asset was not declared to be precompiled in production.
It tells me to declare the file to be precompiled manually, but why should that be necessary? On top of that, why does it concern itself with the production environment when I am doing everything in development?
If you added the image after you've started the server in development, restart the server. Sprockets will then precompile that image and the error will go away.
I'm pretty sure Rails doesn't support .svg yet, hence why it would ignore it.
You'll need to include the file extensions in your config/application.rb file:
#config/application.rb
config.assets.precompile += %w(.svg)
In regards the application concerning itself with the production environment, you have to remember that the precompilation process is meant for production:
The first feature of the pipeline is to concatenate assets, which can reduce the number of requests that a browser makes to render a web page. Web browsers are limited in the number of requests that they can make in parallel, so fewer requests can mean faster loading for your application.
Concantenating assets essentially means to compile your asset files into a single file, which is typically then minified.
--
Although this can be done in real-time, it's mostly the realm of static assets (which have to be precompiled). This means that if you run the rake asstes:precompile task, it will work on the development environment, unless you call RAILS_ENV=production rake assets:precompile (which sets it to the production environment for that request.
why does it concern itself with the production environment when I am doing everything in development
The application is going to run in production, not development.
Ultimately, everything you do in development should make it easier / better to work in production. In the sense of your assets, it means that you can use many of the quirks of Rails' asset pipeline, from sprockets to preprocessors such as SASS & Coffeescript
It's probably because you didn't specify the complete image name. I ran into this problem after updating the gem too. Before I just used image_tag 'some-image', but it seems that you now have to specify what type of image/extension you want to use.
Try this: image_tag 'some-image.svg'. It worked for me.
Cheers.

Ignore certain files in the asset pipeline when performing assets:precompile

I have a templates directory in my assets folder on my Rails setup which hosts my templated-HTML files. I've implemented a partial system where I can load text snippets into each template so long as it has a .erb file attached to it. The partials are prefixed with an underscore, so /assets/templates/_form.html is a partial which is included inside of /assets/templates/edit.html. This works, but there is an issue when I run assets:precompile.
The assets:precompile command will precompile the _form.html files as well (since they're located inside of the assets/templates folder) and I don't want this to happen since they can't be precompiled (since any erb variables are missing and so on).
Is there any way I can inform the rake assets:precompile command to ignore certain files (in this case files that have an underscore infront of them)? Does someone know how to do this? Or can someone point me to the github repository which has the source for the rake assets:precompile command?
In Rails 3.2.8 you can find the source for the rake task definition here.
What you're asking has been brought up at least once in Sprockets issues tracker
https://github.com/sstephenson/sprockets/pull/86
joshpeek added a new stub directive in Sprockets 2.2 which looks like a promising solution to 'ignoring' certain assets from the pipeline.
Rails 3.2 doesn't support a version of Sprockets anywhere near 2.2 and there doesn't seem to be any intention on doing so before Rails 4 from what I've read (though I'd love to be wrong about that). Here's at least one closed issue (no action taken) requesting an upgrade to 2.2.
https://github.com/rails/rails/pull/5984
For your situation though, it seems to me that you might be using app/assets incorrectly. I can't offer an alternative solution as I don't know enough about your setup/usage to say definitively, but as you said, files with .erb in app/assets are going to be processed by Sprockets.

Do you add public/assets in version control?

In rails 3.1, when you precompile the assets, rails create public/assets directory and add files there.
Do you version-control public/assets/*?
I use Capistrano to deploy. The last step is compiling the assets. Nothing like that gets checked into version control.
https://github.com/capistrano/capistrano/wiki/Documentation-v2.x
Checking in compiled assets, .gz files/etc, will just clutter up version control.
I was looking for an answer to this too. I found the official Rails Guide has some thoughts on this:
http://guides.rubyonrails.org/asset_pipeline.html#local-precompilation
Here's a quote of the relevant section (emphasis added):
There are several reasons why you might want to precompile your assets locally. Among them are:
You may not have write access to your production file system.
You may be deploying to more than one server, and want to avoid duplication of work.
You may be doing frequent deploys that do not include asset changes.
Local compilation allows you to commit the compiled files into source control, and deploy as normal.
There are three caveats:
You must not run the Capistrano deployment task that precompiles assets.
You must ensure any necessary compressors or minifiers are available on your development system.
You must change the following application configuration setting:
In config/environments/development.rb, place the following line:
config.assets.prefix = "/dev-assets"
The prefix change makes Sprockets use a different URL for serving assets in development mode, and pass all requests to Sprockets. The prefix is still set to /assets in the production environment. Without this change, the application would serve the precompiled assets from /assets in development, and you would not see any local changes until you compile assets again.
In practice, this will allow you to precompile locally, have those files in your working tree, and commit those files to source control when needed. Development mode will work as expected.
So, it looks like it might be a good idea to put precompiled assets into VCS on occasion.

Resources