17 May 2013 — San Francisco
Yesterday, Google organized an invite-only summit for mobile web and tools developers. As an engineer working on Firefox Developer Tools, I was invited to be on a panel about mobile testing and tooling. This is my attempt to write down my answers in hope they’ll be useful for someone out there. I suggest reading them as separate, individual mini essays.
Read it on Medium
22 February 2013 — San Francisco
A couple of months we landed the integrated JavaScript profiler. Since then we have received some good feedback and made lots of improvements. One upgrade is the ability to profile remote devices using your desktop version of Firefox. This feature is a part of our bigger effort to make sure that developers have the same high quality tools when developing mobile web apps as well as their desktop counterparts.
To enable remote profiling, first thing you’ll need to do is open about:config, set devtools.debugger.remote-enabled variable to true and restart your browser:
After you’ve done that, go to Tools -> Web Developer -> Connect and connect to your remote device[1]:
Once you’re successfully connected you’ll see a list of available tabs. Clicking on any of them will open a separate Developer Tools window with a profiler attached to that remote instance. That’s it!
So if you’re a B2G or Firefox for Android developer, give our profiler a try and share your feedback! Because everytime you share your feedback with us somewhere in the world two Mozillians high five each other and hug a kitten.
[1] — Here are a couple of links on how to setup your device for remote debugging and profiling: Setting up to debug on Firefox OS using Firefox developer tools, Remote debugging.
17 December 2012 — San Francisco
As I said yesterday on Twitter, we shipped a profiler for Firefox DevTools. Here’s how it looks like:
Firefox released its built-in profiler (codename SPS) in version 16. However, to use it you had to install a special addon—developed by Benoit Girard—that exposed a visual interface for the profiler. And now we took that UI and integrated it into our new and shiny DevTools Toolbox.
Of course, this is a very early release. We already have a few bugs on file and I expect to see more of them coming. We will also be adding new features to help people make their websites and applications faster. But, in my personal opinion, everything is much better when you iterate based on user feedback. So please download the latest Nightly, try the profiler out and tell us what you think!
P.S. One common question is about the black-to-red gradient in the UI. Since we’re still working on our docs I’ll answer here: it’s red when we stop processing any events—meaning that the browser won’t be responding to user input and animations won’t be as smooth. So it’s a bad thing.
12 November 2012 — San Francisco
I’m working on refactoring the JSHint source code these days by splitting the main file into independent pieces, improving data structures and so on. And since JSHint was born as a fork of JSLint it has the original author’s signature all over its code. For example, one thing that I’m trying to fix is the fact that we have lots of one- and two- letter variables that can appear anywhere in the file with over 7K lines of code.
Fortunately, JSHint has been invaluable to me since it shows all the spots where I forgot to rename a variable or replace a global function call with a method. Now, I use JSHint strictly from command-line. [1] It works fine except for the part where you get 50+ warnings and then have to either pipe it into your editor or scroll up and down the terminal trying to keep track of all the warnings you have already fixed.
So earlier today I wrote a little JavaScript program that allows me to use JSHint interactively, independent of whatever editor I’m using. I call it jshint-i:
$ npm install jshint-i -g
...
$ jshint-i myfile.js --config=myconfig.json
With it, I can easily step through all the warnings generated by JSHint, and be more aware of which ones I’ve fixed (or intentionally skipped). Right now it is pretty basic but I plan to add more stuff to it over time—for example it would be really nice to fix trivial mistakes (like missing semicolons) without going back to the editor, just by invoking another jshint-i command. But that’s a task for another day.
And, of course, keep in mind that jshint-i is not a general purpose tool. This is something I made to help me with my personal workflow. But maybe you’ll find it useful as well.
[1] I know that nowadays most editors have plugins that add JSHint support to them. But I’m not really into plugins, that’s just how I work. (And before you call me crazy let me tell you that I’m also not into syntax highlighting. Now you can call me crazy.)
3 November 2012 — San Francisco
Earlier today, I decided to fix a small JSHint issue that’d been bothering me for quite some time. You can see the issue in this snippet, where I’ve commented out all of JSHint’s error detection code and left just the shell that wraps that:
try {
advance();
/* Almost complete JSHint parsing logic */
} catch (err) {
if (err) {
var nt = state.tokens.next || {};
JSHINT.errors.push({
scope : "(main)",
raw : err.raw,
reason : err.message,
line : err.line || nt.line,
character : err.character || nt.from
}, null);
}
}
As you can see, JSHint (and JSLint for that matter) is almost entirely wrapped in one giant try/catch block. All errors go directly to the JSHINT.errors array without ever propagating to the outer scope. This behavior bit me a few times before so I finally decided to change the catch block:
try {
advance();
/* Almost complete JSHint parsing logic */
} catch (err) {
if (err && err.name === "JSHintError") {
var nt = state.tokens.next || {};
JSHINT.errors.push({
scope : "(main)",
raw : err.raw,
reason : err.message,
line : err.line || nt.line,
character : err.character || nt.from
}, null);
} else {
throw err;
}
}
Boom! This seemingly minor change suddenly opened a pretty big box full of nasty worms. Because, apparently, some parts of JSHint/JSLint work only if they blow up in the middle of execution. Consider the following code:
prefix("!", function () {
this.right = expression(150);
this.arity = "unary";
if (bang[this.right.id] === true) {
warning("W018", this, "!");
}
return this;
});
What happens when our input is a string with only one character ”!” in it? In this case, a call to expression returns undefined and the line with this.right.id blows up. The catch block I demonstrated above catches that exception, puts it into the JSHINT.errors array and halts execution. And since this exception didn’t have all required fields (like err.raw) the method responsible for generating reports will simply ignore it. In the end, this means that JSHint will appear to be working as expected.
This is horrible. Not only does it make debugging extremely annoying, it also makes sure that our tests don’t catch all corner cases.
So I changed this instance and a few others to explicitly check whether there are more tokens in the input stream and if there are none, give up and quit. But now I can’t really ship JSHint like this because, even though our test coverage is pretty good, I can’t guarantee that it won’t blow up somewhere else. This means I will have to ship it with a switch:
// Propagate exceptions, but only in debug mode.
if (debugMode) {
throw err;
}
The moral of this story is that there is absolutely nothing exceptional in invalid input strings and your error handling code, in most cases, is better when it’s explicit and local.
So now, after spending hours on this and similar bugs, I really see the point behind error handling in Go.