如何让 'grunt less' 自动运行 autoprefixer?

6

我有一个能够使用less和autoprefixer的可用Gruntfile文件,'grunt watch'也可以正常工作。

在使用autoprefixer之前,我使用了less mixins来添加供应商前缀。 运行'grunt less'将生成带有所有前缀的工作CSS。

现在我有了autoprefixer,但是如果我想一次性构建我的样式,那么我现在必须运行'grunt less'然后再运行'grunt autoprefixer'才能获得带有前缀的工作CSS。

如何修改'grunt less'以便再次构建有效的、带有前缀的less样式?

我已经阅读了文档,并且知道我可以添加一个额外的任务来执行这些操作。 但是:

  • 'grunt less'现在没有可用的输出。 任务应始终生成可用的输出。
  • 我不想告诉其他人'grunt less'没有产生可用的输出
  • 不需要添加其他任务来替换不起作用的任务

即,我只想要grunt less生成有效的CSS(带有前缀)

module.exports = function(grunt) {

  // Load Grunt tasks declared in the package.json file
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

  // Configure Grunt
  grunt.initConfig({

    less: {
      development: {
        options: {
          paths: ["./less"],
          yuicompress: false
        },
        files: {
          "./public/css/style.css": "./public/less/style.less"
        }
      }
    },

    autoprefixer: {
      development: {
        browsers: ['last 2 version', 'ie 9'],
        expand: true,
        flatten: true,
        src: 'public/css/*.css',
        dest: 'public/css'
      }
    },

    watch: {
      less: {
        files: ["./public/less/*"],
        tasks: ["less", "autoprefixer:development"],
        options: {
          livereload: true
        }
      }
    },

  });


};
2个回答

10

如果要将autoprefixer用作LESS的插件,您必须安装npm包less-plugin-autoprefix

npm install grunt-contrib-less less-plugin-autoprefix --save-dev

Gruntfile.js

module.exports = function(grunt) {
  "use strict";
  var gruntConfig = {
    less : {
      options : {
        plugins : [ new (require('less-plugin-autoprefix'))({browsers : [ "last 2 versions" ]}) ]
      },
      main : {
        files: {
          'src/css/desktop/bootstrap-theme.css' : 'src/less/desktop/bootstrap-theme.less',
          'src/css/desktop/company.css' : 'src/less/desktop/company.less',
          'src/css/desktop/index.css' : 'src/less/desktop/index.less',
          'src/css/desktop/login.css' : 'src/less/desktop/login.less'
        }
      }
    }
  };

  grunt.initConfig(gruntConfig);
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.registerTask('default', [ 'less' ]);
};

2
这个可以工作 - 但是你需要 grunt-contrib-less 1.0.0 或更高版本来使用 LESS 插件。https://medium.com/@crisnoble/using-new-less-plugins-with-your-build-process-571ef543166d 是一个很好的概述。 - timbo

8

Grunt不能做到你在问题中描述的那样,因为任务本质上不知道彼此。您必须使用别名(简单)或函数(当您想要更多控制时)将任务粘合在一起,但是没有办法修改其中一个任务的行为方式而不改变源代码。

例如,您可以复制grunt-contrib-less并将代码添加到任务中,直接运行自动前缀,大约在这里:https://github.com/gruntjs/grunt-contrib-less/blob/master/tasks/less.js#L69 - 在此处插入此行https://github.com/nDmitry/grunt-autoprefixer/blob/master/tasks/autoprefixer.js#L56,然后使用您的分支代替官方插件。

最简单和最好的方法是注册一个新任务,该任务执行这两个任务的工作,但在一个命令中完成,即:

grunt.registerTask('buildless', ['less', 'autoprefixer']);

我对自己的所有任务都这样做 - SASS编译,JS合并+混淆,Web字体生成等。只需告诉团队中的其他人运行这些任务,而不是单独运行 "grunt less" 或 "grunt autoprefixer"。
更好的方法是,使用我的Grunt插件可用任务。通过这种方式(以及过滤器配置),每当有人运行 "grunt availabletasks" 时,您将能够生成一个精简的任务列表,尽管我更喜欢将其别名为 "tasks",以便更快地输入。如果您像我一样被自动化 bug 所咬,并在 Gruntfile 中注册了大量插件,那么这确实可以帮助项目中的新手确定应该运行哪些任务。

谢谢您的回答,但正如问题中所提到的,我特别不想添加另一个任务。 - mikemaccana
Grunt任务不知道其他Grunt任务,您需要编写一个自定义任务函数,可以为less和autoprefixer任务设置属性,然后只有一个配置块(不建议,至少需要几个小时)。别名任务的整个重点是为您解决此问题,这是最简单,最好的方法。我不确定您为什么反对这一点,但这就是Grunt的工作方式。 - Ben
“我不确定你为什么这么反对” - 我不想再接受另一个任务的原因在问题中用项目符号列出。 - mikemaccana
2
那么唯一的答案就是分叉grunt-contrib-less并将代码直接添加到任务中以运行自动前缀,大约在这里:https://github.com/gruntjs/grunt-contrib-less/blob/master/tasks/less.js#L69 - 在此处注入此行 https://github.com/nDmitry/grunt-autoprefixer/blob/master/tasks/autoprefixer.js#L56,然后使用您的分支而不是官方插件。或者使用Gulp,它比Grunt具有更简单的配置样式-https://github.com/wearefractal/gulp-但超出了本问题的范围。 - Ben
谢谢。如果您将其作为主要答案(如果正确的话,我可以接受“grunt无法做到”),我会将其标记为已接受的答案。 - mikemaccana
1
好的,我已经完成了。我提到了 Gulp,它仍处于早期开发阶段,但配置更接近您所提到的:在 Gulp 中,您只需要注册一个任务来执行 less、autoprefixing 等操作 - 没有配置,只有代码。然而,这些插件还没有被编写,因此它还不能完全替代。 - Ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接