Over the weekend I was working on a small project and needed a copy of jQuery. I try to avoid the CDN as I find myself at airports without wifi access sometimes so I did what I normally do:
- Go to jQuery.com
- Click the download link
- Click for the latest minified version
- Right click, save as
This worked - and it was epic cool - until I realized how much it grabbed...

Ugh. Don't get me wrong - this was still quicker then my old process. And I "get" the idea behind the metadata involved here and why it would be useful in the future. Bower is pretty damn powerful and I definitely recommend folks take a look at it.
But what if you just want a copy of the library, one time, and that's it?
I decided to whip up a quick Brackets extension as a proof of concept. Clicking the "Run JSDownloader" menu option opens up a dialog of options:

Clicking the library fires off a process to download it:

And yeah... that's it. Simple, direct, exactly what I need. There's a few caveats though.
Right now it only supports "single file" downloads. I've got basic architecture in there to support a list of files, but it isn't complete. The idea is that if you provide a list of files, it will create a subdirectory based on the name of the library (as in: currentdir/jqueryui/) and then copy the resources there. But this isn't complete yet because...
The second issue is that Brackets still doesn't support binary file writes in extensions. In theory I could do so if I hook up a Node module to my extension, but... honestly it feels like a bit much. I'd rather just wait a bit and hope for support in a future sprint.
Finally, there is no support in Brackets yet for refreshing the project view. So while the extension certainly works, you need to do a reload to see the files show up.
So - where did that last of four projects come from? This is kinda cool I think. In order to "drive" the data list, my extension reads from a simple JSON packet. Here's how it looks now:
[ | |
{"key":"jquery","name":"jQuery 2.0","file":"http://code.jquery.com/jquery-2.0.0.min.js"}, | |
{"key":"handlebars","name":"Handlebars 1.0.0 rc3","file":"https://raw.github.com/wycats/handlebars.js/1.0.0-rc.3/dist/handlebars.runtime.js"}, | |
{"key":"underscore","name":"Underscore 1.4.4","file":"http://underscorejs.org/underscore-min.js"}, | |
{"key":"zepto","name":"Zepto 1.0", "file":"http://zeptojs.com/zepto.min.js"} | |
] |
While this file is in the extension itself, my code reads the GitHub version of it instead:
var JSDownloader = (function() { | |
var INDEX_URL = "https://raw.github.com/cfjedimaster/brackets-jsdownloader/master/jsdownloader_index.json"; | |
var INDEX_KEY = "jsdownloader.index"; | |
//Number of minutes to cache | |
var CACHE_LEN = 1000*60*60*24; | |
var index; | |
return { | |
getIndex:function() { | |
var raw = JSON.parse(localStorage.getItem(INDEX_KEY)); | |
return raw.index; | |
}, | |
hasCachedIndex:function() { | |
var cache = localStorage.getItem(INDEX_KEY); | |
if(!cache) return false; | |
var ob = JSON.parse(cache); | |
var then = new Date(ob.created); | |
var now = new Date(); | |
if((now.getTime() - then.getTime()) > CACHE_LEN) return false; | |
return true; | |
}, | |
loadIndex:function(cb) { | |
$.get(INDEX_URL, {}, function(res,code) { | |
console.dir(res); | |
var ob = {}; | |
ob.created = new Date(); | |
ob.index = res; | |
localStorage.setItem(INDEX_KEY, JSON.stringify(ob)); | |
cb(); | |
},"json"); | |
} | |
}; | |
}()); | |
This means folks could add a new library by just committing to my GitHub repo. I don't have a nice UI to refresh the cache, but if folks end up using and contributing to this extension, I'll add it.
Download/Fork the code here: https://github.com/cfjedimaster/brackets-jsdownloader