如何在保留文件夹结构的情况下使用grunt-uglify压缩多个脚本文件

17

我尚未找到一种好的方法来grunt-uglify多个分散在多个文件夹中的脚本文件,并保持包括缩小后的文件在内的文件夹结构。

我想这样做的唯一原因是为了增加我正在工作的网页的“旧版”部分的性能。

我已经找到了一个解决方法,但我不想这样做,因为这将花费太多时间,那就是按照这个答案中的方式执行(它们单独指定每个src和dest对):how to config grunt.js to minify files separately

我想要实现的示例:

**src dir (no uglify applied):**
src
 |- app1
    |- randomFile.js
    |- scripts
       |- file1.js
       |- file2.js
    |- libs
       |- file3.js
       |- file4.js
 |- app2
   |- scripts
       |- file1.js
       |- file2.js

**destination dir (uglify applied, same file name):**
dist
 |- app1
    |- randomFile.js
    |- scripts
       |- file1.js
       |- file2.js
    |- libs
       |- file3.js
       |- file4.js
 |- app2
    |- scripts
       |- file1.js
       |- file2.js

顺便问一下,如果可以的话,也想对CSS文件做同样的操作。

有人知道这是否可行吗?


我建议使用源代码映射 - Ismail
5个回答

24

Rafa Heringer在他的回答你链接的帖子中提出的原则看起来很有前途,只是稍微有些变化:

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

这里唯一的区别是在基本路径和通配符文件名及其扩展名之间有双星号。这将遍历所有子文件夹,并且希望能够在正确的文件夹中输出每个找到的内容。 输出结果将会是:
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

当涉及到使用grunt-contrib-cssmin插件进行相同操作时,上述方法仍然适用,但您需要将其与必须存在的相关插件配置组合以按您想要的方式输出缩小的CSS。请注意:我自己没有尝试运行它!

似乎可行,谢谢!我现在唯一的问题是让所有旧版JS文件通过Uglifier。 :s - KungWaz
虽然这很好,但问题在于它也会缩小已经被缩小的文件,因此如果您已经在这些目录中有.min.js文件,每次运行它都会创建.min.min.js等。如何解决这个问题? - Solomon Closson

15
与@DioNNiS的答案类似,但将缩小的文件存储在同一文件夹中:
    uglify: {
        all: {
            files: [{
                expand: true,
                cwd: 'path/to/js/',
                src: ['*.js', '!*.min.js'],
                dest: 'path/to/js/',
                ext: '.min.js'
            }]
        }
    }

7
实际上,您可以采用以下方法:
uglify: {
  all: {
    files: [{
      expand: true,
      cwd: 'js/',
      src: ['*.js', '**/*.js'],
      dest: 'js-min/',
      ext: '.min.js',
    }],
  },
}

2
Wallace的回答很好,但如果您试图缩小的文件在grunt开始之前不存在(即如果您依赖其他任务),它将无法工作,因为在运行任何任务之前生成映射。
我想出了一种解决方案,可以使用node包uglify-js逐个缩小生成的文件,而不是使用grunt-contrib-uglify。
  • 将uglify-js添加到您的package.json中
  • 将下面例子中的"YOUR FILES HERE"替换为适当的glob(s)之一,并添加到您的Grunfile中。
  • 如果您需要更改缩小后的文件目标位置或扩展名,请改用示例2。 它使用grunt.file.recurse并带有回调函数,该回调函数提供每个文件的根目录、子目录和文件名(然后更容易构建自定义目标路径)。 将"FOLDER"替换为要扫描的目录,并构建自己的"CUSTOM PATH HERE"。

示例1:使用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");
});

示例2:使用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

这个解决方案对我不起作用。

这是一个可行的例子:

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

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