Why assets served as compiled? - ruby-on-rails

I am using Rails 5.2, and I notice when serving a page, the javascript file being served is compiled, however, I am in development mode.
for example, I get this html:
<script src="/assets/auth0/auth0_dialog.self-73034e01a7da3c346f6c123d6890950c4f1aac7f5f35ca09ced526e9c550328d.js?body=1"></script>
<script src="/assets/auth0/lock_init.self-b564b1f75c18a2fbbe1d41be6af70aa3d1c36c31aeb50cf52017d2ec31ceba10.js?body=1"></script>
for:
= javascript_include_tag "auth0/auth0_dialog"
= javascript_include_tag "auth0/lock_init"
any idea?

Related

rails 5 webpack 4 handling css files

I have a rails 5 app with webpacker. I am trying to use webpack to both bundle my css files and my js files.
In my javascripts/packs, I have both an application.js and application.scss files. I added bootstrap as dependencies to my package.json and am now trying to import both bootstrap css and js into my rails app. in application.js I have :
console.log('Hello World from Webpacker')
import 'jquery'
import 'bootstrap/dist/js/bootstrap';
In application.scss I have :
#import '~bootstrap/dist/css/bootstrap';
I cant figure out how to import both scss and js at the same time. In application.html.erb I have both
<%= stylesheet_pack_tag 'application' %>
<%= javascript_pack_tag 'application' %>
However it's ever the js or the css that is loaded but never both !
I guess there's a problem in the way webpack is configured but I cant figure it out. How do I configure webpack correctly to work with my rails 5 app and bundle both my css and js correctly.
Here's a link to the project :
https://github.com/davidgeismar/Visitors
For loading webpacker stylesheet to your Rails application first you should remove app/javascript/packs/application.scss file. Because webpacker separate the stylesheet code with same js file name with stylesheet extensions.
Example - Your webpacker main js file is - app/javascript/packs/application.js and you should import all css and js files inside. So you don't need keep app/javascript/packs/application.scss file, but webpacker generate an application.css file from extracting the code from application.js.
Here's the modified code from your rails app github repo. First remove the app/javascript/packs/application.scss
#app/javascript/packs/application.js
console.log('Hello World from Webpacker')
import 'jquery'
import 'bootstrap/dist/js/bootstrap';
//import 'bootstrap/dist/css/bootstrap.css';
// Added js code for checking webpacker is working fine or not.
document.addEventListener('DOMContentLoaded', () => {
document.querySelector('#content-from-webpacker').innerHTML = '<p class="h1">h1. Bootstrap heading</p><h1 class="display-1">Display 1</h1>'
})
Here's view code for loading webpacker.
#app/views/layout/application.html.erb
<body>
<%= render 'shared/navbar' %>
<%= yield %>
<!-- This id(content-from-webpacker) is used for displaying content from webpacker -->
<div id="content-from-webpacker"></div>
<%= javascript_pack_tag 'application' %>
<%= stylesheet_pack_tag 'application' %>
<%= javascript_include_tag 'application' %>
</body>
I hope it should work. Also I made this changes to your github repo and send a pull request.

Async JavaScript in production environment only?

I'm trying to get my JavaScript (Angular app) to load asynchronously so that the page can render a loading image while the browser downloads the JavaScript later. In production, this works just fine, but not in development, because Sprockets hasn't concatinated all of the files yet.
I'm using the following in my HAML file:
= javascript_include_tag "mio", :async => true
which is working as intended in production:
<script async="async" src="/assets/mio.js"></script>
However, in development the files are all separate, and execute out of order. For example, my Angular Quote Form Controller is executing before Angular has finished loading:
<script async="async" src="/assets/angular.js?body=1"></script>
<script async="async" src="/assets/mio.js?body=1"></script>
<script async="async" src="/assets/mio-ng/controllers/quote_form.js?body=1"></script>
So the question is, can javascript_include_tag ignore the async flag when in development, but not in production?
I found a way to rig this up to work, but I feel it is not the best solution:
= javascript_include_tag "application", :async => Rails.env == "production"

How should I reference conditional assets in a rails app?

To install bootstrap and have it work correctly on legacy versions of IE, you need to place this your head:
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
That's fine on a static site, but how would this work in a Rails app? Do I use sprockets to do this?
I have html5shiv.js located at
root/vendor/assets/javascripts/html5shiv.js
and respond.min.js located at
root/vendor/assets/javascripts/respond.js
How should I go about including these conditional assets?
In application.rb:
config.assets.precompile += %w(html5shiv.js respond.js)
Then add them in your layout:
/[if LT IE 9]
= javascript_include_tag 'html5shiv'
= javascript_include_tag 'respond'
By the way, what about a CDN for those resources?

Calling Javascript from the static index page

All I have in the public folder, index.html file of my rails is this:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script src="jstester.js">
</script>
</body>
</html>
and all I have in the assets->javascripts folder is that I added a jstester.js file in it and all it has for now is just one line of code:
alert("fffsdfasdsad");
Everything else is just coming from the Rails defaults.
Now when I run the rails server, should I see a message box? Because I don't see anything.
What is missing?
Assets served via the asset pipeline always come from /assets. The path to a JavaScript file served from the asset pipeline is /assets/<file>.js, not just <file>.js. Fix your src attribute:
<script src="/assets/jstester.js"></script>

how to use dust partial template files (.tl files)

I have few questions on partials and overriding templates.
For that i used the following folder structure.
projectRoot
dust-core-0.6.0.min.js
jquery.js
test.html
partial.tl
main_without_override.tl
The content of partial.tl:
{+greeting} Hola {/greeting}
{+world} World {/world}
The content of main_without_override.tl:
{>partial/}
The content of test.html:
<!DOCTYPE html>
<html>
<head>
<script src="dust-core-0.6.0.min.js" type="text/javascript"></script>
<script src="jq.js" type="text/javascript"></script>
</head>
<body>
</body>
<script>
$.get('main_without_override.tl', function(){
console.log(arguments);
})
</script>
</html>
In the index.html when i try to get the main_without_override.tl its saying 404. But im sure that the file is there. The path that firebug is showing is correct.But browser says 404.
I want to know
How to get this main_without_override.tl
Apply templating for main_without_override.tl and render in the browser.
I searched in google most of the examples give only the syntax. Can somebody help me in rendering the main_without_override.tl template.
In order to compile templates on the client (which is probably not a really good idea), you need to include dust-full instead of dust-core. This is because dust-core does not include the Dust compiler.
The reason that compiling templates on the client is probably not a good idea is that Dust compiles to JavaScript and as #monshi mentioned, you can compile the templates and then serve them as JavaScript. It is possible to get .tl files through AJAX if you include dust-full, but it is a better idea to compile that template beforehand and then make a dynamic request for that .js file when you need.
You can include your dust template as a JavaScript file by using <script> tag, but you need to compile it first, which is explained here
Then add following templates (scripts) to test.html:
<script type="text/javascript" src="partial.js"></script>
<script type="text/javascript" src="main_without_override.js"></script>
And in you JavaScript render the template by dust.render method:
dust.render('main_without_override', your_json_object, function(err, out){
your_dom_element.innerHTML = out;
});
Related question:
how to use dustjs-linkedin as client side templating?

Resources