如何使用Grunt.js(0.3.x)连接和缩小多个CSS和JavaScript文件


99

注意:此问题仅与Grunt 0.3.x有关,已留作参考。有关最新的Grunt 1.x版本的帮助,请参阅此问题下方的我的评论。

我目前正在尝试使用Grunt.js设置自动构建过程,以便首先进行串联,然后最小化CSS和JavaScript文件。

我已经能够成功地串联和最小化我的JavaScript文件,尽管每次运行grunt时,它似乎只是追加到文件中而不是覆盖它们。

至于缩小甚至连接CSS,到目前为止,我还无法做到这一点!

就笨拙的CSS模块而言,我尝试使用consolidate-cssgrunt-css&,cssmin但无济于事。无法理解如何使用它们!

我的目录结构如下(是一个典型的node.js应用程序):

  • app.js
  • grunt.js
  • /public/index.html
  • / public / css / [各种CSS文件]
  • / public / js / [各种javascript文件]

这是我的grunt.js文件当前在我的应用程序的根文件夹中的样子:

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: '<json:package.json>',
    concat: {
      dist: {
        src: 'public/js/*.js',
        dest: 'public/js/concat.js'
      }
    },
    min: {
      dist: {
        src: 'public/js/concat.js',
        dest: 'public/js/concat.min.js'
      }
    },
    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        node: true
      },
      globals: {
        exports: true,
        module: false
      }
    },
    uglify: {}
  });

  // Default task.
  grunt.registerTask('default', 'concat min');

};

因此,总结一下,我需要两个问题的帮助:

  1. 如何将文件夹下的所有CSS文件串联并缩小/public/css/为一个文件,例如main.min.css
  2. 为什么grunt.js不断追加到串联和精缩的JavaScript文件concat.js,并concat.min.js根据/public/js/,而不是每一个命令时覆盖它们grunt运行?

2016年7月5日更新-从Grunt 0.3.x升级到Grunt 0.4.x或1.x

Grunt.js已移至中的新结构Grunt 0.4.x(该文件现在称为Gruntfile.js)。请参阅我的开源项目Grunt.js Skeleton,以获取有关为设置构建过程的帮助Grunt 1.x

从过渡Grunt 0.4.xGrunt 1.x 不应引入许多重大变化

Answers:


107

