Sunday, October 20, 2013

Smarter support for dojo in IntelliJ/WebStorm with Needs More Dojo 0.6

The next version of Needs More Dojo makes many enhancements to IntelliJ IDEA, WebStorm, etc. to provide better integration with Dojo. Personally, I've really enjoyed working on this version and can't wait to get it out the door!

1. this.inherited resolution

If you've ever used Navigate ... Declaration (Ctrl+B) to see the super method of a Dojo module, you would be greeted with this:
Basically: a lot of this.inherited references
It's not really the IDE's fault, as that would require knowledge of Dojo's custom OO model which of course it doesn't have. Luckily, Needs More Dojo does have that knowledge. Now when you use Ctrl+B, Needs More Dojo will navigate the dependency graph in your declare(...) block and search for methods that match. Here's what you get instead:
Much better!
2. Method resolution

After adding support for this.inherited resolution, it was easy to add method resolution as well. IntelliJ does a surprisingly good job of resolving methods in JavaScript, but there are still cases it will miss. For example, if you try to resolve domStyle.set(...) you will get this:

A very incorrect list of set methods
Once again, not really the IDE's fault. With Needs More Dojo, you won't get a list at all. Instead, you will navigate to the set method of dom-style.js.

3. AMD module resolution

This is one of my favorite new features. Let's say you have imported a module and you want to jump to its source file. By default, if you Ctrl+Click on query for example in this block of code: 

define([
    'dojo/query'
], function(query) {
    var results = query('.foo');
});

You will get directed to to the "query" parameter. Not very useful. With Needs More Dojo, it will resolve query.js and send you there. Of course this works for your modules as well, and relative or absolute path syntax.

4. Require blocks and embedded scripts

In this version, you have all AMD management functionality available for require blocks, nested or otherwise. In addition, you have all Needs More Dojo functionality available in embedded scripts in HTML, jsp, php, etc. files. You can configure the list of supported file types in the settings dialog.

Refactoring has been updated to take require blocks into account as well.

5. Quick fixes

Finally, there are several quick-fixes for existing functionality that are now available. For example, if you have an unused import, you get three quick-fixes listed:

As I said, this version has been very exciting to work on. There are some other new changes I didn't add here, but you can see the full list of things that were added on the GitHub issue page. 

I expect to spend a couple of weeks testing this version, so expect it to be released in 2-3 weeks.



Wednesday, September 18, 2013

Needs More Dojo 0.5.1: Cyclic Dependency Detection

So 0.5.1 is a "minor" release. This means that it should be mostly bug-fixes and some minor enhancements. Well in this release I decided to add a pretty big feature (it was a feature request actually). The feature in question is cyclic dependency detection.

In dojo, cyclic dependencies present a problem. If you have a cyclic dependency, one of the modules involved will be resolved to {}, an empty object. Oops. This is to prevent further recursion as the AMD loader goes down the dependency graph. Unfortunately this can lead to subtle bugs and can be difficult to track down. I remember struggling when I was first learning dojo and ran into this problem, luckily a colleague was able to describe the issue.

Anyway, in Needs More Dojo I've added the ability to scan for cyclic dependencies. So now you can run a scan on your project sources, and you get a tool window like this:

Scanning for cyclic dependencies.
All it's doing is navigating the dependency graph and checking for cycles. It also counts the number of times a particular module has been involved in a cycle and displays the count next to it. In my simple example, all of the modules listed appear once. However, if you had one module appearing more than another one, it's more likely the culprit causing the cycle.

This appears as an action in the code menu that you can run. I've also added an inspection that will run in the background and highlight modules that are involved in cyclic dependency graphs like this:

Cyclic dependencies flagged as errors
In this example, the inspection has detected a cyclic dependency and displays it as an error. You can also see that the dependency in question (ProjectData) is flagged as unused. So there's an unnecessary cycle in this project.

The inspection is disabled by default. I did this because I didn't want large projects getting performance hits, as the inspection has to build a graph of dependencies for each file.

Expect 0.5.1 to be released in a couple of weeks.

Saturday, September 14, 2013

Needs More Dojo v0.5: Refactoring Support

For the past couple of months I've been working on an IntelliJ IDEA plugin called Needs More Dojo. It's basically a plugin that makes IntelliJ/WebStorm/etc. aware of conventions and structure of dojo applications. I use dojo at my day job, so it started out of things I noticed could be improved.

I'm very excited about the newest version, 0.5, that was released about a week ago. Although you might not do major refactoring every day, it's painful when you have to do it. Sadly, IntelliJ does not handle dojo's AMD system very well and so when moving files you still have to manually update them.

So Needs More Dojo complements IntelliJ's features by being aware of the AMD system and your project's package structure. Due to this, it will successfully update your import statements with the correct locations. It's taken awhile to build up the code necessary to support refactoring, but I'm glad it's here now.

The next release will be a minor release (0.5.1). For this release I have a few minor enhancements planned so far based on some user feedback and my own roadmap. I'm going to try to space the releases out on a more defined interval instead of sporadic (0.5 took forever to be released for example).

If you have any feature suggestions, head over to the issues page on github and add them.

Saturday, January 19, 2013

JavaScript is not the problem

I've been reading about different new languages in the works that compile to JavaScript. Some examples: Microsoft's TypeScript, Google's Dart, CoffeeScript, etc. They all 'fix' issues in JavaScript that we all know and dislike. Stuff like the 'this' behavior, no block scope, and a lack of even optional static typing. 

I agree that there are plenty of things in JavaScript the language that are annoying and should be fixed. Now apparently everyone thinks that if we just fix JavaScript the web will be a better place.

I've spent the last seven months or so working on a web application. This particular application looks like it should be on the desktop. It is single-page, has a very traditional desktop layout, and can be safely identified as 'rich'.

Out of all the pain that has arisen while developing, the least of my pain comes from JavaScript. In fact, I enjoy using JavaScript and paid the price of learning its quirks and problems. There was an initial learning curve yes, but I'm comfortable with it and can avoid its flaws.

My real problem is not with JavaScript, and I don't think the solution to turning the browser into a 'real' application platform is fixing JavaScript. 99% of my painful, time-consuming tasks are from the DOM (and to an extent, browser inconsistencies).

The DOM is just awful. It's not meant for applications that you would normally write natively (if it wasn't for that good ol' write once, run anywhere). I've been working with the Dojo Toolkit, and it's been a fairly positive experience. This particular framework solves a lot of issues cited with JavaScript, such as the lack of modules and traditional class-based inheritance.

However, my time is spent figuring out how to get my tab containers to fit their content, or resize in a modal dialog, or render charts correctly, or making sure text fields look ok when they're localized, whatever.  Some of these are component issues, but the underlying issue is that the DOM is terrible for real applications. It's not built for components, it's built for documents like the name suggests.

The browser environment in general sucks. Why can't I show the print preview dialog instead of jumping straight to the print dialog? Memory leaks due to the abstraction of the DOM. CSS file limits in IE. Trying to copy something to the clipboard. No, the browser was not designed for this. I understand that, but there are no good alternatives. Flash has its own problems, no other plugins have taken off (Silverlight? Java applets? Ha!). Going native is looking more attractive.

It's not a fun experience, and none of these issues are solved by sticking another language on top of JavaScript.