grunt usemin 2 different concat configs for js and css

1.1k views Asked by At

I'm using grunt usemin to optimize my css and js files. I want to customize concat:generated task for css files only, not js files. But i noticed that the generated config uses the same options for this task even if i specify css key in the post object :

module.exports = function(grunt) {
    require('load-grunt-tasks')(grunt);
    grunt.initConfig({

        copy: {
            ejs: {
                src: 'index.html',
                dest: 'index.prod.html'
            }
        },

        useminPrepare: {
            html: 'index.html',
            options: {
                dest: 'static',
                root: 'static',
                flow: {
                    steps: {
                        'js': ['concat', 'uglifyjs'],
                        'css': ['concat', 'cssmin']
                    },
                    post: {
                        js: [{
                            name: 'uglify',
                            createConfig: function (context, block) {
                                // console.log('\ncontext:\n',context,'\nblock:\n',block);
                                context.options.generated.options = {
                                    // options for uglify:generated task
                                };
                            }
                        }],
                        css: [{
                            name: 'concat',
                            createConfig: function (context, block) {
                                // console.log('\ncontext:\n',context,'\nblock:\n',block);
                                context.options.generated.options = {
                                    process: function (src, filepath) {
                                        // options for concat:generatedCSS
                                        console.log('\nfilepath: ', filepath);
                                        return src;
                                    }
                                };
                            }
                        }]
                    }
                }
            }
        },

        usemin: {
            html: [ 'index.prod.html' ]
        }

    });

    grunt.registerTask('default', ['watch']);
    grunt.registerTask('min', ['copy', 'useminPrepare', 'concat', 'uglify', 'usemin']);

};

The generated concat task is

concat: {
    generated: {
        files: [
            {
                dest: 'path to optimized css',
                src: [ 'css files...' ]
            },
            {
                dest: 'path to optimized js',
                src: [ 'js files...' ]
            }
        ],
        options: { process: [Function] }
    }
}

Is there a way to implement this? Thanks

2

There are 2 answers

0
phuong On

Unfortunately usemin does not support your scenario. But you can do it as a trick:

  • Config global concat/uglify to match your requirements for both CSS/JS files
  • Reserve engineering for each case CSS or JS to fix it

For example if I want to concat only JS files by the ; separator, I can do this:

  1. concat configuration for both CSS/JS

    concat: {
        generated: {
            options: {
                separator: grunt.util.linefeed + ";" + grunt.util.linefeed
            }
        }
    }
    
  2. remove all ; separators - wrong in CSS files

    replace: {
        cssConcat: {
            src: ["<%=pkg.public%>generate-resources/*.css"],
            dest: "<%=pkg.public%>generate-resources/",
            replacements: [{from: "};", to: "}"}]
        }
    }
    

Hope this help

0
Auke On

I had the same question because I concatenated both CSS and JavaScripts. The Javascripts where also partly 3rd party dependencies which I had no control over, but wanted to concatenate (not uglify) them anyway. There were some files that I couldn't concatenate with the default separator (\n).

Here's what I came up with in the end:

concat: {
  options: {
    process: function(src, filepath) {
      // output an extra semicolon when concatenating javascripts
      if (/\.js$/.test(filepath)) {
        return src + ';';
      }

      return src;
    }
  }
},

Basically whatever you specify in concat will be merged with the configuration that the useminPrepare task will generate for you. You can directly specify a separator option in this concat configuration as well, however that will be a separator for both the CSS and the JS which doesn't really help.

Here I check to see if it's a JavaScript file with a very basic extension check and return the source of the file with a ; appended.