Grunt cssmin缩小的CSS是空的

时间:2014-07-08 09:34:59

标签: gruntjs yeoman grunt-contrib-cssmin

我正在为我的项目开发一个Gruntfile。我将此Grunt文件基于generator-webapp Yeoman生成器中包含的Grunt文件。我的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时,除了一步之外,一切似乎都顺利。与generator-webapp一样,css文件被连接并写入.tmp文件夹。在此之后,cssmin应该读取这些连接文件,缩小它们并将它们写入desintation文件夹。但是,这并不适用于我的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>

由于与generator-webapp Gruntfile的相似性,我无法理解我的版本出了什么问题,因为它们几乎是副本。

2 个答案:

答案 0 :(得分:2)

这是我使用的确切解决方案。

下面我将(.tmp)更改为(.)

的index.html:

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

这是一个非常香草的AngularJS应用程序,用自耕农和咕噜声构建。

我使用grunt build:dist --verbose > grunt.log

找到了这个

答案 1 :(得分:1)

我发现了问题。 main.css的路径在HTML文件中设置不正确;它正在.tmp / css / main.css中搜索main.css,但却无法找到它。应该在testGrunt / css / main.css

中查找