gruntjsyeomangrunt-contrib-cssmin

Grunt cssmin minified CSS is empty


I'm working on a Gruntfile for my projects. I've based this Gruntfile on the one included in the generator-webapp Yeoman generator. My Gruntfile looks like this:

'use strict';
var moment = require('moment');

var LIVERELOAD_PORT = 35729;
var lrSnippet = require('connect-livereload')({port: LIVERELOAD_PORT});
var mountFolder = function (connect, dir) {
  return connect.static(require('path').resolve(dir));
};

module.exports = function (grunt) {
  // load all grunt tasks
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
  var config = {
    src: 'testGrunt',
    dest: 'dist'
  };
  var ftpUrl = "testy";
  grunt.initConfig({
    config: config,

    // configure the files to be watched
    watch: {
      // if new dependencies are added in bower, add them to the html file
      bower :{
        files: ['bower.json'],
        tasks: ['bowerInstall']
      },
      // if JS files have changed, re-run jshint
      js :{
        files: ['<%= config.src %>/js/{,*/}*.js'],
        tasks: ['jshint']
      },
      // if CSS files have changed, re-run autoprefixer
      styles: {
        files: ['<%= config.src %>/css/{,*/}*.css'],
        tasks: ['newer:copy:styles', 'autoprefixer']
      },
      options: {
        nospawn: true,
        livereload: LIVERELOAD_PORT
      },
      livereload: {
        files: [
          'index.html',
          'posts/*.md'
        ],
        tasks: ['build']
      }
    },
    // clean command for different dirs
    clean:{
      dist: {
        files: [{
          // allow dot to be present in file name
          dot:true,
          src:[
            // clean the temp and dist folder completely
            '.tmp',
            '<%= config.dest %>/*',
            // ignore hg and git files (do not remove these)
            '<!%= config.dest %>/.hg',
            '<!%= config.dest %>/.git'
          ]
        }]
      }
    },
    // jshint linting for your javascript
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all :[
        // jshint for our own scripts, but let's ignore the lib ones
        '<%= config.src %>/js/{,*/}*.js',
        '!<%= config.src %>/js/vendor/*'
      ]
    },
    autoprefixer: {
      options: {
        // fetch stuff for any browser with more than 5% marketshare
        // WATCHOUT!!!! FORMAT EXACTLY LIKE THIS!
        browsers:['> 5%']
      },
      dist: {
        files:[{
          expand: true,
          // only apply to our own styles and write back to the same tmp folder
          cwd: '.tmp/styles/',
          src: '{,*/}*.css',
          dest:'.tmp/styles/'
        }]
      }
    },
    // copy any files that aren't automatically copied by other tasks
    copy: {
      dist: {
        files: [
          {
            expand:true,
            dot: true,
            cwd: '<%= config.src %>',
            dest: '<%= config.dest %>',
            src: [
              // move any files that we can't optimize with any other tasks
              '*.{ico, txt}',
              '.htaccess',
              'images/{,*/{*.webp',
              '{,*/}*.html',
              'styles/fonts/{,*/}*.*'
            ]
          }]
        },
        styles: {
            expand: true,
            dot: true,
            cwd: '<%= config.src %>/css',
            dest: '.tmp/styles/',
            src: '{,*/}*.css'
        }
    },
    // 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: '<%= config.dest %>'
        },
        html: '<%= config.src %>/index.html'
    },
    usemin: {
        options: {
            assetsDirs: ['<%= config.dest %>', '<%= config.dest %>/images']
        },
        html: ['<%= config.dest %>/{,*/}*.html'],
        css: ['<%= config.dest %>/styles/{,*/}*.css']
    },
    concurrent: {
      dist: [
        'copy:styles',
        'imagemin',
        'svgmin'
      ]
    },
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= config.src %>/images',
          src: '{,*/}*.{gif, jpeg, jpg, png}',
          dest: '<%= config.dest %>/images'
        }]
      }
    },
    svgmin: {
        dist: {
            files: [{
                expand: true,
                cwd: '<%= config.src %>/images',
                src: '{,*/}*.svg',
                dest: '<%= config.dest %>/images'
            }]
        }
    },
    htmlmin: {
        dist: {
            options: {
                collapseBooleanAttributes: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true,
                removeCommentsFromCDATA: true,
                removeEmptyAttributes: true,
                removeOptionalTags: true,
                removeRedundantAttributes: true,
                useShortDoctype: true
            },
            files: [{
                expand: true,
                cwd: '<%= config.dest %>',
                src: '{,*/}*.html',
                dest: '<%= config.dest %>'
            }]
        }
    },
    rev: {
      dist: {
        files: {
          src: [
            '<%= config.dest %>/scripts/{,*/}*.js',
            '<%= config.dest %>/styles/{,*/}*.css',
            '<%= config.dest %>/images/{,*/}*.*',
            '<%= config.dest %>/styles/fonts/{,*/}*.*',
            '<%= config.dest %>/*.{ico,png}'
          ]
        }
      }
    },
    deploy: {
      build: {
        auth: {
          host: 'something.com',
          port: 21,
          authKey: 'key1'
        },
        src: 'dest',
        dest: ftpUrl
      }
    }
  });

  grunt.registerTask('server', ['build', 'connect:livereload', 'open', 'watch']);

  grunt.registerTask('deploy', [
    'deploy'
  ]);

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

  grunt.registerTask('default', [
    'newer:jshint',
    'build'
  ]);
};

