javascriptgruntjsgrunt-usemin

grunt-usemin + grunt-rev, point to CDN url on build but maintain revision number?


I'm using grunt-usemin in combination with grunt-rev to replace references to non-optimized scripts with a single concatenated one, with a revision tacked on each build.

It takes this:

    <!-- build:js({.tmp,app}) scripts/main.js -->
    <script src="scripts/custom_script1.js"></script>
    <script src="scripts/custom_script2.js"></script>
    <script src="scripts/models/custom_model.js"></script>
    <!-- endbuild -->

and, after grunt build, outputs this:

<script src="scripts/b7197f7b.main.js"></script>

Now here's my problem:

I need the build output src to not be relative to the project directory, but rather point to an external URL, as my script will be hosted on a CDN.

// build should produce THIS instead:
<script src="www.my-cdn-url.com/scripts/b7197f7b.main.js"></script>

I've tried to do this using the blockReplacement config object in the usemin task:

// this is what I've tried (note the blockReplacement):
usemin: {
    html: ['<%= yeoman.dist %>/{,*/}*.html'],
    css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
    options: {
        dirs: ['<%= yeoman.dist %>'],
        blockReplacements: {
            js: function (block) {
                return '<script type="text/javascript" src="www.my-cdn-url.com/scripts/'+block.dest+'"></script>';
            }
        }
    }
},

And, while this works for changing the src attribute to point to my CDN, the revision number is not being applied.

My Question: How can I point my usemin build to an external endpoint, while maintaining the revisioning number created during the build?

For reference, here are my complete usemin and rev tasks (taken from the yeoman backbone boilerplate):

usemin: {
    html: ['<%= yeoman.dist %>/{,*/}*.html'],
    css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
    options: {
        dirs: ['<%= yeoman.dist %>'],
        blockReplacements: {
            js: function (block) {
                return '<script type="text/javascript" src="www.my-cdn-url.com/scripts/'+block.dest+'"></script>';
            },
            css: function(block) {
                return '<link rel="stylesheet" href="www.my-cdn-url.com/styles/'+block.dest+'">';
            }
        }
    }
},

rev: {
    dist: {
        files: {
            src: [
                '<%= yeoman.dist %>/scripts/{,*/}*.js',
                '<%= yeoman.dist %>/styles/{,*/}*.css',
                '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}',
                '/styles/fonts/{,*/}*.*',
            ]
        }
    }
}

Solution

  • So I found no way to do this with only grunt-rev and grunt-usemin, I needed to bring in an additional grunt plugin: grunt-cdnify.

    Below is how the Cdnify task configuration to get my desired result:

    cdnify: {
        dist: {
            options: {
                base: '//my-cdn-url.com',
                cc: true
            },
            files: [{
                expand: true,
                cwd: 'dist',
                src: 'index.html',
                dest: 'dist'
            }]
        }
    }
    

    the /scripts/ and /styles/ are being appended to the base URL naturally. Was unfortunate I needed an additional plugin to do something so simple, but hey it works!