How to add external assets file in rails 4 project? - css

I have an external css, javascript and Images files in a separate project and wanted to include in my new rails project. Here is my structure of folders:
external-assets/js/ <Files>
external-assets/js/plugin/<Files>
external-assets/css/<Files>
external-assets/css/plugins/<Files>
external-assets/images/<some Folders>/<Files>
external-assets/images/<Files>
So, I copied external-assets/js folder to app/assets/javascript and for css I copied external-assets/css to app/assets/stylesheets.
and replace <link rel="icon" href="external-assets/css/plugins/bootstrap.min.css"> to <%= stylesheet_link_tag "/plugins/bootstrap.min.css" %> in my html.erb file. I followed the same thing for other css files and js files. When I start the server I got this error:
Asset filtered out and will not be served: add `Rails.application.config.assets.precompile += %w( style.css )` to `config/initializers/assets.rb` and restart your server
After searching on SO post like: Asset filtered out and will not be served: add `config.assets.precompile and
Asset filtered out and will not be served. I need to mention my all js and css files to config.assets.precompile.
Questions
1) Do I really need to mention all of js, css and images file? I know the reason but I do have a lot of assets files.
2) What about If I put them in public folder? Is it good approach?
3) There is stylesheet_link_tag for css , javascript_link_tag for js. What about Images?

Do I really need to mention all of js, css and images file? I know the reason but I do have a lot of assets files.
No.
Sprockets has the require directives which concatenate any files you "require" into your application file...
#app/assets/javascripts/application.js
//= require x
What you want? Probably not... but it at least gives you the ability to call one file (application), whilst benefitting from the content of all the others.
2) What about If I put them in public folder? Is it good approach?
No.
Precompiling assets puts the minified versions into public/assets anyway.
3) There is stylesheet_link_tag for css , javascript_link_tag for js. What about Images?
image_tag
Assets
I think you're getting confused about the role of "external" assets.
If an asset is truly external (such as Google's JQuery repo), you'll be able to reference them by using the javascript_include_tag or stylesheet_link_tag respectively:
<%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js" %>
This will basically add the following to your layout at runtime:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
If this is what you want, you'll be best adding the external repos calls to your #app/views/layouts/application file (as above).
-
Rails Assets
However....
They're obviously not "external" assets if you have them stored locally.
So you're either going to have to call them from their real external repositories, or use them locally in your app.
If you're happy using them locally (which carries the responsibility of keeping them updated), you may wish to look at Rails Assets:
This is a gem repository (you have to add source https://rails-assets.org to your Gemfil), which allows bundler to ping their server for asset-based gems.
It is meant to work like Bower - taking any of the public repos and converting them into gems. It allows you to call external repos into your app:
#Gemfile
gem "rails-assets-jquery.easing"
#app/assets/javascripts/application.js
//= require jquery.easing
This will basically store a local version of the JS / CSS you wish to use in your asset pipeline, allowing you to include it with the sprockets require directive.
The big difference is that since these assets are downloaded through the gem system, they will be updated each time you run bundler.
We use it, and although it can be a little tricky sometimes, it's well worth it.

Either put it all into the public directory, and then use the html <script>, <link>, ≤img> tags to reference the assets. You will lose some Sprockets features like minification and digesting, but that's not a big deal.
Mention all the assets in the application.css / application.js, or create a new manifest file, e.g. custom.css / custom.js, list the assets to use here and then add those two files into the:
Rails.application.config.assets.precompile += %w( custom.css custom.js )

Do you have require _ tree in your application.js & application.css?
If not, just add it to both files and restart your server.
The require_tree directive tells Sprockets to recursively include all JavaScript files in the specified directory into the output. These paths must be specified relative to the manifest file. You can also use the require_directory directive which includes all JavaScript files only in the directory specified, without recursion.
Check out this guide
Hope it helps. :)

Related

Tailwind + SASSC in conjunction with Sprockets

I am having issues with Tailwind.
Seems like Tailwind is not compatible with SASSC as it probably uses newer CSS. https://github.com/rails/cssbundling-rails#how-do-i-avoid-sasscsyntaxerror-exceptions-on-existing-projects
Though I really need SASSC for the asset_path helpers in order to resolve custom fonts fingerprinted resources names that Tailwind will use.
I have been thinking of doing :
Keep SASSC and removing tailwind.css file from the Rails 7 pipeline by having CSSbundling exporting it directly in the public folder. Though asset is not fingerprinted then I can't really add a cache policy to the file which is a shame.
Try to remove asset_path from the SASS files and replacing it with .erb files to resolve the name of the fingeprinted asset. But probably won't work as the erb preprocessing should happen before precompilation.. (EDIt: seems to work but need to find out is it is using the current asset path or an older asset path)
Put fonts in public folder and call from there. Fonts are not assets that are designed to be changed for their respective file names. So I guess this is the best solution..
Has anyone found a solution for this ?
EDIt :
Seems like gem sassc-rails is really lagging on the Sass versions https://www.npmjs.com/package/sass as last repo update is 3 years old. Has someone tried to use the sass package with Jsbundling in order to remove the sass processor from asset pipeline ?
We could then remove the stylesheets folder from the app/config/manifest and leave sprockets to compile the Sass processed files from builds ?

Rails: Precompiled assets missing node modules

I am using yarn with my rails 5.1 app (not webpacker, just the default asset pipeline).
Running a local server in development environment, I experience no issues with my assets.
But as soon as I precompile my assets (the environment doesn't matter) or let Heroku package my assets, all stylesheets (of node modules) I imported from within my application.sass file don't work anymore.
The reason for that behavior is that sass compiles all files into one output file, but because of some reason appears to miss the #import statements which include node modules and load these files separately.
So this:
#import "components/index.sass"
#import "nodemodule/nodemodule.css"
Compiles to this in development:
// content of "components/index.sass"
// content of "nodemodule/nodemodule.css"
and to this in production:
// content of "components/index.sass"
#import "nodemodule/nodemodule.css"
while loading node_module/nodemodule.css separately as an asset, but the browser cannot resolve it. Javascript works fine.
The links are from my project that you can use as reference
in your asset.rb you need to include the /node_modules path in your default load_path.
If you open the rails console and input Rails.application.config.assets.paths you should see the new path /yourproject/node_modules added.
Then you simply write:
#import "nodemodule.css"
In my case for bootstrap 4 in my application.scss
#import bootstrap/scss/bootstrap
which correspond to the file in node_modules/bootstrap/scss/bootstrap.scss
for jquery.js and bootstrap.js you can check my application.js
I was having the same problem. Inspired by this comment removing file extensions from the imports ended up fixing it.
This didn't work:
#import "#shopify/polaris/styles.css";
#import "#uppy/core/dist/style.css";
#import "#uppy/dashboard/dist/style.css";
while this did:
#import "#shopify/polaris/styles";
#import "#uppy/core/dist/style";
#import "#uppy/dashboard/dist/style";
The node_modules need to be installed with npm install for example, so they're probably not getting installed on Heroku. Check out https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app
Most likely, you need to setup a Node.js buildpack which will install your npm dependencies.
I have finally found the problem. It is a very nasty bug of the sass-rails gem & an unfortunate design of the sprockets component of Rails.
1) sass-rails
#import does not seem to work with node_modules as it does with other assets. While those other assets get compiled into one file, node_modules only get referenced, loaded by the browser as separate sources, but ultimately not being used by the browser.
2) sprockets
Sprockets' require statement does only work if it is at the beginning of a file. Or as they put it in their documentation:
Note: Directives are only processed if they come before any application code. Once you have a line that does not include a comment or whitespace then Sprockets will stop looking for directives. If you use a directive outside of the "header" of the document it will not do anything, and won't raise any errors.
However, in my case, I was importing directives from a file that itself was imported from application.sass.

Not able to include external stylesheet in rails application

I have style.css file in my assets/stylesheets directory and in the html I'm using<%= stylesheet_link_tag "/stylesheets/style.css" %>. I tried inspect element to check it, and css file is not being included.
Your problem has the hallmarks of a Rails asset pipeline problem
Do you have an application.css.erb with something like this? It's created by default and serves as the backbone for the CSS aspect of the asset pipeline in rails.
/* ...
*= require_self
*= require_tree .
*/
Using the asset pipeline means that a call like "/stylesheets/style.css" would never be valid in production and should be avoided in code.
If you're seeing this problem in production, did you rake your assets to build the fingerprinted filenames?
The raked filenames are mangled to something like: /assets/style-4dd5b109ee3439da54f5bdfd78a80473.css, so you can see why using the filename "style.css" will not work.
# Rake assets for production
$bundle exec rake assets:precompile RAILS_ENV=production
Debug
To me step 1 is making sure your pipeline is setup to serve CSS assets. Until that works, your CSS will be broken. I would ask you to first check on the application.css.erb, to make sure your app includes your CSS tree in the pipeline. Then run the production rake, this will tell you what is happening with your CSS assets. If you post the output to your question, then we could see which, if any CSS is being included in your app.
Required reading for anyone doing Rails apps is the Asset Pipeline guide
Have you tried this?
<%= stylesheet_link_tag "style.css" %>
or
<%= stylesheet_link_tag "style" %>
Go to your config/initializers/assets.rb and include this in the file 'Rails.application.config.assets.precompile += %w( users.css )' , without the quotes, then restart your server.

Ruby on Rails, broken url() in css after concatenation

Situation
Use bower In .bowerrc
In bowerrc set directory vendor/assets/bower_components
In config application.rb I typed config.assets.paths << Rails.root.join('vendor', 'assets', 'bower_components')
Install gallery plugin called «fotorama», do it by bower
All files of plugin «fotorama» now storage in this directory "/vendor/assets/bower_components/fotorama"
In manifest css file application.css I type *= require fotorama/fotorama.css
In layout file I typed <%= stylesheet_link_tag "application" %>
Starting server rails server — everything is ok. In source of generated page I see <link href="/assets/fotorama/fotorama.css?body=1" rel="stylesheet" />. This css file has this line .fotorama__video-play {background: url(fotorama.png) no-repeat}, and many other lines where uses url for file "fotorama.png", and it is ok, browser try to find this png file near the css file, and successfully do it.
Stop server, precompile all essets rake assets:precompile, and then run server in production environment rails server -e production
Problem
In production, all my css files concatenated, and in source of page it looks like this <link href="/assets/application-2d31fc33890d01b046194920367eb3d4.css" rel="stylesheet" />, and still this file has this line .fotorama__video-play {background: url(fotorama.png) no-repeat}. Now browser trying to find png file here http://localhost:3000/assets/fotorama.png, but it isn't here, it isn't anywhere, because, I don't know why, there is no "fotorama.png" in "public/assets" folder.
Questions
Why pictures didn't transport from "/vendor/assets/bower_components" to "public/assets"
Have you got an idea, what can I do to solve my problem? Important, that I don't want to change urls in css manually, programatically — ok.
Excuse me for my english, and thanks for everybody who going to help me.
Solution and answers
Only files from "app/assets" transports to "public/assets" by default. To transport images from "/vendor/assets" type in "application.rb" this code config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif)
Task for gulp: if you see some changes in "bower.json", take all main files of bower components by npm moudle called "main-bower-files". Generate a manifest file with each css file with .erb extension, and save it "app/assets/stylesheets/bower_components_manifest.css"
This task continue: in every main css files, by npm module called "gulp-css-url-adjuster", add before every url <%= asset_path ' plus path to directory, and after ' %>. url("fotorama.png") >> url("<%= asset_path 'fotorama/fotorama.png' %>"). Add .erb extension and save.
In "app/assets/stylesheets/application.css" I add * require bower_components_manifest.
One of the other solutions, use gem "bower-rails". But I don't like it, because in some plugins in bower I need override some "main" files, and gem "bower-rails" can't do this, npm "main-bower-files" can. And I like to save my workflow for everything what I have done before start include my code to rails, gulp, bower.

How can I change the name of application.css in a rails project?

I'd like to change the name of the file of application.css but this yields the following error:
Asset filtered out and will not be served
I'm assuming this is because somewhere in the config files, rails is told to precompile application.css, and when I change its name, the config file still looks for application.css. can someone explain to me how I would go about doing this?
I ask because I would like to learn how to create my own manifest files for different controllers.
Have you tried include your new .css file to the list: config.assets.precompile += %w( newname.css ) in 'config/environtment/production.rb'?
The joke is in that you probably on the last rails 4 version. The rails team included sprockets_better_errors gem into out of the box functionality, so it checks 'precompilability' of assets even in development mode. Prior to that, you would not see any error, until deployment to the production
Hope it helps

Resources