$ npm install asset-rack
A node-style asset management framework. Designed for Single Page Apps.
Inspired by Trevor Burnham's connect-assets, and the Rails Asset Pipeline
npm install asset-rack
There are two very simple conepts to understand with asset-rack.
An asset after it is complete
, consists of three very important things.
url
: A human readable url.contents
: Contents for the asset, like the actual javascript or image or whatever.md5
: An md5 hash of the contentsThese three pieces are absolutely critical. The md5 hash is super important! This allows us to append our human readable url with the md5 hash for versioning which allows basically every static asset to be cached forever by proxies, browsers, cdn's. This makes everything fast, fast, fast.
An asset rack is a collection of assets. But it allows us to do things with assets that we always want to do very easily. Like serve them from a memory cache using express and connect middleware, or push all individual assets to an Amazon S3 bucket, or write them to disk or whatever other group action we might want to perform on our assets.
Here is a simple walk throught that demonstrates some of the major features of asset rack.
First create your assets. Here we are creating our stylesheets, javascript code, and javascript templates from less, coffeescript and jade.
var rack = require('asset-rack');
var assets = new rack.AssetRack([
new rack.LessAsset({
url: '/style.css',
filename: __dirname + '/path/to/file.less'
}),
new rack.BrowserifyAsset({
url: '/app.js',
filename: __dirname + '/path/to/app.coffee'
}),
new rack.JadeAsset({
url: '/templates.js',
dirname: __dirname + '/templates'
})
]);
assets.on('complete', function() {
console.log('hey all my assets were created!');
});
Once your assets have been created you can hook them into express with ease.
assets.on('complete', function() {
var app = express.createServer();
app.configure(function() {
app.use(assets); // that's all you need to do
});
app.listen(8000);
});
All of those assets are now stored in an in-memroy cache, so it is super fast.
In your jade templates you can include the tags by referencing their url. For your convenience the assets object will be added to response locals, so that you can do the following in say a jade template:
!= assets.tag('/style.css')
!= assets.tag('/app.js')
!= assets.tag('/templates.js')
Which results in the following html:
<link href="/style-{md5-sum}.css" rel="stylesheet"></link>
<script src="/templates-{md5-sum}.js"></script>
<script src="/app-{md5-sum}.js"></script>
Very cool, and this will work for multi-process and multi-server.
Notice the md5 sum that is now on the url. This means you can HTML cache it forever. Which is exactly what we do if you have the hash option set. Also, updating your CDN is now a breeze.
Now that all your assets are done and hooked into express you can just serve them from your app, but we can do better! Let's push them to Amazon AWS so they can be served by S3 or Cloudfront.
assets.on('complete', function() {
assets.pushS3({
key: '<your aws key>',
secret: '<your aws secret>',
bucket: '<your aws bucket>'
});
assets.on('s3-upload-complete', function() {
console.log('our assets are now on amazon s3!');
});
});
This is your initial collection of assets.
var assets = new AssetRack([
new rack.LessAsset({
url: '/style.css',
filename: __dirname + '/path/to/file.less'
}),
new rack.BrowserifyAsset({
url: '/app.js',
filename: __dirname + '/path/to/app.coffee'
}),
new rack.JadeAsset({
url: '/templates.js',
dirname: __dirname + '/templates'
})
]);
To use with express:
app.use(assets);
tag(url)
: Given a url, returns the tag that should be used in HTML.pushS3({key:key, secret:secret, bucket:bucket})
: Pushes all asset contents to their respective
urls in an Amazon S3 bucket.complete
: Emitted after all assets have been created.s3-upload-complete
: Emitted after assets have been loaded to s3.error
: Emitted for any errors.Browserify is an awesome node project that converts node-style requires to requirejs for the frontend. For more details, check it out, here.
new BrowserifyAsset({
url: '/app.js',
filename: __dirname + '/client/app.js',
compress: true
});
url
: The url that should retrieve this resource.filename
: A filename or list of filenames to be executed by the browser.require
: A filename or list of filenames to require, should not be necessary
as the filename
argument should pull in any requires you need.debug
(defaults to false): enables the browserify debug option.compress
(defaults to false): whether to run the javascript through a minifier.extensionHandlers
(defaults to []): an array of custom extensions and associated handler function. eg: [{ ext: 'handlebars', handler: handlebarsCompilerFunction }]
hash
(defaults to true): Set to false if you don't want the md5 sum added to your urls.Snockets is a JavaScript/CoffeeScript concatenation tool for Node.js inspired by Sprockets. Used by connect-assets to create a Rails 3.1-style asset pipeline. For more details, check it out, here.
new SnocketsAsset({
url: '/app.js',
filename: __dirname + '/client/app.js',
compress: true
});
url
: The url that should retrieve this resource.filename
: A filename or list of filenames to be executed by the browser.compress
(defaults to false): whether to run the javascript through a minifier.extensionHandlers
(defaults to []): an array of custom extensions and associated handler function. eg: [{ ext: 'handlebars', handler: handlebarsCompilerFunction }]
debug
(defaults to false): output scripts via eval with trailing //@ sourceURLhash
(defaults to true): Set to false if you don't want the md5 sum added to your urls.This is an awesome asset. Ever wanted the simplicity of jade templates on the browser with lightning fast performance. Here you go.
new JadeAsset({
url: '/templates.js',
dirname: __dirname + '/templates'
});
So if your template directory looked like this:
index.jade
contact.jade
user/
profile.jade
info.jade
Then in the browser, you would first need to include the jade runtime script:
script(src="/static/js/jade-runtime.js", type="text/javascript")
then you could reference your templates like so:
$('body').append(Templates['index']());
$('body').append(Templates['user/profile']({username: 'brad', status: 'fun'}));
$('body').append(Templates['user/info']());
url
: The url that should retrieve this resource.dirname
: Directory where template files are located, will grab them recursively.separator
(defaults to '/'): The character that separates directories, i like to change it to an underscore, _
. So that you get more javascript friendly template names like Templates.user_profile
or Templates.friends_interests_list
.compress
(defaults to false): Whether to minify the javascript or not.clientVariable
(defaults to 'Templates'): Client side template
variable.hash
(defaults to true): Set to false if you don't want the md5 sum added to your urls.The angular templates asset packages all .html templates ready to be injected into the client side angularjs template cache. You can read more about angularjs here.
new AngularTemplatesAsset({
url: '/js/templates.js',
directory: __dirname + '/templates'
});
Then see the following example client js code which loads templates into the template cache, where angularTemplates
is the function provided by AngularTemplatesAsset:
//replace this with your module initialization logic
var myApp = angular.module("myApp", []);
//use this line to add the templates to the cache
myApp.run(['$templateCache', angularTemplates]);
url
: The url that should retrieve this resource.hash
(defaults to true): Set to false if you don't want the md5 sum added to your urls.directory
: Directory where the .html templates are stored.compress
(defaults to false): Whether to unglify the js.The less asset basically compiles up and serves your less files as css. You can read more about less here.
new LessAsset({
url: '/style.css',
filename: __dirname + '/style/app.less'
});
url
: The url that should retrieve this resource.hash
(defaults to true): Set to false if you don't want the md5 sum added to your urls.filename
: Filename of the less file you want to serve.compress
(defaults to false): Whether to minify the css.paths
: List of paths to search for @import
directives.©2012 Brad Carleton, Tech Pines and available under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
© 2010 - cnpmjs.org x YWFE | Home | YWFE