5

我正在为我的项目编写一个 grunt 任务文件。我已经sass在其中定义了任务并安装了所有必需的依赖项。我可以在我朋友的计算机上运行相同的 gruntfile,但在我的计算机上,sass 任务会产生此错误。

Running "sass:dist" (sass) task
Syntax error: Invalid CSS after "      webkit-image": expected ")", was ": -webkit- + $p..."
        on line 21 of /home/chitrank/Documents/shaastr/frontend/frontend/frontend/app/minovate/bower_components/bourbon/dist/helpers/_linear-angle-parser.scss
        from line 10 of /home/chitrank/Documents/shaastr/frontend/frontend/frontend/app/minovate/bower_components/bourbon/dist/_bourbon.scss
        from line 6 of app/sass/main.scss
  Use --trace for backtrace.
Warning: Exited with error code 1 Use --force to continue.

Aborted due to warnings.

由于这个错误,我无法执行 sass 任务,需要在我朋友的计算机上执行。我还添加了我的 Gruntfile.js,以便更好地了解我的 grunt 任务是什么以及它是如何工作的,请看一下。

'use strict';

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 for the application
  var appConfig = {
    app: require('./bower.json').appPath || 'app',
    dist: 'dist'
  };

  // Define the configuration for all the tasks
  grunt.initConfig({
// Project settings
yeoman: appConfig,

// Watches files for changes and runs tasks based on the changed files
watch: {
  bower: {
    files: ['bower.json'],
    tasks: ['wiredep']
  },
  js: {
    files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
    tasks: ['newer:jshint:all'],
    options: {
      livereload: '<%= connect.options.livereload %>'
    }
  },
  jsTest: {
    files: ['test/spec/{,*/}*.js'],
    tasks: ['newer:jshint:test', 'karma']
  },
  styles: {
    files: ['<%= yeoman.app %>/sass/{,*/}*.scss'],
    tasks: ['sass', 'newer:copy:styles', 'autoprefixer']
  },
  gruntfile: {
    files: ['Gruntfile.js']
  },
  livereload: {
    options: {
      livereload: '<%= connect.options.livereload %>'
    },
    files: [
      '<%= yeoman.app %>/{,*/}*.html',
      '<%= yeoman.app %>/views/tmpl/{,*/}*.html',
      '.tmp/styles/{,*/}*.css',
      '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
    ]
  }
},

// The actual grunt server settings
connect: {
  options: {
    port: 9000,
    // Change this to '0.0.0.0' to access the server from outside.
    hostname: '0.0.0.0',
    livereload: 35729
  },
  livereload: {
    options: {
      open: true,
      middleware: function (connect) {
        return [
          connect.static('.tmp'),
          connect().use(
            '/bower_components',
            connect.static('./bower_components')
          ),
          connect.static(appConfig.app)
        ];
      }
    }
  },
  test: {
    options: {
      port: 9001,
      middleware: function (connect) {
        return [
          connect.static('.tmp'),
          connect.static('test'),
          connect().use(
            '/bower_components',
            connect.static('./bower_components')
          ),
          connect.static(appConfig.app)
        ];
      }
    }
  },
  dist: {
    options: {
      open: true,
      base: '<%= yeoman.dist %>'
    }
  }
},

// Make sure code styles are up to par and there are no obvious mistakes
jshint: {
  options: {
    jshintrc: '.jshintrc',
    reporter: require('jshint-stylish')
  },
  all: {
    src: [
      'Gruntfile.js',
      '<%= yeoman.app %>/scripts/{,*/}*.js'
    ]
  },
  test: {
    options: {
      jshintrc: 'test/.jshintrc'
    },
    src: ['test/spec/{,*/}*.js']
  }
},

// compile sass files
sass: {
  dist: {
    files: [{
      expand: true,
      cwd: '<%= yeoman.app %>/sass',
      src: ['*.scss'],
      dest: '<%= yeoman.app %>/styles',
      ext: '.css'
    }],

    options: {
      loadPath: [
        './bower_components/bourbon/dist'
      ]
    }
  }
},

// Empties folders to start fresh
clean: {
  dist: {
    files: [{
      dot: true,
      src: [
        '.tmp',
        '<%= yeoman.dist %>/*',
        '!<%= yeoman.dist %>/.git*'
      ]
    }]
  },
  server: '.tmp'
},

// 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 app
wiredep: {
  app: {
    src: ['<%= yeoman.app %>/index.html'],
    ignorePath:  /\.\.\//
  }
},

// Renames files for browser caching purposes
filerev: {
  dist: {
    src: [
      '<%= yeoman.dist %>/scripts/{,*/}*.js',
      '<%= yeoman.dist %>/styles/{,*/}*.css',
      '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
      '<%= yeoman.dist %>/styles/fonts/*'
    ]
  }
},

// 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: {
  html: '<%= yeoman.app %>/index.html',
  options: {
    dest: '<%= yeoman.dist %>',
    flow: {
      html: {
        steps: {
          js: ['concat', 'uglifyjs'],
          css: ['cssmin']
        },
        post: {}
      }
    }
  }
},

// Performs rewrites based on filerev and the useminPrepare configuration
usemin: {
  html: ['<%= yeoman.dist %>/{,**/}*.html'],
  css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
  json: ['<%= yeoman.dist %>/scripts/jsons/*.json'],
  options: {
    assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/images']
  }
},

// The following *-min tasks will produce minified files in the dist folder
// By default, your `index.html`'s <!-- Usemin block --> will take care of
// minification. These next options are pre-configured if you do not wish
// to use the Usemin blocks.
// cssmin: {
//   dist: {
//     files: {
//       '<%= yeoman.dist %>/styles/main.css': [
//         '.tmp/styles/{,*/}*.css'
//       ]
//     }
//   }
// },
// uglify: {
//   options: {
//    mangle: { except: ["$super"] }
//   }
//   dist: {
//     files: {
//       '<%= yeoman.dist %>/scripts/scripts.js': [
//         '<%= yeoman.dist %>/scripts/scripts.js'
//       ]
//     }
//   },
// },
// concat: {
//   dist: {}
// },

uglify: {
  options: {
    mangle: { except: ['$super'] }
  }
},

imagemin: {
  dist: {
    files: [{
      expand: true,
      cwd: '<%= yeoman.app %>/images',
      src: '{,*/}*.{png,jpg,jpeg,gif}',
      dest: '<%= yeoman.dist %>/images'
    }]
  }
},

svgmin: {
  dist: {
    files: [{
      expand: true,
      cwd: '<%= yeoman.app %>/images',
      src: '{,*/}*.svg',
      dest: '<%= yeoman.dist %>/images'
    }]
  }
},

htmlmin: {
  dist: {
    options: {
      collapseWhitespace: true,
      conservativeCollapse: true,
      collapseBooleanAttributes: false,
      removeCommentsFromCDATA: true,
      removeOptionalTags: true
    },
    files: [{
      expand: true,
      cwd: '<%= yeoman.dist %>',
      src: ['*.html', 'views/{,*/}*.html', 'views/tmpl/{,*/}*.html'],
      dest: '<%= yeoman.dist %>'
    }]
  }
},

// ngmin tries to make the code safe for minification automatically by
// using the Angular long form for dependency injection. It doesn't work on
// things like resolve or inject so those have to be done manually.
ngmin: {
  dist: {
    files: [{
      expand: true,
      cwd: '.tmp/concat/scripts',
      src: '*.js',
      dest: '.tmp/concat/scripts'
    }]
  }
},

// Replace Google CDN references
cdnify: {
  dist: {
    html: ['<%= yeoman.dist %>/*.html']
  }
},

// Copies remaining files to places other tasks can use
copy: {
  dist: {
    files: [{
      expand: true,
      dot: true,
      cwd: '<%= yeoman.app %>',
      dest: '<%= yeoman.dist %>',
      src: [
        '*.{ico,png,txt}',
        '.htaccess',
        '*.html',
        'views/**/*',
        'images/{,*/}*.{webp}',
        'fonts/*'
      ]
    }, {
      expand: true,
      cwd: '.tmp/images',
      dest: '<%= yeoman.dist %>/images',
      src: ['generated/*']
    }, {
      expand: true,
      cwd: 'bower_components/bootstrap/dist',
      src: 'fonts/*',
      dest: '<%= yeoman.dist %>'
    }, {
      expand: true,
      cwd: 'bower_components/simple-line-icons',
      src: 'fonts/*',
      dest: '<%= yeoman.dist %>'
    }, {
      expand: true,
      cwd: 'bower_components/font-awesome',
      src: 'fonts/*',
      dest: '<%= yeoman.dist %>'
    }, {
      expand: true,
      cwd: 'bower_components/weather-icons',
      src: 'font/*',
      dest: '<%= yeoman.dist %>'
    }, {
      expand: true,
      cwd: '<%= yeoman.app %>/scripts',
      src: ['jsons/**','modules/**','vendor/**'],
      dest: '<%= yeoman.dist %>/scripts'
    }]
  },
  styles: {
    expand: true,
    cwd: '<%= yeoman.app %>/styles',
    dest: '.tmp/styles/',
    src: '{,*/}*.css'
  }
},

// Run some tasks in parallel to speed up the build process
concurrent: {
  server: [
    'copy:styles'
  ],
  test: [
    'copy:styles'
  ],
  dist: [
    'copy:styles',
    'imagemin',
    'svgmin'
  ]
},

// Test settings
karma: {
  unit: {
    configFile: 'test/karma.conf.js',
    singleRun: true
  }
},

// grunt-text-replace

replace: {
  html_js_css_images_rep: {
    src: ['dist/scripts/*.js', 
    'dist/styles/*.css',
    'dist/*.html',
    'dist/views/*.html' ,
    'dist/views/tmpl/*.html' ,
    'dist/views/tmpl/forms/*.html',
    'dist/views/tmpl/layouts/*.html',
    'dist/views/tmpl/mail/*.html',
    'dist/views/tmpl/maps/*.html',
    'dist/views/tmpl/pages/*.html',
    'dist/views/tmpl/shop/*.html',
    'dist/views/tmpl/tables/*.html',
    'dist/views/tmpl/ui/*.html'
    ],
    //dest: ['dist/scripts/'],
    overwrite: true,
    replacements: [{
      from: 'http://127.0.0.1:8000',
      to: ''
    },
    {
      from: 'http://localhost:8000',
      to: ''
    },
    {
      from: 'views/',
      to: 'static/views/'
    },
    {
      from: 'scripts/',
      to: 'static/scripts/'
    },
    {
      from: 'styles/',
      to: 'static/styles/'
    },
    {
      from: 'images/',
      to: 'static/images/'
    }]
  }


}




 });



// adding the text replace grunt plugin 
  grunt.loadNpmTasks('grunt-text-replace');



  grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

grunt.task.run([
  'clean:server',
  'wiredep',
  'concurrent:server',
  'sass',
  'autoprefixer',
  'connect:livereload',
  'watch'
]);


});



grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
    grunt.task.run(['serve:' + target]);
  });

  grunt.registerTask('test', [
    'clean:server',
    'concurrent:test',
    'autoprefixer',
    'connect:test',
    'karma'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'wiredep',
    'useminPrepare',
    'sass',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'ngmin',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'filerev',
    'usemin',
    'htmlmin',
    'replace'
  ]);

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

如果有人在此之前解决了这个问题,请告诉我。

4

1 回答 1

1

这个讨论说这个问题是由 Sass 和 Bourbon 版本之间的不兼容引起的。

Bourbon 4 至少需要 Sass 3.3,因此如果您运行的是较低版本,则需要将 Bourbon 降级到 3.x 或升级 Sass

于 2015-08-13T21:49:58.987 回答