JavaScript dependency injection is all the rage these days. But after
looking through all the options, I just haven’t found the perfect
framework. That’s why I’m introducing my own framework to provide the
best possible interface, helping you to inject exactly the dependency
you need.
First, I want to introduce the problem we’re trying to solve. Let’s say
you have a JavaScript function that has a dependency, but the client
knows too much about the dependency. This is what smarty-pants engineers
call “tight coupling”:
function Dependency1(say){
alert(say);
}
function Client(){
new Dependency1('hi'); // bad! tightly coupled interface
}
new Client();
Continue reading »
Like the rest of the world, RightScale has been moving more and more of
its application from the server to the client. That means we’ve suddenly
found managing larger and larger piles of JavaScript. All that
JavaScript needs to be delivered to clients as quickly as possible in
order to minimize the time customers spend waiting for web pages to
load.
So we created a nice little build tool leveraging
Grunt which among other things takes all that
JavaScript and compiles it into one big blob for each application. In
order to make that big blob as small as possible, we use
UglifyJS.
Unfortunately, some of our apps are so big that running the uglify Grunt
task can take a long time. Ideally, this task would be fast enough to
where it could be run at or just before deploying. Fast enough is a
pretty subjective term, but we deploy code all the time to production
and various kinds of staging systems, so fast enough becomes however
long you want to wait for code deploys in addition to the time it
already takes. In my case, three extra minutes is not fast enough.
So I theorized about the virtue of using UglifyJS at all and my
reasoning went something like this: Any sane person who’s delivering a
lot of JavaScript to clients on the web is going to be using some kind
of HTTP compression
algorithm like gzip or deflate. And hardcore file size optimizations
prior to compression seem like exactly the kind of things that would
make regular file compression less efficient. So wouldn’t we be better
off with something fast and simple like Douglas Crockford’s good old
JSMin? We could just
rely more on the file compression than mifification or uglification to
reduce file size.
Continue reading »
Do a search on google for “youtube api javascript upload” and you’ll get
all kinds of results. There are a huge number of ways people try to get
around the document same origin
policy
to make an HTTP request using JavaScript. Lets go through some of them:
You can create a real HTML form and submit it with
JavaScript,
and you can avoid the page refresh by submitting to an iframe. You can
use
jsonp
to sneak by and load remote JavaScript using a script tag. You can
fruitlessly attempt to muck with
document.domain.
There are all kinds of other crazy hacks people use to circumvent the
same origin policy, but they are all either severely limited, or suffer
in terms of your ability to control the HTTP request parameters and
properly handle the response in failure scenarios.
Another option is to skip the whole idea of submitting your requests
directly from the browser to the remote server. You can install your own
proxy server on the same domain as your client JavaScript application
and make requests to your proxy which then makes the disallowed requests
for you because your proxy server isn’t governed by the same origin
policy. This method gives you full control over the entire process, but
setting up and maintaining a proxy server, paying for bandwidth and
storage, and dealing with the added complexity might be too expensive
and time consuming. It might also be totally unnecessary.
CORS is here to save the day. CORS has existed for a long time, but for
some reason (maybe browser compatibility reasons), it hasn’t yet caught
on in a big way. Many well-known APIs, including Google’s YouTube Data
API v3 already support CORS.
And chances are, the browser you’re currently using supports CORS too.
Continue reading »
jqXHR and the Promise Interface
jQuery 1.5 features a brand new mechanism for dealing with asynchronous
event-driven processing. This system, called deferreds, was first
implemented for jQuery’s $.ajax method and so we’ll be looking closely
at that method.
$.ajax({
url: "/some/url",
success: function(r){
alert("Success: " + r);
},
error: function(r){
alert('Error: ' + r);
}
});
Continue reading »