Just a few questions to clarify some confusing factors for me.
About application.js:
require_tree . will recursively include all the js files within app/assets/javascripts. If I put a javascript file in app/assets/javascripts/subfolder, it will be included. If I just want to include a specific directory, I should use require_directory
lib/assets/javascripts and vendor/assets/javascripts can be referenced from the manifest, application.js. Their javascript files WILL NOT be precompiled unless they are stated in the manifest.
When I install a gem that requires a set of javascripts(e.g. bootstrap) I require the related javascripts files in the manifest too (e.g. //= require bootstrap). The javascript files live in the Gem path, and they can be referenced by relative paths too.
Are my statements all true?
For sure I can say that 1 & 3 are true, I use both of those statements in my code.
When it comes to numer 2, as Rails Asset Pipeline docs says:
For example, these files:
app/assets/javascripts/home.js
lib/assets/javascripts/moovinator.js
vendor/assets/javascripts/slider.js
would be referenced in a manifest like this:
//= require home
//= require moovinator
//= require slider
http://guides.rubyonrails.org/asset_pipeline.html#asset-organization
Related
After bundle update my Rails app fails to boot with:
Expected to find a manifest file in `app/assets/config/manifest.js` (Sprockets::Railtie::ManifestNeededError)
What's happening?
Looks like you've upgraded sprockets. The later version(s) of sprockets require what's called a manifest.js file. You don't have one. You need to create one, and add in a few "directives".
Why do I need to do this?
In the old version of sprockets, big assumptions were made about what assets to bundle/concatenate** - this is what sprockets does btw.
"Sprockets, please"
bundle everything in folder abc together
bundle AND concatenate everything in folder xyz
keep admin.js separate.
Easy Steps To Solve the Problem:
Create the manifest.js file
$ mkdir -p app/assets/config
$ touch app/assets/config/manifest.js
(not the root rails directory)
Then copy and paste the following into the manifest.js file you just created:
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
What are "Directives"?
Those commenty things //= are called "directives".
If you haven't done so, pls review the sprockets documentation and save yourself some headaches. Small example below:
Let's translate the //= link_directory ../javascripts .js directive:
"grab every js file in the javascripts directory, concatenate them, and keep them as SEPARATE javascript files i.e. no bundling." If you want bundling, use a different directive.
Set up your layouts template
You should also have a javascript_include_tag, which is typically placed in your application.html.erb file. If you have other files js files that are separately bundled, don't forget to add them to application.html.erb e.g.:
<%= javascript_include_tag "application", "addOtherFiles", "here", "etc", "data-turbo-track": "reload", defer: true %>
If you have a precompile array in your app/config/environments/production.rb folder (see below for an example) then perhaps you should move them over to your manifest.js if they are not already accessed above.
config.assets.precompile = ["admin.js", "admin.css"]
Presumably you will want your admin.js javascript file separate from your application.js file. No problem, just tell sprockets to keep them separate:
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
//= link "admin.js"
Lastly, if you are using webpacker, you might want to decide what you want handled by the asset pipeline and what you want handled by webpacker. i.e. remove the link_directory to the javascripts file according to your own particular use cases.
Reference: read here for further details re: manifest.js. file
Source: Thanks to Richard Schneeman's blog - see here for more information..
Footnotes and Primers
Concatenating? Normally JavaScript has a lot of white space. To speed things up, you can transform your JS code so that it has no white spaces, so it can be uploaded quickly - that's concatenating.
And bundling? Not as important as it was anymore, but you can combine multiple JS files into one single file, and send that over to the browser). The latest changes are a step in the right direction: now you have to tell sprockets explicitly, what files you want bundled and/or concatenated: this is done in your manifest.js file e.g.:
EDIT: if things are confusing / not clear: complain loudly! How can I fix if you keep mum? everyone benefits by these improvements.
A new major version of sprockets was recently released which is not compatible with the previous version.
Either perform the steps needed to upgrade or pin to version 3.x in Gemfile
gem 'sprockets', '~>3.0'
Based on the answer here you may be able to solve this with:
mkdir -p app/assets/config && echo '{}' > app/assets/config/manifest.js
And if you need more details, the answer in this thread helpfully points to the Guide to upgrading from Sprockets 3.x to 4.x
As suggested by link http://www.redmine.org/boards/2/topics/58169, it is a known issue. See #32223 and sprockets 4.0.0 breaks Redmine 3.4.11 with Ruby <2.5.0.
I just reproduced this issue with redmine 3.4.4, but found everything is ok with Redmine 3.4.12.
wget http://www.redmine.org/releases/redmine-3.4.12.tar.gz
I can run jQuery on local production doing rails s -e production but when the same project is deployed to Heroku, jQuery doesn't work and I get an error in the console that says
"Uncaught ReferenceError: $ is not defined"
. I am not using Turbolinks so I don't think I need to do anything besides
$(document).ready(function() {
//everything js goes here });
Normal JavaScript works though.
I checked in the console on Chrome with $("#element-id") and it gave details of the element, so I think jQuery is being loaded. Or is it that Chrome console has jQuery by default?
My application.js
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
// vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require Chart.min
//= require_tree .
Shouldn't the local production environment be the same as the Heroku? Why is the behavior different on Heroku and local production environment?
I tried to load i18n.js and translations.js in the application.js.erb
However the file i18n.js could be found, but the translations.js could not found.
it shows me this exception ActionView::Template::Error (couldn't find file 'translations.js')
How could I fix the problem? I've also tried to load ../../public/javascript/translations.js but it didn't work as well.
public/javascripts
-i18n.js
-translations.js
pplication.js.erb
//= require i18n
//= require i18n.js
//= require translations.js
The asset pipeline and public/ have nothing to do with each other.
If you want to include the files via the asset pipeline, they need to go under app/assets, lib/assets or vendor/assets.
Anything placed in public/ is not part of the asset pipeline and you'll need to include it via its own <script src="/i18n.js"> tag.
I just finished writing controller for a project, everything works fine on my local computer, but in production images from the view of my controller load from 'images/bg/*' instead of 'assets/bg', same goes for javascripts ('javascripts/games/' instead of 'assets/games/')
I think the reason behind this is because image_tag somehow generates wrong links, but what's with javascripts? I don't know what to do
The server computer runs nginx, if it matters
See for yourself - this is my controller http://gorodigr.com/ruletka , and this is another one http://gorodigr.com/poker_kosti as an example
application.js
//
//= require jquery
//= require jquery.turbolinks
//= require websocket_rails/main
//= //require jquery_ujs
//= //require bootstrap-alert
//= //require vallenato
//= //require websocket_rails/main
//= //require_tree .
//= require turbolinks
jQuery(document).ready(function($){
.
.
.
some javascript
application.css
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the top of the
* compiled file, but it's generally better to create a new file per style scope.
*
*= require_self
*= require main
*/
Update
Now it behaves even more strangely, same image_tag path, different results
I doubt the assets are loading from the "wrong" place - they are likely subject to the workings of the asset pipeline, especially if you're seeing problems in production
--
Asset Pipeline
The main issue you have is likely to do with the asset pipeline. Let me explain
The asset pipeline is a feature of Rails, removed in Rails 4 actually (but the functionality still persists), whereby your "assets" (images, css and javascripts) will be kept in a set of folders detatched from your "views". You'll then be able to call these as you wish
The magic of the asset pipeline is that when you run your app in production, it will take your files, compile them, and pull them from a totally different location (public/assets), a path which will be called by your asset path helpers:
--
Structure
Bottom line is that if you have to concern yourself with the path of your assets, you're not doing it right.
As long as you keep your assets in the correct folders & use the helpers, your app should serve them correctly. In regards to your specific issue, let's look at what the problem might be:
Your assets should be stored as such:
-- app
-- | assets
-- | -- | javascripts
-- | -- | -- application.js
-- | -- | -- your.js
-- | -- | -- other.js
-- | -- | -- javascripts.js
This will give you the ability to call any of these files using the different asset path helpers you are provided with:
#app/views/layouts/index.html.erb
<%= javascript_include_tag "application", "your", "other", "javascripts" %>
In conjunction with this, you'll want to consider the role of manifest directives in your assets:
#app/assets/javascriots/application.js
// ...
//= require jquery
//= require jquery_ujs
//= require_tree .
This means that if you call the application.js file in your layout in development, it will just load the files you need. If you load its precompiled version in production, it will concatenate all the required files into the single application.js file
--
Fix
In light of your image & updated post, here's what I'd do:
Put all your javascripts into the correct folder (/assets/javascripts)
"Require" all the files you need in your application.js
If you want to include separate files, precompile it separately
Firstly, put all your files into the app/assets/javascripts folder
Secondly, fix the following problems in your application.js:
//= require jquery_ujs
//= require bootstrap-alert
//= require vallenato
//= require websocket_rails/main
//= require_tree .
Thirdly, if you want to include /games/ruletka.js, you'll be best doing this:
#config/environments/production.rb
config.assets.precompile += ['games/raletka.js']
#app/views/layouts/application.html.erb
<%= javascript_include_tag "games/raletka" %>
If you have different assets than application.js you have to include them in the config for precompile.
For example in your config/environments/production.rb uncomment the following line and adjust it to your assets.
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
config.assets.precompile += %w( games/ruletka.js )
Images should be automatically precompiled, so they should work out of the box. But for CSS you have to use special helper to get correct url:
.class { background-image: url(<%= asset_path 'image.png' %>) }
For more details, reffer to http://guides.rubyonrails.org/asset_pipeline.html
Also, if you're deploying with capistrano, make sure to include 'capistrano-rails' gem, and enable it to allow precompilation of the assets after your deployment is finished.
so here is my problem
sprocket defines these directives
include
require_directory
require_tree
require_self
depend_on
stub
so what I miss is an include_tree directive to include all javascript sources (placed in another directory) in one file!
what is the best way to do that?
Let's say your js files are in the directory lib/assets/your_library/yourfiles.js (notice , that it should be an assets directory). You just have to create an index file , named index.js ( it is a manifest file too) and insert a directive like this :
//= require_tree .
(or files you wish to be included)
After that , in your application.js insert :
//= require your_library
More about using index files in asset-pipeline can be found in this Rails guide.