concat.js已包含在concat任务的源文件中public/js/*.js。您可能需要执行以下任务:concat.js再次连接之前删除(如果文件存在),传递数组以显式定义要连接的文件及其顺序,或更改项目的结构。

如果要进行后者,则可以将所有源./src文件和构建文件放在下面./dest

src
├── css
   ├── 1.css
   ├── 2.css
   └── 3.css
└── js
    ├── 1.js
    ├── 2.js
    └── 3.js

然后设置您的concat任务

concat: {
  js: {
    src: 'src/js/*.js',
    dest: 'dest/js/concat.js'
  },
  css: {
    src: 'src/css/*.css',
    dest: 'dest/css/concat.css'
  }
},

您的最小任务

min: {
  js: {
    src: 'dest/js/concat.js',
    dest: 'dest/js/concat.min.js'
  }
},

内置min任务使用UglifyJS,因此您需要替换。我发现grunt-css很好。安装后,将其加载到您的grunt文件中

grunt.loadNpmTasks('grunt-css');

然后设置

cssmin: {
  css:{
    src: 'dest/css/concat.css',
    dest: 'dest/css/concat.min.css'
  }
}

请注意,用法类似于内置的min。

将您的default任务更改为

grunt.registerTask('default', 'concat min cssmin');

现在,运行grunt将产生您想要的结果。

dest
├── css
   ├── concat.css
   └── concat.min.css
└── js
    ├── concat.js
    └── concat.min.js

1
你是个天才!当然,如果我将它包含concat在同一js文件夹中,它不会把它挖出来并附加它,这对我来说从来没有发生过!我已经开始使用cssmin,效果很好!再次感谢。
Jasdeep Khalsa

1
很棒,真的很棒!但是文件名始终为concat.min.cssconcat.min.js。如果我修改了某些内容,然后重新运行和部署,人们将无法获得最新版本,因为浏览器已经对其进行了缓存。有一些方法可以随机命名文件并根据适当的<link><script>标记链接它们?
Tárcio泽梅尔

3
@TárcioZemel您可以在文件名中包含package.json的版本:concat.min-<%= pkg.version %>.js
Rui Nunes

1
您可以.dest像这样使用cssmin: { css:{ src: '<%= concat.css.dest %>', dest: './css/all.min.css'}}`这是操作的结果concat -> css
Ivan Black

12

我想在这里提及一种非常非常有趣的技术,该技术已在jQuery和Modernizr等大型项目中用于连接事物。

这两个项目都是完全使用requirejs模块开发的(您可以在其github仓库中看到它),然后它们将requirejs优化器用作非常聪明的连接器。如您所见,有趣的是,jQuery和Modernizr都不要求requirejs起作用,这之所以发生,是因为它们擦除了requirejs语法仪式以便在代码中摆脱requirejs。因此,它们最终得到了一个由requirejs模块开发的独立库!因此,他们能够执行自己库的cutsom构建以及其他优势。

对于所有对使用requirejs优化器进行连接感兴趣的人,请查看这篇文章。

还有一个小工具可以抽象化流程的所有样板:AlbanilJS


这非常有趣,但与问题无关,因为RequireJS是模块加载器,它不会串联或缩小AFAIK
Jasdeep Khalsa 2015年

谢谢!没错,RequireJS是模块加载器,它不连接也不缩小。但是r.js(RequireJS优化器-> requirejs.org/docs/optimization.html)可以做到。更具体地说,它将模块按依赖关系串联在一起。Modernizr和jQuery的开发人员利用了该工具的排序算法,并将其专门用作智能连接器。您可以检查他们的仓库以查看他们在做什么。
奥古斯托·奥特曼·夸兰塔

使用grunt的concat或uglify,结果文件将按照配置的指定源文件中的顺序组成。而RequireJS是基于依赖关系的。然而,不同的方法可以达到相同的结果。
priyabagus

10

我同意以上答案。但是这是CSS压缩的另一种方式。

您可以使用YUI压缩器连接 CSS :

module.exports = function(grunt) {
  var exec = require('child_process').exec;
   grunt.registerTask('cssmin', function() {
    var cmd = 'java -jar -Xss2048k '
      + __dirname + '/../yuicompressor-2.4.7.jar --type css '
      + grunt.template.process('/css/style.css') + ' -o '
      + grunt.template.process('/css/style.min.css')
    exec(cmd, function(err, stdout, stderr) {
      if(err) throw err;
    });
  });
}; 

如果您使用的是'grunt-css',则必须使用Locale Npm模块,因此请确保在安装'grunt-css'时必须在Locale Npm模块中。
Anshul 2012年

7
为什么要进行所有这些复杂操作并在构建过程中调用jvm?只是无缘无故放慢了一切。
迈克尔·鲑鱼2014年

3

您不需要添加concat软件包,可以通过cssmin做到这一点,如下所示:

cssmin : {
      options: {
            keepSpecialComments: 0
      },
      minify : {
            expand : true,
            cwd : '/library/css',
            src : ['*.css', '!*.min.css'],
            dest : '/library/css',
            ext : '.min.css'
      },
      combine : {
        files: {
            '/library/css/app.combined.min.css': ['/library/css/main.min.css', '/library/css/font-awesome.min.css']
        }
      }
    }

对于js,请像这样使用uglify:

uglify: {
      my_target: {
        files: {
            '/library/js/app.combined.min.js' : ['/app.js', '/controllers/*.js']
        }
      }
    }

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.