Минимизированный CSS Grunt cssmin пуст

Я работаю над Gruntfile для своих проектов. Я создал этот файл Grunt на основе файла, включенного в генератор Yeoman generator-webapp. Мой Gruntfile выглядит так:

'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'
  ]);
};

Моя файловая структура выглядит следующим образом:

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

Когда я запускаю свой Gruntfile, кажется, что все идет хорошо, за исключением одного шага. Как и в случае с генератором и веб-приложением, файлы css объединяются и записываются в папку .tmp. После этого cssmin должен прочитать эти соединенные файлы, минимизировать их и записать в папку назначения. Однако этого не происходит для моего main.css. Он работает для объединения внешних файлов (т.е. библиотек, которые я включил в свой HTML). При выполнении Gruntfile появляется следующая ошибка:

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 написан правильно. Мой файл HTML, содержащий триггеры для concat и cssmin (потому что я использую 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>

Из-за схожести с генератором-webapp Gruntfile я не могу понять, что не так в моей версии, так как они почти копии.


person danielvdende    schedule 08.07.2014    source источник


Ответы (2)


Это точное решение, которое я использовал.

Ниже я изменил (.tmp) на (.)

индекс.html:

<!-- build:css(.) styles/main.css -->
<link rel="stylesheet" href="/app/styles/main.css">
<!-- endbuild -->

Это для очень ванильного приложения AngularJS, созданного с помощью yeoman и grunt.

Я узнал это, используя grunt build:dist --verbose > grunt.log

person Jess    schedule 16.07.2015
comment
Я бы добавил --no-color для облегчения чтения: grunt build:dist --verbose --no-color > grunt.log - person Esteban; 30.05.2016

Я нашел проблему. В HTML-файле неправильно указан путь к main.css; он искал main.css в .tmp/css/main.css, где его не удалось найти. Надо было искать в testGrunt/css/main.css

person danielvdende    schedule 08.07.2014
comment
Не могли бы вы предоставить фактическое исправление кода, которое вы использовали (я предполагаю, что тег ‹!--build --›)? какие версии usemin и cssmin также были бы полезны, так как они постоянно меняются - person ejfrancis; 20.02.2015