Versions images, less, css, js for your website
versioner uses the hash of the file contents, this means the URL of the asset will only change if the contents of the file changes. This is beneficial vs. just using a version number since assets will only cache bust when they really change vs. every time you do a new release of your website to your servers.
For example, versioner will generate URLs like:
If the contents of main.js changes but style.css doesn't the versioner approach will only cause clients to redownload main.js, whereas the simple version number will cause all of the files to be downloaded by the client.
npm install versioner
In order to create versioned assets you need to provide the location on disk where the assets live, plus provide a URL where the versioned assets will be referenced from. The options that can be passed to the Versioner constructor are:
Once you have specified the urlRoot and sources of all the files you can use the following methods on the versioner instance:
If you specify a root path, then the path you pass into the methods above is relative to the root path. For example, if you specify the root of images to be: /Users/mark/projectA/images
Then to retrieve the file that lives at: /Users/mark/projectA/images/dir1/foo.jpg you would call:
The value returned will be the versioned image name appended to the urlRoot value, so if urlRoot is: http://localhost/static then imageUrl('dir1/foo.jpg') will return http://localhost/static/foo.<UNIQUE_HASH>.jpg.
NOTE: the path has been flattened to only use the file name, not including the dir1 reference.
If you specify an explicit path for a file or specify a buffer in the files: property of the Versioner options, then to retrieve the versioned URL, you give the "path" value you entered in the explicit file information. For example:
var img1Buffer = require'fs'readFileSync'/Users/mark/projectA/images/img1.jpg';var options =urlRoot: ''types:image:files:data: img1Buffer path: 'dir1/img1.jpg'source: '/Users/mark/projectA/images/img2.jpg' path: 'dir2/img2.jpg'style:files:source: '/Users/mark/projectA/less/url-replace.less'path: 'url-replace.css'compiler: 'less';
To retrieve the versioned URL references you would call:
The reason you may have a buffer is that files in your project may not actually exist on disk. For example, you may have files a.js, b.js and c.js on disk that you concatenate together and want to serve as mysite-min.js If you wanted to version this you could concatentate the files and store the concatenated data in a buffer, then pass the buffer to versioner along with the path of 'mysite-min.js'
It is very common to reference images from stylesheets. For example:
versioner provides an easy way to update the assets to point to their versioned equivalent. You simply wrap the path in either versionerUrl or versionerDataUri wrappers, then when versioner loads the stylesheet, the image path updates e.g.
This will then be converted to something like:
Pretty neat :)
less http://lesscss.org/ support is built directly into versioner. Simply specify the compiler as less in the options to the Versioner constructor and the files will automatically be compiled e.g.
If you don't specify a compiler value the style files will assume to be CSS. You can also specify a custom compiler to use. Instead of passing the string 'less' specify a function with the following signature:
Where styleString will be the contents of the style file and the callback should be passed the compiled CSS string after it has been processed.
NOTE: Currently versioner does not support CSS files that reference other CSS files, you can either just include multiple CSS files in your webpage or concatentate all of your CSS files into a single CSS file.
Below is a quick example of how you can us versioner in your app:
In your backend templates you can now use the versioner instance that you created above, e.g. mytemplate.ejs
<%= title %><!-- IMPORTANT: Note how you reference the file as style.css even ifit was initially style.less, since after compilation the .lessfiles are now .css file --><%= title %>
This will end up generating something like:
Versioner ExampleVersioner Example
This example assumes that your server is capable of serving the versioned assets from the http://localhost/assets URL root. You can do this by calling the save() method on the versioner instance which will write all of the versioned assets to disk.
Note: Although you can use versioner to server files directly, you should really be using one of those fancy CDN things that are capable of serving large amounts of traffic.
Simply caller the build() method then save() all of the versioned assets will then be written to yhe specified output directory
There is a simple to use express middleware provided as part of versioner. This allows you to easily plug versioner into your existing express apps with minimal effort.
var Versioner = require'versioner';// 1. Create the versioner instancevar vers = //options ... });// 2. Add the versioner middlewareappconfigure// ...// Add express middleware that will check each incoming request// and see if it is a versioned asset. If it is then this piece// of middleware will serve the file, otherwise the next piece// of middleware will be called.appuseVersionerExpressvers;// Might be other assets we haven't versioned, serve those as normalappuseexpressstaticpathjoin__dirname 'public';;// 3. Build version information and start listening for// requests on successversbuildiferrorconsole.error'Failed to load versioned assets';processexit1;var port = appget'port';httpcreateServerapplistenportconsole.log"Express server listening on port " + port;;;
For a full working express example see examples/express/app.js
You can then view http://localhost:5678/ and see a page that is serving versioned assets.
git clone https://github.com/markdaws/versioner.gitcd versionernpm installnpm test