Domanda

I'm looking for tools (and techniques) to help with versioning my static asset (CSS, JS, image, etc) URLs within my HandlebarsJS templates. This is for a Node.js web app using express, and running under iisnode in Windows. For performance reasons, I want IIS to serve up the static assets directly -- and NOT use Node or other connect middleware for this pipeline.

Based on how I've done this in the past (with Classic ASP), my current thinking is as follows:

  • Write a HandlebarsJS helper that takes, as input, the asset name. The helper would then get the proper version (timestamp, checksum, etc) for that asset (likely by looking into a pre-generated JSON object), and return the properly versioned path to the asset to be rendered into the template output.
    • e.g.: {{asset 'images/button.png'}} --> //sc.domain.com/images/<version#>/button.png
  • Use Grunt to build a file containing the JSON object mapping asset names to versions. This would then be used by the HandlebarsJS helper to build the URLs.
  • Have IIS rewrite the incoming URLs to remove the version#, which eliminates the need to actually duplicate/version the filename on disk (our site does not require multiple versions of an asset to be live under the same filename at the same time).

In theory, this should all work perfectly for my purposes. But, before I dig in and write all of this infrastructure, I wanted to see if anyone knew a) whether these items already existed somewhere, and b) if there are alternate approaches that would work better for HandlebarsJS?

È stato utile?

Soluzione

Well, I didn't find any better options, so I ended up going forward with my proposed approach above.

For the grunt task, I came across grunt-hashmap, which appeared to do everything I wanted (and more!). As I didn't want it to actually rename the files, all I had to specify in my grunt config was the following:

    hashmap: {
        options: {
            output: 'assethash.json'
        },
        all: {
            cwd: 'public/',
            src: ['**/*']
        }
    }

The next piece, the Handlebars helper, looks like this (assuming params.hashes is basically require('./assethash.json'):

    hbs.registerHelper('versionedUrl', function(file, opts) {
        var hash = (params.hashes && params.hashes[file]) || '';
        if (hash) file = file.replace(/(.*)\/(.*)/, '$1/' + hash + '/$2');
        return (params.appRoot || '') + file;
    });

This splits the path to the resource, and inserts the hash as the last path component. For example:

'js/myscript.js' --> 'js/[hashvalue]/myscript.js'

Finally, to tie it all together, the IIS rewrite rules look like this:

           <rule name="Remove Static Content Version">
                <match url="^(m\/js|m\/css|m\/images)/\w+/(.+)$" />
                <conditions />
                <serverVariables />
                <action type="Rewrite" url="{R:1}/{R:2}" appendQueryString="true" />
            </rule>

And that's basically it! Just wanted to post this in case others have similar questions. I am happy to hear about any improvements or suggestions you can offer, as well.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top