const fs = require("fs"); const path = require("path"); const lodash = require("lodash"); const depts = {}; async function handle(filename) { if (path.extname(filename) !== ".js") { return; } const code = fs.readFileSync(filename).toString(); const inheritRegResult = /BI\.(.*?)\s=\sBI\.inherit\(/.exec(code); if (inheritRegResult) { const clzName = inheritRegResult[1]; depts[clzName] = filename; } else { // 一个文件夹里面可能有多个 xtype const reg = /export\s+class\s+(.*?)([\s|{])([\w\W]*?)static xtype\s?=\s?((["|'])(.*?)(\5))/g; Array.from(code.matchAll(reg)).forEach(res => { const xtype = res[4]; depts[xtype] = { clzName: res[1], clzPath: filename, }; }); // 同时找一下 export if (path.basename(filename) !== "index.js") { const regs = [ /export function (.*?)\(/g, /export const (.*?) =/g, /export class (.*?) /g, /export \{([\w\W]*?)\}/g, ]; regs.forEach((reg, index) => { Array.from(code.matchAll(reg)).forEach(el => { depts[el[1]] = filename; if (index === 3) { el[1].split(",").map(el => el.trim()).forEach(key => { depts[key] = filename; }); } }); }); } } } function isExist(filePath) { return fs.existsSync(filePath); } async function bfs(filename) { const stat = fs.statSync(filename); const isDir = stat.isDirectory(); if (isDir) { const files = fs.readdirSync(filename); for (let i = 0; i < files.length; i++) { const file = files[i]; await bfs(path.resolve(filename, file)); } } else { await handle(filename); } } async function initDepts() { // dfs 构建依赖关系 await bfs(path.resolve("src")); const m = {}; lodash.forEach(depts, value => { if (typeof value === "object") { m[value.clzName] = value.clzPath; } }); Object.assign(depts, m); } function search(src, module) { let clzName = module; let clzPath = depts[module]; if (!depts[clzName]) { return ""; } if (clzName.indexOf("\"") >= 0) { clzName = depts[module].clzName; clzPath = depts[module].clzPath; } const dstName = path.basename(clzPath).replace(/.js$/g, ""); const dstPath = path.normalize(clzPath).split("src")[1].split("\\").join("/").split("/"); const srcPath = path.normalize(src).split("src")[1].split("\\").join("/").split("/"); // console.log("src", src); // console.log("dst", depts[clzName]); dstPath.shift(); dstPath.pop(); srcPath.shift(); srcPath.pop(); const findDstIndexPath = (dstArr, startIndex) => { let i = startIndex; while (!isExist(path.resolve("src", dstArr.slice(0, i + 1).join("/"), "index.js")) && i < dstArr.length) { i++; } if (i < dstArr.length) { return dstArr.slice(startIndex, i + 1).join("/"); } else { return `${dstArr.slice(startIndex).join("/")}/${dstName}`; } }; // 不同包 if (dstPath[0] !== srcPath[0]) { return `@/${dstPath[0]}`; } // 同包 let i = 0; while (dstPath[i] === srcPath[i] && i < dstPath.length && i < srcPath.length) { i++; } // i 代表同名的位置 i--; // 没有匹配完 if (i < srcPath.length) { let result = ""; // 回溯,向上找,回到目录 i for (let j = srcPath.length - 1; j > i; j--) { result += "../"; } // 匹配过的下一个位置 i++; if (i >= dstPath.length) { // 越界 return `${result}${dstName}`; } else { // 看看这个目录下有没有 index return result + findDstIndexPath(dstPath, i); } } else if (i === srcPath.length) { if (i === dstPath.length) { return dstName; } else if (i < dstPath.length) { return findDstIndexPath(dstPath, i); } } } // search(process.argv[2], "Text").then(res => { // console.log(res); // }); exports.initDepts = initDepts; exports.search = search; exports.depts = depts;