Birdy is a fast, fine-grained static asset management tool. It intends to replace bower for common uses, although it is not as flexible (it does not include the kitchen sink).
Goals:
- Curated repository / database of resources. More like homebrew than npm, in that it's not publicly writable, and all changes are recorded in source control.
- Fast. Does not clone the entire git repository (which often contains tests, benchmarks, etc.), but only the files you (ought to) want.
- Minimal.
- Structured. Puts the files in a somewhat configurable location. Does not require the user to know the structure of the endpoint repository (this repository does that work for you, somewhat).
First, install Birdy
npm install -g birdy
You'll need to add a section to your package.json
, or a package.json
file to your project, if you don't node.
birdy init
Add resources to the newly created "staticDependencies" hash in your package.json
file as needed, something like:
{
...
"staticDependencies": {
"jquery": "2.0.0",
"handlebars": "*",
"angular": {
"filter": ["angular.js", "angular.min.js"]
},
"angular-translate": "git://github.com/angular-translate/bower-angular-translate.git",
"tv4": {
"url": "git://github.com/geraintluff/tv4.git",
"filter": ["tv4.js", "tv4.min.js"]
}
}
}
You can also specify in your package.json
where the files go:
{
...
"staticPattern": "static/{resource}/{file}",
"staticDependencies": { ... }
}
staticPattern
is resolved relative to your current working directory where
you happen to run birdy install
, and all necessary directories will be created.
It has two special values, which are replaced as the script proceeds.
{resource}
: The resource name, e.g., "jquery"{file}
: The file name, which may be several files, as specified by the resource inresources/{resource}.js
.
So if you want something like bower
, you could use:
{ "staticPattern": "components/{resource}/{file}" }
Or if you want everything in one directory:
{ "staticPattern": "static/{file}" }
Most filenames denote their resource, but not specifying {resource}
might
end up overwriting some files. birdy install
will not inform you of such
conflicts, so be careful.
Then fetch them!
birdy install
Every entry in staticDependencies
has a key, the resource
name, and a flexible value field.
Possible values are:
- A version, e.g., "*", or "1.10.2".
- A git repository url, e.g., "git://github.com/chbrown/misc-js.git"
- A dictionary with
You can specify all these options at the command line, instead of package.json
.
But I led with package.json
because that's the sane way.
Run birdy --help
to see what flags to use.
Every resource is an arbitrary javascript file that exposes a function as module.exports
.
Function signature:
function(version, callback) {
// compute a dictionary mapping filenames to lists of urls
// each of the urls should return an identical file
// the urls can be fully specified git paths
if (version === '2.0.0') {
callback({
'jquery.min.js': [
'https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js',
'http://code.jquery.com/jquery-2.0.0.min.js'
],
'jquery.max.js': [
'https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.js',
'http://code.jquery.com/jquery-2.0.0.js'
]
})
}
else {
callback(new Error('Cannot find version = ' + version));
}
}
The callback is not guaranteed to be async (e.g., setImmediate
or requiring some fetch).
Fork and send a pull request. I won't haphazardly accept all requests, but I do want this to cover a lot of packages. Before you send a pull request, please verify that:
- Your addition is not a duplicate of an existing resource.
- Someone else might conceivably want to use the resource you are submitting.
- Support git directly, rather than converting to
https://raw.github.com/...
for github and dying on everything else. - Add option not to overwrite existing files (or even fetch them).
- Maybe even incorporating the file creation time as a
If-Modified-Since
header, and ignoring "304 Not Modified" responses.
- Maybe even incorporating the file creation time as a
- Cache locally like
bower
does, something like~/.birdy/
? - Look for a config file when including a tarball / git repo (
package.json
?)- Inside that config file, look for a field describing ignored files (
staticIgnore
?) - Do not copy over filepaths that match those globs / filenames
- Inside that config file, look for a field describing ignored files (
- Use multiple urls when available. Ideas:
- Randomize which url gets picked.
- Check that they're all the same.
- Fall back to other urls if any of them error out with a 404 / 500.
- Add more libraries!
- D3.js (at v3)
- HeadJS (at v0.99)
- mousetrap
- jquery.fileupload
- jsSHA
- Maybe add these, too (lower priority):
- LESS (less.js)
- Support
bower.json
files (for Bower-like functionality)
Copyright © 2013 Christopher Brown. MIT Licensed.