给定一个路径和目录,返回在这个路径下所有可能存在当前目录的路径组合算法,摘自Node模块算法
一、声明一个保存node_modules逆序字符串(seludom_edon)的ASCII编码数组
// seludom_edon对应的编码
const nmChars = [ 115, 101, 108, 117, 100, 111, 109, 95, 101, 100, 111, 110 ];
二、算法
Module._nodeModulePaths = function(from) {
// 得到绝对路径
from = path.resolve(from);
// 如果是根目录,直接返回一个['/node_modules']
if (from === '/')
return ['/node_modules'];
// 存放所有可能存在node_modules的绝对路径数组
const paths = [];
// 用户筛选异常路径中可能包含的node_modules目录
var p = 0;
var last = from.length; // 路径的长度
// 反向遍历
for (var i = from.length - 1; i >= 0; --i) {
// 得到最后一个字符
const code = from.charCodeAt(i);
// CHAR_FORWARD_SLASH === '/' === 47
// 判断当前的编码是否为47
if (code === CHAR_FORWARD_SLASH) {
if (p !== nmLen) // 比对完一个目录 判断目录是否为node_modules,如果不是则拼接一个/node_modules路径放入paths数组
paths.push(from.slice(0, last) + '/node_modules');
last = i;// 记录当前比对到的字符为'/'的位置(剩余未比对路径的长度+1),用于拼接上一级目录+'/node_modules'
// 重置当前字符比对node_modules逆序时的相等相等的字符长度 如/a/modules_modules会跳过/a/modules_modules
// 直接加入paths,而是比对到/a后拼接得到一个/a/modules_modules加入paths目录
p = 0;
} else if (p !== -1) {
if (nmChars[p] === code) { // 判断当前获取的字符是否和node_modules逆序相同,用于匹配node_modules
++p;
} else {
p = -1;
}
}
}
// 最后追加一个根目录下的node_modules
paths.push('/node_modules');
return paths;
};
示例:'/a/b/c'
结果:['/a/b/c/node_modules','/a/b/node_modules','/a/node_modules','/node_modules']