My file structure is as follows:

testDirectory/
    testGrunt/
        js/
        css/
        libs/
        index.html
    dist/
        styles/
        scripts/
        index.html
    Gruntfile.js
    package.json
    bower.json

When I run my Gruntfile, all seems to go well, apart from one step. As in the generator-webapp case, the css files are concatenated and written to a .tmp folder. Following this, cssmin is supposed to read these concatenated files, minify them and write them to the desintation folder. However, this doesnt' happen for my main.css. It works for the concatenation of the external files (i.e. libraries that I have included in my HTML). When executing the Gruntfile, the following error shows up:

Running "cssmin:generated" (cssmin) task
File dist/styles/external.css created: 3.31 kB → 1.68 kB
>> Destination not written because minified CSS was empty.

dist/styles/external.css is correctly written. My HTML file, containing the triggers for concat and cssmin (because I'm using usemin):

<html>
<head>
  <!-- build:css styles/external.css -->
  <!-- bower:css -->
  <link rel="stylesheet" type="text/css" href="libs/gridism/gridism.css">
  <!-- endbower -->
  <!-- endbuild -->

  <!-- build:css(.tmp) css/main.css -->
  <link rel="stylesheet" type="text/css" href="css/main.css">
  <!-- endbuild -->
</head>
<body>
  <section class="demo">
    <div class="grid">
      <div class="unit whole">
        <pre>.whole</pre>
      </div>
    </div>
    <div class="grid">
      <div class="unit half">
        <pre>.half</pre>
      </div>
      <div class="unit half">
        <pre>.half</pre>
      </div>
    </div>
    <div class="grid">
      <div class="unit one-third">
        <pre>.one-third</pre>
      </div>
      <div class="unit two-thirds">
        <pre>.two-thirds</pre>
      </div>
    </div>
    <div class="grid">
      <div class="unit one-quarter">
        <pre>.one-quarter</pre>
      </div>
      <div class="unit three-quarters">
        <pre>.three-quarters</pre>
      </div>
    </div>
    <div class="grid">
      <div class="unit one-fifth">
        <pre>.one-fifth</pre>
      </div>
      <div class="unit four-fifths">
        <pre>.four-fifths</pre>
      </div>
    </div>
    <div class="grid">
      <div class="unit two-fifths">
        <pre>.two-fifths</pre>
      </div>
      <div class="unit three-fifths">
        <pre>.three-fifths</pre>
      </div>
    </div>
    <div class="grid">
      <div class="unit golden-large">
        <pre>.golden-large</pre>
      </div>
      <div class="unit golden-small">
        <pre>.golden-small</pre>
      </div>
    </div>
    <div class="grid">
      <div class="unit one-quarter align-right center-on-mobiles">
        <h2>Nested grids</h2>
        <p>Nested grids also work, but the markup gets gnarly pretty&nbsp;quickly.</p>
      </div>
      <div class="unit three-quarters">
        <div class="grid">
          <div class="unit whole">
            <p class="align-center">Gridception!</p>
          </div>
        </div>
        <div class="grid">
          <div class="unit one-third">
            <pre>★</pre>
          </div>
          <div class="unit two-thirds">
            <div class="grid">
              <div class="unit whole">
                <p class="align-center">Gridception!</p>
              </div>
            </div>
            <div class="grid">
              <div class="unit two-fifths">
                <pre>★</pre>
              </div>
              <div class="unit three-fifths">
                <pre>★</pre>
              </div>
            </div>
          </div>
        </div>
        <div class="grid">
          <div class="unit four-fifths">
            <div class="grid">
              <div class="unit whole">
                <p class="align-center">Gridception!</p>
              </div>
            </div>
            <div class="grid">
              <div class="unit one-quarter">
                <pre>★</pre>
              </div>
              <div class="unit one-quarter">
                <pre>★</pre>
              </div>
              <div class="unit one-quarter">
                <pre>★</pre>
              </div>
              <div class="unit one-quarter">
                <pre>★</pre>
              </div>
            </div>
          </div>
          <div class="unit one-fifth">
            <pre>★</pre>
          </div>
        </div>
      </div>
    </div>
  </section>

  <!-- build:js js/external.js -->
  <!-- bower:js -->
  <script src="libs/jquery/dist/jquery.min.js"></script>
  <script src="libs/GA/index.js"></script>
  <script src="libs/gmgeo/index.js"></script>
  <script src="libs/gmaps/gmaps.js"></script>
  <!-- endbower -->
  <!-- endbuild -->

  <!-- build:js({testGrunt, .tmp}) js/main.js-->
  <script src="js/main.js"></script>
  <!-- endbuild -->
  </body>
</html>

Because of the similarity with the generator-webapp Gruntfile, I can't understand what is going wrong in my version, as they are almost carbon copies.


Solution

  • I found the problem. The path of the main.css was set incorrectly in the HTML file; it was searching for main.css in .tmp/css/main.css where it couldn't be found. It should have been looking in testGrunt/css/main.css