Version 38, changed by carlavmott 02/02/2007. Show version history
There are excellent tools to help write and debug Javascript - it isn't all about liberally using alert() any more!
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).
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.
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.
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.
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 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>
<!--
you MUST close the script tag here in order to use debugAtAllCosts
-->
<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
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.
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!).
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.
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.
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 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.
You can debug the old fashioned way (print statements in the code). There are three functions for this:
Debugging output:
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
<div id="dojoDebug"></div>