Development and Debugging Tips

This section talks about some of the tools available to help develop JavaScript programs. With the increasing popularity ofJavaScript there surely will be alot of changes in this space in a relatively short time. In this section you will find helpful tools that may or may not be part of Dojo.

Also remember to check the Dojo FAQs especially the Common Pitfalls section.

Debugging JavaScript

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

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).

The easiest way to understand how it helps with debugging is to see it's effect within a debugger. For example within Visual Web Developer Express the image on the left is when using debugAtAllCosts and the RHS image is without debugAtAllCosts being used:

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

<div id="dojoDebug"></div> Author: Carla

JavaScript Editors

Editors/IDEs

ATF (Eclipse)

Ajax Toolkit Framework is an incubator project within the Eclipse Web Tools Project. It is also a pluggable framework for other AJAX tools. It provides Javascript syntax checking, server deployment, Mozilla embedding, runtime tools such as XHR Monitor, and a debugger based on Mozilla Spidermonkey, JSD, and the Eclipse debug UI. Eclipse integration provides access to existing plugins like ant, subclipse for SVN, server development tools, etc. AJAX "Personalities" provide the potential for tighter integration with Dojo and other toolkits, although so far very little has been done in this area.

There's visual Javascript validation built into ATF. It includes both basic syntax validation and optionally Jslint validation for less obvious potential syntax problems. It works just like MS Word as-you-type spellchecking and Eclipse as-you-type Java validation - as you type if you make a syntax error (or just do something somewhat sloppy) you'll get a red or yellow squiggly under the warning/error and an explanation in the margin. A background task will run validation against all files and place markers in the code such that you can see errors across a project.



You can download and use ATF and its prerequisite Eclipse components (Eclipse SDK, WTP, EMF, GEF, JEM, xulrunner) and choose to use all of ATF or just install the "javascript" feature which implements this validation.



Note - you have to fetch and manually install jslint.js, Dojo and xulrunner due to Eclipse policies - make sure to read the ATF readme to get the full functionality of ATF.

JSEclipse

JSEclipse is a commercial Eclipse plugin which provides a rich Javascript editor with support for syntax validation, code completion and Dojo idioms.

MyEclipseIDE

To be written...

JS-Sourceror (Eclipse)

JS-Sourceror performs syntax checking and variable type and flow analysis on JavaScript files.

JavaScript plugin for jEdit

See http://skrul.com/blog/projects/javascript

It also does syntax checking, as well as scope checking and structure browsing.

Aptana

Aptana is an open-source, JavaScript-focused IDE, including code assist for Dojo. It works as a stand-alone app on Mac, Linux, or Windows, or as a plug-in for Eclipse.

Profiling JavaScript

Profiling is the term for looking at where time is spent by any Javascript code. If you have a problem with code taking too long, then it helps to use a profiling tool to diagnose exactly where all the time is being used.

When using some profiling tools you may need to use debugAtAllCosts and not a packaged version of Dojo (see DebuggingJavascript). Using debugAtAllCosts will enable the profiling tool to allocate time spent per function to the correct source file -- otherwise you will end up with the elapsed times being allocated to anonymous functions which will make it difficult for you to understand!

Profiling Tools

dojo.profile

dojo.profile is a package that implements timing primitives for recording how much time is spent in particular functions. To learn how to use it, the best resource is to search the tests directory and look at how it is used by various tests.

FireBug 1.0

Displays the time it took to load each file.

Venkman (for Firefox)

Free but a bit buggy to use. I have found it easiest to get into debugging mode with Venkman by using a debugger keyword in your sourcecode. Run the Venkman debugger, then run your code and it will stop at the breakpoint.

Venkman contains a profiling tool, although the reports are a bit difficult to use. It does work.

Tito web studio

It seems it does not work with Dojo. It modifies JavaScript, and obviously in some manner incompatible with Dojo.

Manually do it yourself

Get the time at the start and end of a routine, and calculate the difference. Not a great technique, because you have to make educated guesses as to where the inefficient areas are, and it may take quite a lot of work to home in on the problem area.



But it is easy to do if you are measuring a single function:

function() {

var startTime = new Date();

// do something here

dojo.debug("Total time: " + (new Date() - startTime));

}



Or another example of code to do this is on this page near the top under the heading "Measure your changes".