javascript 如何在保持文件夹结构的同时咕噜咕噜化多个脚本文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22045950/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 22:16:34  来源:igfitidea点击:

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

javascriptgruntjsgrunt-contrib-uglify

提问by KungWaz

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 only reason I want to do this is to be able to increase the performance of the "legacy" part of the web page I'm working on.

我还没有找到一种很好的方法来粗暴丑化分布在多个文件夹中的多个脚本文件,同时保持包括丑化文件在内的文件夹结构完整无缺。我想要这样做的唯一原因是能够提高我正在处理的网页“遗留”部分的性能。

I have found a way around this which I don't want to do, since it will take to much time, and that is to do it like in this answer (they specify each src and dest pair seperately): how to config grunt.js to minify files separately

我找到了一种解决方法,我不想这样做,因为这会花费很多时间,那就是像在这个答案中那样做(他们分别指定每个 src 和 dest 对): 如何配置 grunt。 js 分别缩小文件

An example of what I want to achieve:

我想要实现的一个例子:

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

Btw, want to do the same for CSS-files if possible.

顺便说一句,如果可能的话,想对 CSS 文件做同样的事情。

Does anyone know if this is possible?

有谁知道这是否可能?

回答by Wallace Sidhrée

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

对您链接的帖子Rafa Heringer的回答中的原则看起来很有希望,但略有不同:

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-cssminplugin), 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 CSSthe way you want.

当涉及到CSS(使用grunt-contrib-cssmin插件)做同样的事情时,上面提到的方法仍然有效,但你必须将它与相关的插件配置结合起来,这些配置必须以CSS你的方式输出缩小想。

PS: Haven't tried running it myself!

PS:没试过自己跑!

回答by tivnet

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

类似于@DioNNiS 的答案,但将缩小的文件存储在同一文件夹中

    uglify: {
        all: {
            files: [{
                expand: true,
                cwd: 'path/to/js/',
                src: ['*.js', '!*.min.js'],
                dest: 'path/to/js/',
                ext: '.min.js'
            }]
        }
    }

回答by DioNNiS

Actually you can use following approach:

其实你可以使用以下方法:

uglify: {
  all: {
    files: [{
      expand: true,
      cwd: 'js/',
      src: ['*.js', '**/*.js'],
      dest: 'js-min/',
      ext: '.min.js',
    }],
  },
}

回答by Thomas Roch

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.

Wallace 的回答很好,但是如果您尝试缩小的文件在 grunt 开始之前不存在(即,如果您依赖于另一个任务),它将无法工作,因为地图是在任何任务运行之前生成的。

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

我想出了一个单独缩小生成文件的解决方案,使用节点包 uglify-js 而不是 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".
  • 将 uglify-js 添加到您的 package.json
  • 将以下示例之一添加到您的 Grunfile(如果您使用的是示例 1,只需将“您的文件在这里”替换为适当的 glob(s))。
  • 如果您需要更改缩小后的文件目标或扩展名,请改用示例 2。它使用带有回调的 grunt.file.recurse ,该回调为您提供每个文件的根目录、子目录和文件名(然后构建自定义目标路径更容易)。将“FOLDER”替换为您要扫描的目录,然后构建您自己的“CUSTOM PATH HERE”。

Example 1:With grunt.file.expand

示例 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");
});

Example 2:With grunt.file.recurse

示例 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");
});

回答by v2p

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