fis-kernel icon indicating copy to clipboard operation
fis-kernel copied to clipboard

_.find 的性能问题

Open liunian opened this issue 7 years ago • 0 comments

_.find 中存在一个问题,即便 设定了 exclude 某目录,但如果有 include 规则,那么会递归扫描目录下的所有文件。扫描完成后才把所有的文件按照 include、exclude 规则来过滤。

_.find = function(rPath, include, exclude, root){
    var list = [],
        path = _.realpath(rPath),
        filterPath = root ? path.substring(root.length) : path;
    if(path){
        var stat = fs.statSync(path);
        if(stat.isDirectory() && (include || _.filter(filterPath, include, exclude))){
            fs.readdirSync(path).forEach(function(p){
                if(p[0] != '.') {
                    list = list.concat(_.find(path + '/' + p, include, exclude, root));
                }
            });
        } else if(stat.isFile() && _.filter(filterPath, include, exclude)) {
            list.push(path);
        }
    } else {
        fis.log.error('unable to find [' + rPath + ']: No such file or directory.');
    }
    return list.sort();
};

在大项目中,如大规模的基于 react/angular 等的方案下,由于 node_modules 的依赖,扫描的内容将很多。特别是在 cnpm 的机制中(npminstall 的加速安装方式),依赖拉平,软链接的形式,在扫描文件的时候会直接陷入死循环状态直至内存溢出崩溃。

建议优化下处理逻辑,扫描到一个目录时,同时判断目录是否 exclude,如果 exclude 了,那么就不递归扫描该目录了。

示例(在大项目中(如 react 系列)使用 npm3)

app
├── node_modules/
└── src/
    ├── exclude/
    ├── a/
    └── b/
// root 是项目根目录
_.find(root, ['src/'], [/\/exclude/], root)

liunian avatar Jul 14 '17 13:07 liunian