How to grunt-uglify multiple script files while keeping folder structure

后端 未结 5 1722

I have not found a good way to grunt-uglify multiple script files spread over multiple folders while keeping the folder structure including the uglified files intact. The on

相关标签:
5条回答
  • 2020-12-23 23:04

    The answer from Wallace is great, but if the files you are trying to minify don't exist before grunt starts (i.e. if you are depending on another task), it won't work because the map is generated before any task is run.

    I came up with a solution for minifying generated files individually, using the node package uglify-js instead of grunt-contrib-uglify.

    • Add uglify-js to your package.json
    • Add one of the following example to your Grunfile (just replace "YOUR FILES HERE" by the appropriate glob(s) if you are using Example 1).
    • If you need to change the minified file destination or extension, use Example 2 instead. It uses grunt.file.recurse with a callback which provides you with the root directory, sub directory and file name of each file (it is easier then to build a custom destination path). Replace "FOLDER" by the directory you want to scan, and build your own "CUSTOM PATH HERE".

    Example 1: With grunt.file.expand

    grunt.registerTask('uglifyFiles', 'Uglifies files', function () {
        var jsp = require("uglify-js").parser,
            pro = require("uglify-js").uglify,
            count = 0;
    
        grunt.file.expand(['YOUR FILES HERE']).forEach(function (abspath) {
            // Exclude already minified files (with extension .min.js)
            if (!abspath.match(/\.min\.js$/i)) {
                // Get Abstract Syntax Tree
                var ast = jsp.parse(grunt.file.read(abspath));
                // If mangling
                // ast = pro.ast_mangle(ast);
                // If squeezing
                ast = pro.ast_squeeze(ast);
                // Write new file
                grunt.file.write(abspath.replace(/\.js$/i, '.min.js'), pro.gen_code(ast));
                count += 1;
            }
        });
    
        grunt.log.oklns("Successfully uglified " + count + " files");
    });
    

    Example 2: With grunt.file.recurse

    grunt.registerTask('uglifyFiles', 'Uglifies files', function () {
        var jsp = require("uglify-js").parser,
            pro = require("uglify-js").uglify,
            count = 0;
    
        grunt.file.recurse('FOLDER', function callback(abspath, rootdir, subdir, filename) {
            // Exclude already minified files (with extension .min.js)
            if (!abspath.match(/\.min\.js$/i)) {
                // Get Abstract Syntax Tree
                var ast = jsp.parse(grunt.file.read(abspath));
                // If mangling
                // ast = pro.ast_mangle(ast);
                // If squeezing
                ast = pro.ast_squeeze(ast);
                // Write new file, using abspath or rootdir, subdir and filename
                grunt.file.write('CUSTOM PATH HERE', pro.gen_code(ast));
                count += 1;
            }
        });
    
        grunt.log.oklns("Successfully uglified " + count + " files");
    });
    
    0 讨论(0)
  • 2020-12-23 23:07

    This solution not working for me.

    This is working example:

            path: {
                build: {
                   src: 'assets',
                   js: 'js',
                   css: 'css'
                },
                js: 'js',
                css: 'css'
            },
            uglify: {
                scripts: {
                    expand: true,
                    cwd: '<%= path.js %>/',
                    src: [
                        '**/*.js', 
                        '*.js',
                        //skip minified scripts
                        '**/!*.min.js', 
                        '!*.min.js'
                    ],
                    dest: '<%= path.build.src %>/<%= path.build.js %>/',
                    rename: function (destBase, destPath) {
                        return destBase + destPath.replace('.js', '.min.js');
                    }
                }
            },
            //same options for css minify
            cssmin: {
                styles: {
                    expand: true,
                    cwd: '<%= path.css %>/',
                    src: [
                        '**/*.css',
                        '*.css',
                        //skip minified styles
                        '**/!*.min.css', 
                        '!*.min.css'
                    ],
                    dest: '<%= path.build.src %>/<%= path.build.css %>/',
                    rename: function (destBase, destPath) {
                        return destBase + destPath.replace('.css', '.min.css');
                    }
                }
            },
            //and watch it for changes
            watch: {
                js: {
                    files: [
                        '<%= path.js %>/*.js',
                        '<%= path.js %>/**/*.js'
                    ],
                    tasks: [
                        'uglify:scripts'
                    ],
                    options: {
                        livereload: true
                    }
                },
                css: {
                    files: [
                        '<%= path.css %>/*.css',
                        '<%= path.css %>/**/*.css'
                    ],
                    tasks: [
                        'cssmin:styles'
                    ],
                    options: {
                        livereload: true
                    }
                }
            }
    
    • grunt 0.4.1
    • grunt-contrib-uglify 0.9.1
    • grunt-contrib-cssmin 0.12.2
    • grunt-contrib-watch 0.6.1
    0 讨论(0)
  • 2020-12-23 23:11

    The principle in Rafa Heringer's answer on the post you linked to looks promising, with a little twist:

    uglify: {
        min: {
            files: grunt.file.expandMapping(['path/**/*.js', 'path2/**/*.js'], 'destination/', {
                rename: function(destBase, destPath) {
                    return destBase+destPath.replace('.js', '.min.js');
                }
            })
        }
    }
    

    The only difference here is the double asterisk between the base path and the wildcard filename with its extension. That will go through all the sub-folders and - hopefully - output each find it finds in its rightful folder.

    The output would be:

    path/test.js => destination/path/test.min.js
    path/subpath1/abc.js => destination/path/subpath1/abc.min.js
    path/subpath2/yey.js => destination/path/subpath2/yey.min.js
    path2/foo.js => destination/path2/foo.min.js
    

    When it comes to doing the same with CSS (using the grunt-contrib-cssmin plugin), the approach mentioned above would still work, but you would have to combine it with the relevant plugin configurations that must be in place to output minified CSS the way you want.

    PS: Haven't tried running it myself!

    0 讨论(0)
  • 2020-12-23 23:18

    Similar to the answer by @DioNNiS, but stores minified files in the same folder:

        uglify: {
            all: {
                files: [{
                    expand: true,
                    cwd: 'path/to/js/',
                    src: ['*.js', '!*.min.js'],
                    dest: 'path/to/js/',
                    ext: '.min.js'
                }]
            }
        }
    
    0 讨论(0)
  • 2020-12-23 23:21

    Actually you can use following approach:

    uglify: {
      all: {
        files: [{
          expand: true,
          cwd: 'js/',
          src: ['*.js', '**/*.js'],
          dest: 'js-min/',
          ext: '.min.js',
        }],
      },
    }
    
    0 讨论(0)
提交回复
热议问题