Birdy
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).
Getting started
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
staticDependencies
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
Command line options
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.
resources/*
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).
Contributing
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.
To-do
- 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)
License
Copyright © 2013 Christopher Brown. MIT Licensed.