【问题标题】:How to concatenate and minify multiple CSS and JavaScript files with Grunt.js (0.3.x)如何使用 Grunt.js (0.3.x) 连接和缩小多个 CSS 和 JavaScript 文件
【发布时间】:2012-11-22 16:35:00
【问题描述】:

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

我目前正在尝试使用 Grunt.js 设置一个自动构建过程,以首先连接然后缩小 CSS 和 JavaScript 文件。

我已经能够成功地连接和缩小我的 JavaScript 文件,尽管每次我运行 grunt 时它似乎只是附加到文件而不是覆盖它们。

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

就 grunt CSS 模块而言,我尝试过使用 consolidate-cssgrunt-csscssmin,但无济于事。无法理解如何使用它们!

我的目录结构如下(是一个典型的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. 如何将/public/css/ 文件夹下的所有css 文件连接并缩小到一个文件中,例如main.min.css
  2. 为什么 grunt.js 继续追加到 /public/js/ 下的串联和缩小的 JavaScript 文件 concat.jsconcat.min.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.x 移动到Grunt 1.x should not introduce many major changes

【问题讨论】:

    标签: javascript css concatenation minify gruntjs


    【解决方案1】:

    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'
      }
    }
    

    请注意,用法类似于内置的最小值。

    将您的 default 任务更改为

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

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

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

    【讨论】:

    • 你是个天才!当然,我从来没有想过如果我将concat 包含在同一个js 文件夹中,它会将它舀起来并附加它!我已经开始使用 cssmin 并且效果很好!再次感谢。
    • 太棒了,太棒了!但文件名总是concat.min.cssconcat.min.js。如果我修改某些内容,重新运行和部署,人们将不会获得最新版本,因为浏览器已经缓存了它。有什么方法可以随机命名文件并根据正确的&lt;link&gt;&lt;script&gt; 标签链接它们?
    • @TárcioZemel 您可以在文件名中包含 package.json 的版本:concat.min-&lt;%= pkg.version %&gt;.js
    • 你可以这样使用.dest cssmin: { css:{ src: '&lt;%= concat.css.dest %&gt;', dest: './css/all.min.css' } }` 是concat -&gt; css操作的结果
    【解决方案2】:

    我同意上面的回答。但这是 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模块中。
    • 为什么要在构建过程中处理所有这些复杂性并调用 jvm?只是无缘无故地放慢速度。
    【解决方案3】:

    我想在这里提一个非常非常有趣的技术,它被用于像 jQuery 和 Modernizr 这样的大型项目中用于连接事物。

    这两个项目都是完全用 requirejs 模块开发的(你可以在他们的 github repos 中看到),然后他们使用 requirejs 优化器作为一个非常智能的连接器。有趣的是,正如您所见,无论是 jQuery,Modernizr 都不需要 requirejs 来工作,这是因为他们删除了 requirejs 语法仪式,以便在他们的代码中摆脱 requirejs。所以他们最终得到了一个使用 requirejs 模块开发的独立库!多亏了这一点,他们能够执行库的 cutsom 构建,以及其他优势。

    对于所有对使用 requirejs 优化器进行串联感兴趣的人,请查看this post

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

    【讨论】:

    • 这很有趣,但与问题无关,因为 RequireJS 是一个模块加载器,它不会连接或缩小 AFAIK
    • 谢谢!你是对的,RequireJS 是一个模块加载器,它不会连接也不会缩小。但是 r.js(RequireJS 优化器 --> requirejs.org/docs/optimization.html)做到了。更具体地说,它将您的模块按依赖项排序。 Modernizr 和 jQuery 的人利用了该工具的排序算法并将其专门用作智能连接器。您可以查看他们的存储库以了解他们在做什么。
    • 使用 grunt 的 concat 或 uglify,结果文件是使用配置的指定源文件的顺序组成的。而 RequireJS 是基于依赖的。不同的方法可以达到相同的结果。
    【解决方案4】:

    你不需要添加 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']
            }
          }
        }
    

    【讨论】:

      【解决方案5】:

      我认为可能更自动化,grunt task usemin 会为你完成所有这些工作,只需要一些配置:

      https://stackoverflow.com/a/33481683/1897196

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-25
        • 1970-01-01
        • 2016-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-21
        相关资源
        最近更新 更多