title: Configuring grunt-uncss with Yeoman's generator-webapp
body: <p>I am trying to configure grunt-uncss with a Sass Bootstrap scaffold made with Yeoman's generator-webapp. I've found this discussion that comes close to what I'm trying to do: <a href="https://github.com/addyosmani/grunt-uncss/issues/75" rel="nofollow">https://github.com/addyosmani/grunt-uncss/issues/75</a></p>
  
  <p>I tried to change and apply this to my situation but Grunt is giving me the following error:</p>
  
  <pre><code>...
  Running "uncss:dist" (uncss) task
  File .tmp/styles/main.css created: 121.77 kB → 7.24 kB
  
  Running "cssmin:dist" (cssmin) task
  File dist/styles/main.css created: 7.24 kB → 4.8 kB
  
  Running "cssmin:generated" (cssmin) task
  &gt;&gt; Destination not written because minified CSS was empty.
  File dist/styles/main.css created: 121.77 kB → 96.74 kB
  ...
  </code></pre>
  
  <p>Gruntfile.js</p>
  
  <pre><code>// Generated on 2014-06-16 using generator-webapp 0.4.9
  'use strict';
  
  // # Globbing
  // for performance reasons we're only matching one level down:
  // 'test/spec/{,*/}*.js'
  // use this if you want to recursively match all subfolders:
  // 'test/spec/**/*.js'
  
  module.exports = function (grunt) {
  
      // Load grunt tasks automatically
      require('load-grunt-tasks')(grunt);
  
      // Time how long tasks take. Can help when optimizing build times
      require('time-grunt')(grunt);
  
      // Configurable paths
      var config = {
          app: 'app',
          dist: 'dist'
      };
  
      // Define the configuration for all the tasks
      grunt.initConfig({
  
          // Project settings
          config: config,
  
          // Watches files for changes and runs tasks based on the changed files
          watch: {
              bower: {
                  files: ['bower.json'],
                  tasks: ['bowerInstall']
              },
              js: {
                  files: ['&lt;%= config.app %&gt;/scripts/{,*/}*.js'],
                  tasks: ['jshint'],
                  options: {
                      livereload: true
                  }
              },
              jstest: {
                  files: ['test/spec/{,*/}*.js'],
                  tasks: ['test:watch']
              },
              gruntfile: {
                  files: ['Gruntfile.js']
              },
              sass: {
                  files: ['&lt;%= config.app %&gt;/styles/{,*/}*.{scss,sass}'],
                  tasks: ['sass:server', 'autoprefixer']
              },
              styles: {
                  files: ['&lt;%= config.app %&gt;/styles/{,*/}*.css'],
                  tasks: ['newer:copy:styles', 'autoprefixer']
              },
              livereload: {
                  options: {
                      livereload: '&lt;%= connect.options.livereload %&gt;'
                  },
                  files: [
                      '&lt;%= config.app %&gt;/{,*/}*.html',
                      '.tmp/styles/{,*/}*.css',
                      '&lt;%= config.app %&gt;/images/{,*/}*'
                  ]
              }
          },
  
          // The actual grunt server settings
          connect: {
              options: {
                  port: 9000,
                  open: true,
                  livereload: 35729,
                  // Change this to '0.0.0.0' to access the server from outside
                  hostname: '0.0.0.0'
              },
              livereload: {
                  options: {
                      middleware: function(connect) {
                          return [
                              connect.static('.tmp'),
                              connect().use('/bower_components', connect.static('./bower_components')),
                              connect.static(config.app)
                          ];
                      }
                  }
              },
              test: {
                  options: {
                      open: false,
                      port: 9001,
                      middleware: function(connect) {
                          return [
                              connect.static('.tmp'),
                              connect.static('test'),
                              connect().use('/bower_components', connect.static('./bower_components')),
                              connect.static(config.app)
                          ];
                      }
                  }
              },
              dist: {
                  options: {
                      base: '&lt;%= config.dist %&gt;',
                      livereload: false
                  }
              }
          },
  
          // Empties folders to start fresh
          clean: {
              dist: {
                  files: [{
                      dot: true,
                      src: [
                          '.tmp',
                          '&lt;%= config.dist %&gt;/*',
                          '!&lt;%= config.dist %&gt;/.git*'
                      ]
                  }]
              },
              server: '.tmp'
          },
  
          // Make sure code styles are up to par and there are no obvious mistakes
          jshint: {
              options: {
                  jshintrc: '.jshintrc',
                  reporter: require('jshint-stylish')
              },
              all: [
                  'Gruntfile.js',
                  '&lt;%= config.app %&gt;/scripts/{,*/}*.js',
                  '!&lt;%= config.app %&gt;/scripts/vendor/*',
                  'test/spec/{,*/}*.js'
              ]
          },
  
          // Mocha testing framework configuration options
          mocha: {
              all: {
                  options: {
                      run: true,
                      urls: ['http://&lt;%= connect.test.options.hostname %&gt;:&lt;%= connect.test.options.port %&gt;/index.html']
                  }
              }
          },
  
          // Compiles Sass to CSS and generates necessary files if requested
          sass: {
              options: {
                  includePaths: [
                      'bower_components'
                  ]
              },
              dist: {
                  files: [{
                      expand: true,
                      cwd: '&lt;%= config.app %&gt;/styles',
                      src: ['*.scss'],
                      dest: '.tmp/styles',
                      ext: '.css'
                  }]
              },
              server: {
                  files: [{
                      expand: true,
                      cwd: '&lt;%= config.app %&gt;/styles',
                      src: ['*.scss'],
                      dest: '.tmp/styles',
                      ext: '.css'
                  }]
              }
          },
  
          // Add vendor prefixed styles
          autoprefixer: {
              options: {
                  browsers: ['last 1 version']
              },
              dist: {
                  files: [{
                      expand: true,
                      cwd: '.tmp/styles/',
                      src: '{,*/}*.css',
                      dest: '.tmp/styles/'
                  }]
              }
          },
  
          // Automatically inject Bower components into the HTML file
          bowerInstall: {
              app: {
                  src: ['&lt;%= config.app %&gt;/index.html'],
                  exclude: ['bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap.js']
              },
              sass: {
                  src: ['&lt;%= config.app %&gt;/styles/{,*/}*.{scss,sass}']
              }
          },
  
          // Renames files for browser caching purposes
          rev: {
              dist: {
                  files: {
                      src: [
                          '&lt;%= config.dist %&gt;/scripts/{,*/}*.js',
                          '&lt;%= config.dist %&gt;/styles/{,*/}*.css',
                          '&lt;%= config.dist %&gt;/images/{,*/}*.*',
                          '&lt;%= config.dist %&gt;/styles/fonts/{,*/}*.*',
                          '&lt;%= config.dist %&gt;/*.{ico,png}'
                      ]
                  }
              }
          },
  
          // Reads HTML for usemin blocks to enable smart builds that automatically
          // concat, minify and revision files. Creates configurations in memory so
          // additional tasks can operate on them
          useminPrepare: {
              options: {
                  dest: '&lt;%= config.dist %&gt;'
              },
              html: '&lt;%= config.app %&gt;/index.html'
          },
  
          // Performs rewrites based on rev and the useminPrepare configuration
          usemin: {
              options: {
                  assetsDirs: ['&lt;%= config.dist %&gt;', '&lt;%= config.dist %&gt;/images']
              },
              html: ['&lt;%= config.dist %&gt;/{,*/}*.html'],
              css: ['&lt;%= config.dist %&gt;/styles/{,*/}*.css']
          },
  
          // The following *-min tasks produce minified files in the dist folder
          imagemin: {
              dist: {
                  files: [{
                      expand: true,
                      cwd: '&lt;%= config.app %&gt;/images',
                      src: '{,*/}*.{gif,jpeg,jpg,png}',
                      dest: '&lt;%= config.dist %&gt;/images'
                  }]
              }
          },
  
          svgmin: {
              dist: {
                  files: [{
                      expand: true,
                      cwd: '&lt;%= config.app %&gt;/images',
                      src: '{,*/}*.svg',
                      dest: '&lt;%= config.dist %&gt;/images'
                  }]
              }
          },
  
          htmlmin: {
              dist: {
                  options: {
                      collapseBooleanAttributes: true,
                      collapseWhitespace: true,
                      removeAttributeQuotes: true,
                      removeCommentsFromCDATA: true,
                      removeEmptyAttributes: true,
                      removeOptionalTags: true,
                      removeRedundantAttributes: true,
                      useShortDoctype: true
                  },
                  files: [{
                      expand: true,
                      cwd: '&lt;%= config.dist %&gt;',
                      src: '{,*/}*.html',
                      dest: '&lt;%= config.dist %&gt;'
                  }]
              }
          },
  
          // By default, your `index.html`'s &lt;!-- Usemin block --&gt; will take care of
          // minification. These next options are pre-configured if you do not wish
          // to use the Usemin blocks.
          // cssmin: {
          //     dist: {
          //         files: {
          //             '&lt;%= config.dist %&gt;/styles/main.css': [
          //                 '.tmp/styles/{,*/}*.css',
          //                 '&lt;%= config.app %&gt;/styles/{,*/}*.css'
          //             ]
          //         }
          //     }
          // },
          // uglify: {
          //     dist: {
          //         files: {
          //             '&lt;%= config.dist %&gt;/scripts/scripts.js': [
          //                 '&lt;%= config.dist %&gt;/scripts/scripts.js'
          //             ]
          //         }
          //     }
          // },
          // concat: {
          //     dist: {}
          // },
  
          // Copies remaining files to places other tasks can use
          copy: {
              dist: {
                  files: [{
                      expand: true,
                      dot: true,
                      cwd: '&lt;%= config.app %&gt;',
                      dest: '&lt;%= config.dist %&gt;',
                      src: [
                          '*.{ico,png,txt}',
                          '.htaccess',
                          'images/{,*/}*.webp',
                          '{,*/}*.html',
                          'styles/fonts/{,*/}*.*'
                      ]
                  }, {
                      expand: true,
                      dot: true,
                      cwd: '.',
                      src: ['bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/*.*'],
                      dest: '&lt;%= config.dist %&gt;'
                  }]
              },
              styles: {
                  expand: true,
                  dot: true,
                  cwd: '&lt;%= config.app %&gt;/styles',
                  dest: '.tmp/styles/',
                  src: '{,*/}*.css'
              }
          },
  
          // Run some tasks in parallel to speed up build process
          concurrent: {
              server: [
                  'sass:server',
                  'copy:styles'
              ],
              test: [
                  'copy:styles'
              ],
              dist: [
                  'sass',
                  'copy:styles',
                  'imagemin',
                  'svgmin'
              ]
          },
  
          autoshot: {
              dist: {
                  options: {
                      path: 'screenshots/',
                      remote : {
                          files: [
                              { src: 'http://localhost:&lt;%= connect.options.port %&gt;', dest: 'app.jpg'}
                          ]
                      },
                      viewport: ['320x480','480x320','384x640','640x384','602x963','963x602','600x960','960x600','800x1280','1280x800','768x1024','1024x768']
                  }
              }
          },
  
          uncss: {
              dist: {
                  options: {
                      stylesheets: ['../.tmp/styles/main.css']
                  },
                  files: {
                      '.tmp/styles/main.css': ['app/index.html']
                  }
              }
          }
      });
  
  
      grunt.registerTask('serve', function (target) {
          if (target === 'dist') {
              return grunt.task.run(['build', 'connect:dist:keepalive']);
          }
  
          grunt.task.run([
              'clean:server',
              'concurrent:server',
              'autoprefixer',
              'connect:livereload',
              'watch'
          ]);
      });
  
      grunt.registerTask('server', function (target) {
          grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
          grunt.task.run([target ? ('serve:' + target) : 'serve']);
      });
  
      grunt.registerTask('test', function (target) {
          if (target !== 'watch') {
              grunt.task.run([
                  'clean:server',
                  'concurrent:test',
                  'autoprefixer'
              ]);
          }
  
          grunt.task.run([
              'connect:test',
              'mocha'
          ]);
      });
  
      grunt.registerTask('build', [
          'clean:dist',
          'useminPrepare',
          'concurrent:dist',
          'autoprefixer',
          'concat',
          'uncss',
          'cssmin',
          'uglify',
          'copy:dist',
          'rev',
          'usemin',
          'htmlmin'
      ]);
  
      grunt.registerTask('default', [
          'newer:jshint',
          'test',
          'build'
      ]);
  
      grunt.registerTask('screenshots', [
          'clean:server',
          'concurrent:server',
          'connect:livereload',
          'autoshot'
      ]);
  
      grunt.registerTask('build-uncss', [
          'build',
          'uncss'
      ]);
  };
  </code></pre>
  
  <p>I understand it's an issue with the order of events for all the grunt tasks ran with "grunt", but I can't find the point that breaks the process. What am I missing here?</p>