Using Django Pipeline, why am I running into JS errors? - javascript

I've configured Django Pipeline (verison 1.3.15) for a single group of JS files. I've configured them in the same order that they appear in my page normally. Everything works fine with collectstatic, etc. When I view the source, everything appears to have been correctly crammed into 1 monolithic JS file, but when I load the page, things are wrong. The jQuery plugins I've included (which worked fine before) aren't attached to jQuery (verified via Firebug) (jQuery is passed to a closure for my plugins, not by $, so it's not a noConflict() issue). Is there a known issue with Pipeline that I somehow have overlooked, where you can't include multiple JavaScript files together under some circumstances, due to the way they're compressed (Note: I'm using the JSMin compressor)?.

The problem has most likely nothing to do with the pipeline but with js syntax of your js files. Consider the following scenario:
// file1.js
var foo='bar'
and
// file2.js
var cat='dog'
When both of the files are separate the browser has no issue processing the js since it automatically can figure out the end of each expression however when you combine and minify the two files you get something like:
//combined.js
var foo='bar' var cat='dog'
The above is clearly a syntax error. So most likely something similar is happening in your case. To solve this make sure that all of the files have absolutely valid js syntax (which is most cases are just missing semicolons).

Related

Grouping js files returns a strange js error

I have a website, which uses different javascript plugins, and a bunch of js files to run (~30). I wanted to try to group these js files into a single file, and tried to apply a basic minification to it(only removing whitespaces) using Google's Closure Compiler.
I've introduced all of the js files, in the same order as they are included in my page to the Closure Compilers online version, and run the compilation. The parameters for the compilation looked like this:
// ==ClosureCompiler==
// #output_file_name default.js
// #compilation_level WHITESPACE_ONLY
// .... bunch of javascript files here
// ==/ClosureCompiler==
The compilation ran with success, there were neither warnings nor errors. I then fetched the result file, copied it to my server, and tried to include it to my page.
The page runs, but a strange error appears, which stops my javascript in the middle of it's operation:
TypeError: event.feature.values_ is undefined
I've tried to fetch the space where this error is happening, the code there looks something like this:
this.vectorLayer.getSource().on("addfeature",function(event){if(typeof event.feature.values_.type=="undefined")return;
This is something which my own javascript code is doing, but this part of the code shouldn't even run when the page is loading. When I use the separate javascript files, the page loads just greatly, without any errors, but with the white-space removed, and the files combined, this error appears.
With basic logic, I tought that by adding together the .js files in the same order in which they are included on my page, and only removing the white-spaces to get a smaller file size shouldn't result in any errors, as the browser loads the js files in synchronously anyways. Am I mistaken in this regard? If not, what could the possible reason for this error be?
EDIT 1:
Okay, so I narrowed down the problem to a single .js file, the javascript file of OpenLayers. If I do not compile that file, and include it separatly, everything works fine. What could be causing this strange problem?
As it turns out, this was caused by a strange caching mechanism on Google's side. Restarting the Closure Compiler, and reintroducing all the js files once again, then recompiling it, solved my problem.
Thanks for the comments guys!

Grails - Redeploy after javascript change

Recently I added conf/ApplicationResources.groovy (using resources plugin) file to my project structure. Here I keep my modules definitions for javascript and css libraries. Before, I was importing libraries with classic g:javascript tag.
Now every time when javascript code changes (while server is running) I get client side js error saying
"Uncaught SyntaxError: Unexpected end of input".
So for each javascript change application needs to be redeployed, what I dont want.
I have also declared .js files to be excluded from resources plugin pattern, but the problem remains. Any advice/help will be appreciated.
Solution from Sérgio Michels that worked:
Add to Config.groovy: "grails.resources.debug = true;"
To avoid cache issues with the Resources plugin, in all my projects I'm using the config grails.resources.debug = true in Config.groovy.
You still use <r:require modules=""/> in your GSP, but in development mode the source will show all files included instead of merging them.

Organizing javascript in Rails app

I have several javascript (coffee script) files in my Rails javascripts directory. The code is logically divided into different files. However, each file starts with $(document).ready -> and some files share common helper functions.
What is the best way to factor out the helper functions? Should I just put them all in some other file that gets included earlier in application.js?
Also, is it normal to have the code divided up the way mine is, where every page does $(document).ready ->? Doesn't this mean that all of my code is called on every page, regardless of whether or not it is relevant? Are there alternatives to this organization?
I'm not sure if this question is specific to Rails or relevant to javascript and jQuery in general.
I do think this is a Rails question, and a good one.
The normal paradigm in Rails, where "global" stuff goes in application.* is a little messed up with the asset pipeline, since the application.js really acts as a manifest, rather than a common file. Of course you could add stuff there, or even create an application.js.coffee for your common code. I decided to create a file called common.js.coffee (and in another case shared.js.coffee), which in my case was automatically handled by the require_tree . directive.
(Update based on comment from #jonathan-tran) In some cases, you may just want methods called on document ready for all pages -- for example, I used this to make a datepicker available to any field in any view. If, instead you want methods (actually global functions) available to be callable, you'll need to export the coffeescript functions to variables, for example by attaching to the window object. You can do both in a shared file.
It is true that if you use generators you'll end up with files for every controller which, if there's no specialized code result in a series of redundant $(document).ready -> statements when assets are compiled. So just get rid of the ones you don't use. But following the pattern of separating functionality specific to a page makes good sense to me and works well -- I know where to look to find stuff and that's worth a lot as a project grows.
And another rule I have learned with Rails: go with the flow. If that's how Rails does it, it's probably a good way. They do indeed think about these things. Don't fix what works :-)

how to avoid generation document.write in GWT cache.js file

I am using Gwt 2.4. After compiling my project i am getting some document.write lines in the mymodle.chache.js which is most weired .
So i want to know the places which producing these lines in my GWT code and came across and found some lines of code like
element.setInnerHtml("blah ..blah..");
and
doc.write("blah..blah ..");
So i removed those line of code and compiled again again and still getting some (ex:document.write(df+er+t)) lines .
Anyone suggest a way to find the cause to producing those lines from my GWT ??
(assuming you're talking about the *.nocache.js file rather than the *.cache.* files, as *.cache.* don't contain calls to document.write, unless you're using a crappy third-party lib)
The *.nocache.js file is generated by the primary linker, so its content is independent from your code. It contains calls to document.write() for various things: determine your module base URL (as a last resort, when it cannot infer it from elsewhere), inject scripts and stylesheets referenced from your *.gwt.xml files, and finally inject the GWT application code itself (with the standard linker, this will be an <iframe>, with the newer xsiframe linker it'll be a <script>).
If you're really worried about it, it can be customized quite easily by extending the CrossSiteIframeLinker (xsiframe linker) and providing different code snippets.
Tip: compile with -style PRETTY to make the generated code readable.
You are not supposed to hand-edit/modify mymodle.cache.js. This file gets generated again from GWT Compiler. What issue are you trying to solve by hand-editing it?

Issue with concatenating a few javascript files

This is a complete noob question, but I gotta ask it anyway
I started playing with backbone.js a few days ago and I was really fascinated. As I got over the "ToDo", I started working on a project of my own. Coming from the world of Java, I prefer keeping everything in as many separate files as possible. Therefore, I split my models views, and routers into separate files, into separate folders.
The problem came when I tried to combine those fiels into one single applciation.js file. Again, coming from the Java world, I love when I can automate stuff, and even more, when I can use familiar tools like ant, to setup build processes for my javascript projects.
I got a sample ant build template which concatenates and minifies all the files in an arbitrary order. When it finished, I tried to run my JS app, and not surprisingly, it failed with a bunch of errors. Many of my models and views try to extend each other, others depende on them as components. If they are not defined in a proper order, the app just reaches a point where it is trying to execute extend of an undefined
I know from before that for JavaScript the order is very important, but somehow I was left with the impression that if all the scripts are in one single file, the JS parser will load all the stuff first and then will try to execute whatever is to be executed. Well, my assumption was wrong.
It is possible to list all the files in the specific order I want them, but do I really need to go for such a primitive step? Unfortunately after spending a few hours researching, I couldn't find anything better.
Is it really possible to concatenate JS files, which depend on each other, in an arbitrary order, without them clashing? I guess, the biggest problem is the fact that the extend function is actually being called, rather than each script simply defining and object literal
So, what's the solution?
UPDATE: I just saw that Sproutcore has its own builder. If SC is roughly similar to BB, in the way one creates and extends entities, how does the SC builder work without clashing?
There are many ways to do this, but here's my recipe. I prefix my development files with a number, starting from the one with no dependencies (base "classes", models that will be depended upon from other models, then views using these models, then routers calling those views, etc.).
Then I use uglify-js (available as a node.js library, that you install using npm install uglify-js) to minify all my js in one file (don't know from your question if you use node.js server-side, though). Then I cat *.js | uglifyjs -o min/myfile.min.js. This will send the content of all my .js files (respecting the order of dependencies because of my prefix) to uglify, which will minify it and save it to a single file.
Since I, too, like automation, I have this set up in a Makefile, though I guess it could be done using Ant (not too familiar with it). The relevant part of the Makefile look like this:
TARGET_MIN_FILE = public/js/min/myfile.min.js
JS = $(shell echo public/js/*.js)
public/js/min/myfile.min.js: $(JS)
cat $(JS) | uglifyjs -o $(TARGET_MIN_FILE)
clean:
rm -f $(TARGET_MIN_FILE)
.PHONY: clean
On the other hand, if you go for the asynchronous module definition (AMD) format, you can require() your modules and it will manage for you the dependency loading in the correct order (see Require.js for more info), as mentioned by TheShelfishMeme.
Your "assumption" is only true for var statements and functions of the form function name(a,b) {}. Those two get hoisted to the top of the script (or function block they are in) and are evaluated first.
If your files depend on other files being loaded first, it stands to reason that when you concatenate them they must be in that order in the final file.
Have a look at requirejs. It takes some time to set up but it should help you with your problem.
This article should help with the implementation.

Categories