How to minify JS with Django templates, and RequireJS - javascript

Setup:
Django, currently using Django-Compressor for CSS
Nested Templates using Django templatetags to nest
RequireJS to pull in JS modules.
Example:
base.html:
<html>
...
<script src="/static/js/libs/require.js">
...
{% include "body.html" %}
...
<script>
require(['/static/js/base']);
</script>
</html>
body.html
<h1> This is the body </h1>
<script>
require(['/static/js/body']);
</script>
So with this setup none of my JS files are being compressed. I can't use Django-Compressor because it won't utilize requireJS correctly, nor can I find anything that will help in this case.
Some ideas I have come up with have been to minify the JS files in place, or to run gulp/grunt beside Django, but that would make local development ugly.

Have you considered using django-pipeline?
https://django-pipeline.readthedocs.org/en/latest/usage.html
With it's template tag to pull in JS files, you may be able to replace both RequireJS and Django-Compressor.

Related

Play Framework 2.5 using JS file in index.scala.html

I'm currently attempting to refactor my repeated JavaScript code from my xyz.scala.html files into a separate main.js file, which can then be linked to using something like the below (from my scala.html files):
<script src='#routes.Assets.at("javascripts/main.js")'><script>
And using the below in my conf/routes file:
GET /js/*file controllers.Assets.at(path = "/public/javascripts", file)
Having Googled around I'm struggling to find a simple way of using JS from a file in my Play Framework application and setting up the conf/routes file.
Does anyone know a simple way of getting this to work?
Public assets folders
Record in the routes file
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
Script loading in twirl template
<script src="#routes.Assets.versioned("javascripts/hello.js")" type="text/javascript"></script>

Bundling individual files

I have a page in my MVC application with only one JavaScript file in it. Should I bundle this file or keep it as is?
My current code
#section scripts{
<script src="~/Scripts/Custom/Home/Index.js" type="text/javascript"></script>
}
I would still suggest you put that file through bundling, advantages you get:
It will get minified for production
Should you add more javascript files later, it will be just a matter of adding those to a bundle, without ever making changes to your HTML template

handlebar helper functions are not working

I am using handlebars in my application all the templates and their corresponding helperfunctions writing in .html file itself. Templates compilation happening inside my Backbone views so that means it's happening in .js file.
Before implement require.js,all my views instances are global that's why template compilation working fine but now I re-factor my views code into modules wise using require.js because of this my templates are not working while templates compilation time exceptions(Missing helper: 'setIndex') are coming. This is the way I written
index.html:
//loading library
<script type="text/javascript" src="lib/js/handlebars-v1.1.2.js"></script>
//helper function
<script>
Handlebars.registerHelper('setIndex', function(value){this.index = Number(value);});
</script>
//template
<script id="ftpBodyInitialTpl" type="text/x-handlebars-template">
{{#each bizSteps}}
{{setIndex #index}}
{{/each}}
</script>
.js file :
define(["handlebars"],function(Handlebars){
//templates compilation happening here.
});
I don't know, why it's showing Missing helper: 'setIndex' can anyone help me.
Thanks.
It looks like you are loading Handlebars without RequireJS:
<script type="text/javascript" src="lib/js/handlebars-v1.1.2.js"></script>
and then with RequireJS:
define(["handlebars"],function(Handlebars){
You did not mention a module loading error message so I'm assuming you correctly configured RequireJS to load it, and that RequireJS does load it. The problem is that you end up with two instance of Handlebars. The one loaded without RequireJS gets the setIndex helper. The one loaded with RequireJS does not. There are multiple solutions to this problem:
Load Handlebars without RequireJS and avoid loading it with RequireJS too. In this case, you'd just use the global Handlebars symbol that Handlebars exports. You don't list handlebars in the modules that your modules require.
Load Handlebars with RequireJS and avoid loading it without RequireJS. You'd have to remove the script tag that loads Handlebars and the helper would have to become an AMD module.
Load Handlebars without RequireJS and fake loading Handlebars in RequireJS. You could keep your code as it is now. You'd configure RequireJS like this:
paths: {
handlebars: "path/to/handlebars-fake.js"
}
And the handlebars-fake.js file would be:
define(function () {
return Handlebars;
});
So RequireJS would end up with the same instance of Handlebars as the one loaded with script.

Emberjs : Loading all template at once

So i have been wondering that if i write all my templates into a single file, will Ember load all these templates at once when the application is loaded?
Say, i have this in index.html
<! -- Added all dependecies of Ember -->
<script type="text/x-handlebars" >
This is application template
</script>
<script type="text/x-handlebars" id="about">
This is about template
</script>
And my application.js
App = Ember.Application.create();
App.Router.map(function(){
this.resouce('about');
});
So lets say i visits index.html so is the about template is already loaded at this time? ,i mean what i naturally assume is that it GET the index.html page and extracts handlebar templates from it so all the templates defined in index.html should be loaded when the application boots up. Is this right? , will diving different templates into different files will rectify this?
Yes all your templates will be available at boot time with the above mentioned way.
If you want to just separate the templates for development. Just separate the templates into different 'hbs' files and use a grunt precompiler task which will compile all the templates to a single js file which you can include in your index.html. Most ember apps just precompile and concatenate all the templates and js files.
If your thinking on lazy loading the template files, you may need to implement that mechanism yourself. Matthew Beale explains on lazy loading stuff in ember.
For application structure and organization, you should really look into ember-cli.

What's the difference between goog.require and goog.addDependency?

when I put goog.require in to a HTML file..
base.js file definitely write script tag like
<script type="text/javascript" src="{{STATIC-FILE}}closure-library/closure/goog/dom/dom.js"></script>
However, when I put a dependency file generated by depswriter.py..
it does not put any file required by other files.
so.. my question is..
what's the difference between goog.require and goog.addDependency?
can goog.addDependency replace goog.require? I mean, without any goog.require sentences, goog.addDependency can serve as goog.require?
please help me.. I spent more than 4 hours figuring out why the hell goog.addDependency does not incorporate dependency files into a HTML file and failed!!!..
goog.require:
Implements a system for the dynamic resolution of dependencies that works in parallel with the BUILD system.
goog.addDependency
Adds a dependency from a file to the files it requires.
You don't have to use goog.addDependency. It's only used by the dependency generator scripts. You need to put deps.js in the same directory than base.js. Then put a script tag for loading base.js in your head section, followed by a script tag with your requires. Like that:
<script src="../base.js"></script>
<script>
goog.require('goog.events.EventType');
goog.require('goog.ui.AdvancedTooltip');
</script>
Have a look at the Closure demo: http://closure-library.googlecode.com/svn/trunk/closure/goog/demos/index.html

Categories