Fast Example,
lets say, i have this js file, test.coffee
alert 'test!'
my goal is,
I dont want this code to be loaded in every pages
so i manually included where i want,
<%= javascript_include_tag 'test'%>
but the tragedy happens in production mode,
this test.coffee is not minified in production mode!
I want this code to be minified, but it should not integrate and minified to application.js, because i don't want this code be loaded in every pages.
How can i solve this dilemma?
You are having this issue because rails by default doesn't precompile file with the coffee extension. You should be able to solve this issue be prepending the .js extension so your file should look like this:
test.js.coffee
Straight from the rails docs:
When using asset precompilation, you will need to ensure that your controller assets will be precompiled when loading them on a per page basis. By default .coffee and .scss files will not be precompiled on their own. See Precompiling Assets for more information on how precompiling works.
Note:
There's a mechanism in rails that allows you to "inject" javascript at runtime.
Typically you would define a yield :javascripts in your app layout.
And add content to this yield using:
<% content_for :javascripts do %>
<%= script_tag :test %> # Content here will be yielded
<% end %>
This allows you to define your javascript at the bottom page while injecting page specific assets.
Related
Upgrading an existing React project from Rails 4 to 5.1 and loading assets with the new Webpacker pack_tag system. Things seem to compile correctly, I've got a pack file packs/mutts.jsx and in my index.html.erb I reference with
<%= javascript_pack_tag 'mutts' %>
<%= stylesheet_pack_tag 'mutts' %>
When the server runs, this results in 4 files compiled to app/public/packs/: a .js, .js.map, .css and .css.map - all with [packname]-[hash].extension format.
When I inspect the html generated from the pack_tags, I can see they each link to the corresponding js and css files, with the correct hash in the filename. And looking at the Network tab in devtools, both files load successfully with 200.
But when I look at the Sources tab, I see at localhost:3000 there is a packs/ directory that only contains the js file, and the css is nowhere in sight, and styles are definitely not being applied to the page.
Am I getting the file structure or importing wrong or something? Doesn't seem to be a webpack config issue, as the contents of the compiled file look correct.
The problem was where I placed the stylesheet_pack_tag. After placing it in the <head> it worked.
Should have caught this - most of the demos for Webpacker have the tag placed right with the relevant javascript_pack_tag, but in my case I'm rendering a new JS root per page, so the js pack is rendered by a rails view that's not the root application.html.erb
I've seen some webpacker examples that seemed to be going for "keep assets in proximity of concerned code", but I'm happy just chucking global styles in the head here.
Is this a good practice to require assets located under public folder? e.g. I have lots of javascript under public/mythirdparyjs folder and I want to make these javascript files available for only specific page, what will be the best way to do this?
Thirdparty js files should be in your vendor folder. Once you precompile them for production they will be then moved into your public folder automagically. To call certain files on specific pages you need to remove the require_tree directive and also pay attention to which files are called in your application.js asset file. At the bottom of every view page (html.erb) you can add the following to run only page specific js:
<%= content_for :javascript do %>
<script type='text/javascript'>
YOUR FUNCTIONS HERE
</script>
<% end %>
Then in your application/layout view at the bottom before the closing body tag you should add:
<%= javascript_include_tag params[:controller] if Rails.application.assets_manifest.assets["#{params[:controller]}.js"] %>
<%=yield :javascript %>
This will then run any js on a page by page view basis and include any require statements for any files in the corresponding controller's js asset file.
UPDATE to address comment: If you have a gem you installed and then need to require certain js files, these should be required from your app/assets/javascripts folder in either the application.js file (if you want that gem to be usable throughout your application) or in the controller specific js file if you only need that functionality on a few pages. For example, the angular gem is probably used throughout your application so you would add the //=require statement to the application.js file in your app/assets/javascripts folder. If you manually download some js libraries you should put them in the vendor/javascripts folder however you still require them in your app/assets/javascripts folder files wherever needed.
My local development runs fine, rendering javascript_include_tag "some-script" as referencing /assests/some-script.js correctly.
In Heroku, it references /javascripts/some-script.js
I'm using gem 'rails_12factor' in production in my Gemfile
Do I need to change any asset configuration settings? Like precompiling assets? I'm aware there are several config settings, but I'm unsure when to use them, in the past I've been fine without modifying them (like this suggestion).
It's just odd it references the /javascripts folder...
Also, to note, I am not currenty using javascript_include_tag "application" in layout/application.html.erb I am importing scripts manually using javascript_include_tag "some-script" in specific view erb files
Secondly, /assets/some-script.js comes up as a 404, so this must means my assests aren't available, which could be a second issue.
Any ideas?
This answer helped me resolve my issue. I had to manually add the js files to the assets precompile list in config/environments/production.rb like so:
config.assets.precompile += %w( some-script.js )
config.assets.precompile += %w( some-script2.js )
...
When I use a script in a view javascript_include_tag "some-script" works.
I want to use a JavaScript library such as a jQuery plugin. Do I use the Rails asset pipeline? Or should I include it with a javascript_include_tag? What are my options and what is the recommended practice?
Will you use the JavaScript library on only a few pages or throughout the application? If you will use it throughout the application, use the asset pipeline by adding it to the vendor/assets/javascripts folder. If you plan to use the library on a single page, use the javascript_include_tag.
Here are rules of thumb to guide your use of JavaScript in Rails:
Logically organize your site-wide scripts in the app/assets/javascripts/ folder.
Copy external JavaScript libraries (such as jQuery plugins) to the vendor/assets/javascripts folder.
List site-wide scripts in the app/assets/javascripts/application.js manifest.
Let the Rails asset pipeline combine them all in one minimized application.js file.
For scripts that are used on a few pages that have few visits, load as page-specific JavaScript.
Put page-specific JavaScript in the lib/assets/javascripts folder.
For page-specific JavaScript, use <%= yield(:head) %> in the application layout and <% content_for :head ... %> in the view.
For a full explanation with all the details, see my article:
Including External JavaScript Files in Rails
To access Javascript on a single file, javascript_include_tag is the best option.
With that what you can do is too add 'Rails.application.config.assets.precompile += %w( yourfilename.js )' to your 'config/initializers/assets.rb' file.
In Haml
= javascript_include_tag "example"
To load the file assets/javascripts/example.js
So I've recently started to include quite a few .js files in to my web application and some of them depend on each other so load order is important.
However rails caching just seems to load a all.js file with no particular order to the files.
What's a good way to solve this issue?
You can do as follows
First, load the default JavaScript files.
Then load other scripts in the order that you want
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag "script_1", "script_2", "script_3" %>
The load order depends on your Javascript manifest file. In Rails 3.1 you can go to
app/assets/javascripts/application.js
At the bottom of the file you will see directives for rails how what / how to include files into the Rake pipeline. In the below example, I included a new directive that will include all the files in the directory called "Templates". I also made sure that the Handlebars.js templating file is called before all of the files in the "Templates" directory, otherwise the browser would throw an exception
//= require handlebars
//= require_tree ../templates
//= require_tree .
Hope it helps!
I've been experimenting with the YUILoader Module, it seems pretty nifty, though I am currently frussing about loading up custom modules. It's totally doable, I just couldn't figure it out in 5 mins.
http://developer.yahoo.com/yui/yuiloader/ (YUI2.8.1)
http://developer.yahoo.com/yui/examples/yuiloader/index.html