- The Book of Dojo
- The Dojo Book, 0.4
- Part 1: "Introduction"
- Part 2: "Out of the Box" Dojo
- Part 3: "The Dojo Programming Model"
- Part 4: "More on Widgets"
- Part 5: "Connecting the pieces"
- Part 6: "Customizing Dojo Builds for Better Performance"
- Part 7: "Utilities"
- Part 8: "Internationalization and Accessiblity"
- Part 9: "Dojo Community"
- Part 10: "Fresh From The Shed" Dojo
- BookWriting
- Glossary
Debugging JavaScript
Submitted by criecke on Fri, 02/02/2007 - 22:19.
There are excellent tools to help write and debug Javascript - it isn't all about liberally using alert() any
more!
IDEs
IDEs are available which support a wide range of web development activity, including editing Javascript and HTML files, deploying code to servers, and integration with existing features like source control. In addition, some include runtime tools and browser integration to assist in debugging (for example, myeclipse and ATF)
If you use one of the JavaScriptEditors that checks your syntax as you enter your code, you can be warned immediately of simple errors and save yourself a lot of time. Some Eclipse plugins even specifically support Dojo idioms by giving you tooltips for common Dojo functions and doing more complex analysis for errors (not just normal syntax checking).
Browser specific tools
Mozilla/Firefox
- The Web Developer Toolbar is brilliant.
- The Firebug extension is a must for debugging and inspecting html pages - dojo.debug can also be configured to output directly to Firebug's console. It contains a simple Javascript debugger too. just use dojo.require("dojo.debug.Firebug") in your pages.
- Venkman is the mozilla javascript debugger - ugly and cantankerous, but it can be useful if you need to debug in FF. Note that in general the IE debugger is much better. Use the venkman port for FF1.5.
- Live HTTP Headers is a good extension for debugging HTTP traffic (You may prefer to use the equivalent functionality that exists in the in Firebug extension).
- JavaScript Shell - While it's not a debugger, I've found the JavaScript Shell to be a really great tool for analyzing problems, and even just exploring JavaScript libraries like dojo. Works best as a firefox bookmarklet, in which case you can open it in the context of any given page and invoke javascript functions yourself, evaluate expressions, redefine functions, etc.
Debugging on Firefox may need you to use the djConfig flag debugAtAllCosts (see further below for information). The debugAtAllCosts flag is sometimes necessary to locate exceptions or syntax errors. Even without the debugger, Mozilla and Firefox are unable to locate a line of code loaded by dojo.require() due to a flaw in the way eval() debugging hooks are implemented in Spidermonkey. Currently, the Javascript console will report all source references as the location of the eval() call itself (in the bootstrap code), but with an additional line offset equal to the offset in the corresponding *.js file.
Firefox Safe Mode
If you are having wierd problems with Firefox, it is often worthwhile running Firefox in safe mode.
This is because installed extensions can interfere with the DOM tree, CSS, or even with javascript. In Windows there is a shortcut to start Firefox in safe mode from within the Mozilla Firefox folder, from the Start button.
Internet Explorer
- Microsoft Script Editor – very stable, part of MS Office web scripting add ons.
- Visual Web Developer Express is free.
- Visual Studio .NET has a built in Javascript debugger if you have Visual Studio.
- Microsoft Script Debugger a piece of crap compared with MSE.
- IE DOM Inspector is awesome (commercial product with 15 day free trial)
- IE Developer Toolbar is super useful (free from Microsoft)
- DOMSpy is ok
- IE DocMon is pretty good
If you are using a debugger with IE, go to Tools | Options | Advanced and make sure that Disable Script Debugging is not ticked. Using debugAtAllCosts can also help significantly - read about it below.
Safari
The debugger is Drosera.The Safari Developer FAQ has some general information about developing with Safari, as well as instructions on how to turn on a debug menu that allows showing a Javascript console.
There is a "dom inspector" type tool, but it requires using a nightly build of Safari.
debugAtAllCosts
debugAtAllCosts may have unobvious side-effects - you should only use it if you are actually debugging. If you hit problems with files not loading or __package__.js then check that you are using writeIncludes() correctly, and try removing this flag to ensure that the flag is not the issue.
You generally should not use a packaged build if you want to
debug, because in a packaged build the majority of code will end up in your dojo.js file
(and usually be obfuscated due to compression).
To use it needs one more line in your page. Here's how you might use it:
<script>
djConfig = {
isDebug: true,
debugAtAllCosts: true
};
</script>
<script src="/path/to/dojo/dojo.js" />
<script>
// dojo includes here
dojo.require("dojo.myModule");
dojo.hostenv.writeIncludes(); // this is a new line
</script>
// ...
Once you've structured your code this way, if you open up your debugger, you will see all the constituent files listed and you can then set breakpoints. You may need to add in dojo.require() statements for files that you want the files to show, above the writeIncludes(). If you do not, then any javascript files that need loading after the call to writeIncludes().
You
can see an example of using debugAtAllCosts with your own widgets
within your own namespace in
dojo/src/tests/widget/test_Custom_Widget_Debugging.html
How does debugAtAllCosts work?
When debugAtAllCosts is set to true, then dojo.require() does not actually include the package at that point. It only gets included in the page once you call dojo.hostenv.writeIncludes().
Normally when you dojo.require() a file that is not already loaded, it is fetched using using an xmlhttprequest, and loaded into your Javascript runtime environment using an eval() statement (each of the eval items in the RHS screenshot above is actually a js file). When the file is eval()'ed, dojo.require() calls will occur, and those then recursively load any further dependencies (those which are not already loaded).
When you set debugAtAllCosts to true, the file is still fetched using xmlhttprequest but it is not eval()'ed. Instead a regexp is used to find the dojo.require() dependencies, and required files may be fetched and searched recursively for dependencies. Each of the required javascript filenames is added into a list of pending files that need to be loaded (the list is in order so that dependent files are loaded in the correct order). When you then call dojo.writeIncludes(), inside the head of the document script tags are appended with src attributes set to the js files that need to be loaded. The script tags cause the files to be loaded by the browser: files loaded this way are understood by debuggers much better than when the files are eval()'ed.
What alternatives are there to debugAtAllCosts?
If you just need to debug one or two known files, then you can just include those specific files using script tags after dojo.js. e.g.
<script src="/dojo.js" type="text/javascript"></script>
<script src="/mine/myWidget.js" type="text/javascript"></script>
You cannot do this for files that are packaged into your
dojo.js (Of course, using packaged files makes debugging hard in other
ways too!).
Profiling
Javascript is slow and you want to speed it up?
Use a ProfilingJavascript tool to help you find the functions where all the time is spent, and optimise those routines.
Traffic analysis
A great many problems can be resolved by watching the traffic between the browser and the server. If you are having any problems with Ajax calls such as bind() or with js/html/css/jpg files not loading as you would expect, this is often the best way to diagnose them quickly. Also if you are having problems with required files not loading then this is a good starting point to find out why.
- Fiddler is a fantastic HTTP header and content inspector for Windows. It understands HTTP and presents the information very clearly (once you get used to its slightly quirky interface). Well integrated with IE, but work s with any browser. With FF a useful extension to help use Fiddler is the Switch Proxy extension (scroll down that page to find it).
- Ethereal is great for sniffing all kinds of network traffic.
How do I debug syntax errors? aka How can I find this syntax error in bootstrap?
Sometimes Dojo's error messages about syntax errors are really cryptic due to how dojo loads files via dojo.require(), however you can get a better message by simply directly including the js file with the [script] tag.
The debugAtAllCosts flag can also be used.
There's also a lint program that Brian has recommended.
You can also find the debug error message in the dojo source code and remove the corresponding try/catch statement so that when the error occurs you get a debugger breakpoint instead of a dojo debug message.
Javascript debugger statement
Javascript has a debugger keyword that forces a breakpoint to occur. Just insert debugger; and if you have a debugger for your browser, then it will stop at the debugger keyword.
This is especially useful when using Venkman, because otherwise it can be difficult to get Venkman into debugging mode (e.g. you try to click on a line of source and it puts in a [F] future breakpoint).
It also works with the Firebug extension for Firefox.
Debug Messages
You can debug the old fashioned way (print statements in the code). There are three functions for this:
- dojo.debug - prints a message
- dojo.debugShallow - prints all the members in an object
- dojo.debugDeep - opens new window w/tree showing structure of an object
Debugging output:
- FireBug object - this will print debugging output to the Firebug console
- DebugConsole - will capture all your debug messages in a floating pane.
Alternately, in djConfig, you can specify which element they are appended to by
providing an id of that element: i.e.:
var djConfig = {
isDebug: true,
debugContainerId : "dojoDebug"
};
and have a div
