Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Managing images in bower packages using grunt

I have an express app in which I'm using bower to manage the front-end dependencies. I'm also using grunt to build the front end by concatenating, uglifying, minifying, and rev'ing all the assets, including the scripts/styles that ship with each bower component using grunt-usemin.

To accomplish this I'm moving all of the compiled assets (including bower scripts/styles) to a dist/public directory. I end up with a <cache-buster>.vendor.js and a <cache-buster>.vendor.css file, which contain all of the optimized bower components.

The question is, how should I manage images that ship with various bower packages? I could manually move them into my images folder, but I would prefer to leave them packaged in bower_components (where they belong, in my opinion) and leave it up to grunt during the build process.

Any input would be appreciated.


Gruntfile.js (extract)

    rev: {
      dist: {
        files: [{
          src: [
            'dist/public/css/{,*/}*.css',
            'dist/public/js/{,*/}*.js',
            'dist/public/img/{,*/}*.{gif,jpeg,jpg,png}'
          ]
        }]
      }
    },

    useminPrepare: {
      options: {
        dest: 'dist/public'
      },
      jade: ['dist/views/{,*/}*.jade']
    },

    usemin: {
      jade: ['dist/views/{,*/}*.jade'],
      options: {
        assetsDirs: ['dist/public'],
        patterns: {
          jade: require('usemin-patterns').jade
        }
      }
    },

    concurrent: {
      server: [
        'stylus', 'coffee'
      ],
      dist: [
        'stylus', 'coffee'
      ]
    },

    copy: {
      dist: {
        files: [{
          expand: true,
          cwd: 'views',
          dest: 'dist/views',
          src: '{,*/}*.jade'
        }]
      }
    }
  });

  grunt.registerTask('server', [
    'clean:server',
    'concurrent:server',
    'express:server',
    'watch'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'concurrent:dist',
    'copy:dist',
    'useminPrepare',
    'concat',
    'uglify',
    'cssmin',
    'rev',
    'usemin'
  ]);

layout.jade (extract)

//-<!-- build:css(assets) css/vendor.css -->
link(href='/bower_components/nivo-slider/nivo-slider.css')
//-<!-- endbuild -->

//-<!-- build:css(.tmp) css/application.css -->
link(href='/css/one.css')
link(href='/css/two.css')
//-<!-- endbuild -->

//-<!-- build:js(assets) js/vendor.js -->
script(type='text/javascript', src='/bower_components/jquery/jquery.js')
script(type='text/javascript', src='/bower_components/nivo-slider/jquery.nivo.slider.js')
//-<!-- endbuild -->

//-<!-- build:js(.tmp) js/application.js -->
script(type='text/javascript', src='/js/one.js')
script(type='text/javascript', src='/js/two.js')
//-<!-- endbuild -->
like image 463
Feech Avatar asked Dec 11 '13 01:12

Feech


1 Answers

Here is a solution adapted to your Gruntfile:

rev: {
  dist: {
    files: [{
      src: [
        'dist/public/css/{,*/}*.css',
        'dist/public/js/{,*/}*.js',
        'dist/public/img/{,*/}*.{gif,jpeg,jpg,png}',
        'dist/bower_components/**/*.{png,jpg,jpeg,gif,webp,svg,eot,ttf,woff}'
      ]
    }]
  }
},
useminPrepare: {
  options: {
    dest: 'dist/public',
    flow: {
      html: {
        steps: {
          js: ['concat', 'uglifyjs'],
          css: ['cssmin']
        },
        post: {}
      }
    }
  },
  jade: ['dist/views/{,*/}*.jade']
},

cssmin: {
  options: {
    root: 'src'
  }
},

This assumes your bower_compontents directory is located in a source directory called 'src'. In my environment (bootstrapped with Yeoman) it was in 'app', so you may need to tweak cssmin.

Here is what is happening:

First, we add rev checksums to a bunch of possible resource files in the bower_components directory.

Next, the flow configuration tells usemin to skip the concat step for css files. This is because cssmin does a concatenation itself, and cssmin needs to know the origin of the css files in order to do the relative-path correction for referenced resources.

Lastly, the root config tells cssmin which path to start searching from to find the resources.

You can check to verify the results are correct by going to dist/styles/<cache-buster>.vendor.css and verifying the images have relative URLs, starting with /bower-components/

For example, in my build, I have bootstrap.css embedded in my vendor.css, and it has been rewritten like this:

@font-face{
   font-family:'Glyphicons Halflings';
   src:url(/bower_components/bootstrap/dist/fonts/2ad0632b.glyphicons-halflings-regular.eot);

(line wrapping added for legibility, its all cssminified in reality).

I hope this helps.

Giving credit where it is due, I found this originally here: https://stackoverflow.com/a/21415649/1017787 I've adjusted it to your configuration and added the revision config.

like image 182
JBCP Avatar answered Dec 23 '22 06:12

JBCP