Devtools Redirect: A Chrome Extension To Help Debug Live, Obfuscated Javascipt without Source maps

Don’t you hate getting that ticket with the bug that can only be reproduced in one godforsaken corner on the live app that you didn’t even know existed?  Sure, your browser dev tools help a ton.  Prettifying that obfuscated code and setting breakpoints can often be enough to get to the root of the bug.  But sometimes, you have to dig a little deeper and make some code edits.  Unfortunately, you can’t edit prettified code.  Aahrg!!  If only you had been able to check off that to-do list item labeled “implement source maps”!

Enter the Chrome extension: Devtools Redirect.

It’s actually quite simple.  Devtools Redirect adds another tab to your devtools panel where you can define file requests to intercept and redirect to another location.

If the edit is small enough, you can just download the javascript file in question, make your edits, and serve it from your local machine.  But for a more complete picture, you can run a non-obfuscated build from your production tag and serve that in its place.

This is a very handy tool that I can imagine a few good uses for.  I’m thinking something along the lines of giving Project Management a heart attack by making them think the live app has been Raptorized.

TwitterRedditShare
Tagged with: , , ,
Posted in Programming

Avoiding AMD Parallel List Hell with RequireJS’s CommonJS Wrapper

We’re all familiar with the AMD standard and all its quirks.

define([
		'dependancy1',
		'dependancy2',
		.
		..
		...
		'dependancy1337'
	],
	function(
		Dep1,
		Dep2,
		.
		..
		...
		Dep1337,
	) {
		//define module
	}
);

As you know, the pain of managing these lists grows exponentially with each module included. I’ve spent more time than I care to admit chasing down bugs that could be sourced to misalignments in these lists.

Fortunately, I have a coworker who is much more thorough in documentation-reading than I am. He pointed out that RequireJS has an alternate syntax that can eliminate this hell.

define(function(require) {
	var Dep1 = require('dependancy1'),
		Depy2 = require('dependancy2'),
		.
		..
		...
		Dep1337 = require('dependancy1337');

	//define module
});

And magically, we no longer have parallel lists to maintain!

Though it was intended as a wrapper for CommonJS modules, we find it works quite well in our large-scale app.

There is one thing to keep in mind when using this alternative syntax. It may look like we can take advantage of CommonJS’s ability to conditionally load modules. However, that is not the case.

define(function(require) {
	var Dep1;

	if(false) {
		Dep1 = require('dependancy1');
	}
});

In this example, “dependancy1″ will be loaded and defined. We just won’t have a reference to it. Before defining the module, Require will parse the contents for dependencies. Then it will execute the factory function.

This may seem odd at first glance, but it’s for a good reason. Remember that the A in AMD is “Asynchronous”. This syntax is intended to provide some compatibility with the synchronous CJS standard without giving up the advantages of AMD.

Happy Require-ing!

Tagged with: , , ,
Posted in Programming, Tech, Tutorials