Liferay 6.2. tries to use best practices and JS minification is one of them.
But what do you do when your unminified JavaScript works and minification produces errors like this (in Tomcat console):
12:23:48,794 ERROR [http-bio-8080-exec-10][MinifierUtil:111] 607: 21: identifier is a reserved word
12:23:48,797 ERROR [http-bio-8080-exec-10][MinifierUtil:111] 608: 45: identifier is a reserved word
12:23:48,802 ERROR [http-bio-8080-exec-10][MinifierUtil:111] 1: 0: Compilation produced 2 syntax errors.
12:23:48,805 ERROR [http-bio-8080-exec-10][MinifierUtil:88] JavaScript Minifier failed for_________ AUI().use('node', 'aui-base', 'aui-io-request', 'aui
[MinifierUtil:111] 607: 21: and [MinifierUtil:111] 608: 45: are not line numbers in your code (jsp/ftl/...) as man expects from console log and googling "identifier is a reserved word" or "JavaScript Minifier failed for_________" helped me almost nothing (ok, I knew about https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords normally).
Pasting code between <script> and </script> to JS lint or hint or any other JS tool is not an option as it contains many JAVA and spring/freemarker/liferay tags etc...
So - my question is - as I wasn't able to find best practices / methodologies for debugging this - what is your opinion (or even better - experience :)) ?
Well, you solved the problem in another way - just some pointers should you (or someone else) run into this issue again:
Minifier reports Line number and Offset in these error messages, but they're related to the content that the minifier sees - e.g. not in your JSP, FTL or other file, but in whatever gets passed to the minifier.
The way to read the minifier log is:
Line 607, column 21 as well as Line 608, column 45 have a problem
In the following line, you see JavaScript Minifier failed for_________ AUI().use('node', 'aui-base', 'aui-io-request', 'aui which is the first part of the content that the minifier sees - locating this code, you might be able to identify which content gets passed to the minifier and count down the lines (well, jump down 607 lines from there)
Side issues: Agreeing with #Origineil that the startup time rather points to another issue that you have - it shouldn't be that much unless you deliberately have processes running at startup. E.g. if you're running a cluster and each machine keeps its own lucene index, you must reindex at startup. If you want to work around that, two indexes might not be what you're after. But it's only an example, and you didn't ask for this. I just wanted to add some pointers. I assume that you have tuned your JVM memory settings already and are not running with the default bundle's settings?
I finally managed to solve the problem by:
copying the rendered (and unminified(!)) code between <script> and </script> and
paste it to JShint/lint/online minifier and re-check it there,
but I still wonder if there is some better way... (changing server properties from developer to production and back means restarting server few times at least and that takes about 300 seconds (only for restart) on my new(!) i7 vPro 64GB, SSD HDD workstation, so I try to avoid it as much as I can :)).
BTW: unminified code had some "deprecated" but simple ECMA methods that worked normally in JSFiddle and all latest browsers on my Win8.1...
Related
Is there a way to tell a page/project this it should ignore some javascript code/file? I am working on a project, that works well on all browsers, eccept IE8. I haven't tested for less than IE8, and I wont bother. Anyway. The error that I am getting is my language, but I'll translate to English.
Exception was thrown at line 4, column 12204 in https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js
0x800a01b6 - A javascript runtime error occured: The object doesn't support the property or method 'getElementsByClassName'
If there is a handler for this exception, the program may be safely continued
This is just one of MANY errors like that.
And many more.
This is a huge problem for me. Is there any workaround for this? I am forced to keep this file, since the project is big, and other pages depend on this file
You could try replacing this line...
getElementsByClassName("classname")
with...
$(".classname")
I want to know how to access JavaScript execution trace at runtime. I saw Firebug can do something like this:
Refer to the image above, all the line numbers executed are highlighted in green. They are achieved at runtime. I guess there must be some way to access those info from the JavaScript engine used by the browser.
Say now I want to build a firebug plugin to access those info and examine all the variables in each executed line at the runtime, how should I start?
Obviously you asked the same question in the Firebug forum.
To duplicate Honza's answer:
Firebug is currently using JSD (jsdIDebuggerService) to figure out,
which line is executable. However, the plan is to switch to JSD2 (work
in progress) https://wiki.mozilla.org/Debugger
You should also base your extension on JSD2
Look for getLineOffsets(line) and getOffsetLine(offset) in the
Debugger document. I didn't test it, but I think that if getLineOffset
returns null, the line is not executable.
Sebastian
I'm testing out a website that runs fine on Firefox (Win/Mac), Chrome (Win/Mac) and Safari. I'm having difficulty with Internet Explorer unfortunately. I get the following error message:
SCRIPT65535: Unexpected call to method or property access.
raphael-min.js, line 8 character 64961
I've taken a look at the debug output which looks like just takes me to a part of the Raphel library:
c=a.getScreenCTM()||a.createSVGMatrix()
I've searched for this error message online, but I don't understand what solution is relevant to this case as I've no idea what is causing the problem. I am also using the jQuery library. Are there any tests that I can do that can give me more information about the source of the problem?
I just found how to patch this, in order to keep the compressed version of Raphael.
Replace (don't forget the coma):
c=a.getScreenCTM()||a.createSVGMatrix(),
By that (dont't forget the end space):
c;try{c=a.getScreenCTM()||a.createSVGMatrix()}catch(e){c=a.createSVGMatrix()};var
Works fine ! :)
Means :
c; : declaration of variable c, and stop the first instruction.
try{c=a.getScreenCTM()||a.createSVGMatrix()}catch(e){c=a.createSVGMatrix()}; : our instruction, surrounded by a try/catch, to avoid IE error
var + a space : (don't forget the space!) allow us to continue to declare variable
I found out that it's an issue with compression (of the js file). I had the exact same issue and I had been searching for a solution. Guess what? I tried it with the uncompressed Raphael file and voila! No more issues. Compressed file needs a tweak, it seems.
Where I work, all our JavaScript is run through a compiler before it's deployed for production release. One of the things this JavaScript compiler does (beside do things like minify), is look for lines of code that appear like this, and strip them out of the release versions of our JavaScript:
//#debug
alert("this line of code will not make it into the release build")
//#/debug
I haven't look around much but I have yet to see this //#debug directive used in any of our JavaScript.
What is it's possible usefulness? I fail to see why this could ever be a good idea and think #debug directives (whether in a language like C# or JavaScript) are generally a sign of bad programming.
Was that just a waste of time adding the functionality for //#debug or what?
If you were using a big JavaScript library like YUI that has a logger in it, it could only log debug messages when in debug mode, for performance.
Since it is a proprietary solution, we can only guess the reasons. A lot of browsers provide a console object to log various types of messages such as debug, error, etc.
You could write a custom console object is always disabled in production mode. However, the log statements will still be present, but just in a disabled state.
By having the source go though a compiler such as yours, these statements can be stripped out which will reduce the byte size of the final output.
Think of it as being equivalent to something like this:
// in a header somewhere...
// debug is off by default unless turned on at compile time
#ifndef DEBUG
#define DEBUG 0
#endif
// in your code...
var response = getSomeData({foo:1, bar:2});
#if DEBUG
console.log(response);
#endif
doStuffWith(response);
This kind of thing is perfectly acceptable in compiled languages, so why not in (preprocessed) javascript?
I think it was useful (perhaps extremely useful) back a few years, and was probably the easiest way for a majority of developers to know what was going on in their JavaScript. That was because IDE's and other tools either weren't mature enough or as widespread in their use.
I work primarily in the Microsoft stack (so I am not as familiar with other environments), but with tools like VS2008/VS2010, Fiddler and IE8's (ugh! - years behind FF) dev tools and FF tools like firebug/hammerhead/yslow/etc., peppering alerts in your JavaScript isn't really necessary anymore for debugging. (There's probably a few instances where it's useful - but not nearly as much now.) Able to step through JavaScript, inspect requests/responses, and modify on the fly really makes debugging alert statements almost obsolete.
So, the //#debug was useful - probably not so much now.
I've used following self-made stuf:
// Uncomment to enable debug messages
// var debug = true;
function ShowDebugMessage(message) {
if (debug) {
alert(message);
}
}
So when you've declared variable debug which is set to true - all ShowDebugMessage() calls would call alert() as well. So just use it in a code and forget about in place conditions like ifdef or manual commenting of the debug output lines.
For custom projects without any specific overridden console.
I would recommend using: https://github.com/sunnykgupta/jsLogger , it is authored by me.
Features:
It safely overrides the console.log. Takes care if the console is not available (oh yes, you need to factor that too.)
Stores all logs (even if they are suppressed) for later retrieval.
Handles major console functions like log, warn, error, info.
Is open for modifications and will be updated whenever new suggestions come up.
I'm having problems with getting decent JavaScript error invormation in a Production environment.
When I'm developing I can just attach a debugger and (usually) fix the problem.
When I get the same error in a production environment however at best I see is an error report that looks like this:
Error: Object doesn't support this property or method
Url: SomePage
Line: 42
Char: 13
Which doesn't help me very much - I can't see the rendered page and so I have no idea what line 42 looks like.
Is there any way for me to log the entire rendered page contents whenever an error like this occurs? (So line 42 of the output is the line where the error occured)
While I'm at it, are there any other techniques that I can use to help with getting useful error information from JavaScript (without need to break into the debugger) - failing that is there any way that I can structure my JavaScript slightly differently to help getting decent debug information?
I'm predominantly interested in IE - this is the browser that tends to cause me most problems.
I don't think you'll be able to get the exact original HTML source of the page back in all pages and all browsers.
Regarding debugging, you could use a logging library such as log4javascript (disclaimer: I wrote it) and intersperse logging calls in your code. log4javascript enables you to send logging messages back to the server via Ajax.
Unfortunately, IE has by default the most utterly useless error reporting. The script and line number reported in the error are essentially guaranteed to be absolutely wrong. You can, however, install the IE developer tool bar (for IE7 and older, it's built into IE8) from Microsoft, which can help track down the error source.