forked from fanruan/fineui
Treecat
2 years ago
3 changed files with 19 additions and 710 deletions
@ -0,0 +1,19 @@
|
||||
module.exports = { |
||||
plugins: [ |
||||
[ |
||||
"@babel/plugin-proposal-decorators", |
||||
{ |
||||
legacy: true |
||||
} |
||||
], |
||||
[ |
||||
"module-resolver", |
||||
{ |
||||
root: ["./src"], |
||||
alias: { |
||||
"@": "./src" |
||||
} |
||||
} |
||||
] |
||||
] |
||||
}; |
@ -1,538 +0,0 @@
|
||||
const fs = require("fs"); |
||||
const path = require("path"); |
||||
const prettier = require("prettier"); |
||||
const { exec } = require("child_process"); |
||||
const { search, initDepts, depts } = require("./es6.xtype"); |
||||
const lodash = require("lodash"); |
||||
const DEPTS = depts; |
||||
|
||||
// const XTYPE_ONLY = false;
|
||||
// const THIS_REPLACE = false;
|
||||
|
||||
const ConflictImport = []; |
||||
const CircularDependency = []; |
||||
|
||||
function objHaveFunction(obj) { |
||||
if (obj === null) { |
||||
return false; |
||||
} |
||||
|
||||
return Object.keys(obj).some(key => { |
||||
const value = obj[key]; |
||||
if (typeof value === "object") { |
||||
return objHaveFunction(value); |
||||
} else if (typeof value === "function") { |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
}); |
||||
} |
||||
|
||||
function parserImport(code) { |
||||
const reg = /import {([\s\S]*?)} from "(.*?)";/g; |
||||
|
||||
const importMap = {}; |
||||
let regResult = reg.exec(code); |
||||
while (regResult) { |
||||
importMap[regResult[2]] = regResult[1] |
||||
.split(",") |
||||
.map(el => el.trim()) |
||||
.filter(el => el); |
||||
regResult = reg.exec(code); |
||||
} |
||||
|
||||
return importMap; |
||||
} |
||||
|
||||
async function saveAndFixCode(path, code) { |
||||
let _code = code; |
||||
if (!code) { |
||||
_code = fs.readFileSync(path).toString(); |
||||
} |
||||
const prettierCode = prettier.format(_code, { |
||||
tabWidth: 4, |
||||
parser: "babel", |
||||
printWidth: 120, |
||||
}); |
||||
fs.writeFileSync(path, prettierCode); |
||||
|
||||
new Promise(res => { |
||||
exec(`yarn eslint --fix ${path}`, () => { |
||||
res(); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
function divideFile(srcName) { |
||||
const targetPath = srcName.match(/.*\//g); |
||||
const sourceCode = fs.readFileSync(srcName).toString(); |
||||
const splitSourceCode = sourceCode.match(/[\.\s]{1}[^\s\.]+?\s=\sBI\.inherit\([^]*?BI\.shortcut.*\;/g); |
||||
const newFileNames = []; |
||||
for (let i = 0; i < splitSourceCode.length; i++) { |
||||
// 去除开头的 空格 或者 .
|
||||
const newCode = splitSourceCode[i].slice(1); |
||||
// 匹配第一个等号之前的组件名
|
||||
const componentName = /BI\.shortcut\("(.*)"/.exec(newCode)[1]; |
||||
// 文件名转化 ButtonIcon => demo.button.icon.js
|
||||
const demoFileName = componentName + '.js'; |
||||
newFileNames.push(demoFileName); |
||||
// 代码 componentName 前面加上 BI.
|
||||
const fileCode = 'BI.' + newCode; |
||||
|
||||
// 规范最后一行的组件为 BI.Button
|
||||
const targetComponet = /(BI\..*)\s=/.exec(fileCode)[1]; |
||||
// 最后一行的内容
|
||||
const replaceContext = /BI\.shortcut.*;/.exec(fileCode)[0]; |
||||
// 替换
|
||||
const finalCode = fileCode.replace(replaceContext,`BI.shortcut("${componentName}", ${targetComponet});`) |
||||
|
||||
// 创建新文件
|
||||
fs.writeFileSync(targetPath + demoFileName, finalCode); |
||||
} |
||||
return newFileNames; |
||||
} |
||||
|
||||
// const target = [];
|
||||
|
||||
// 加载模块
|
||||
const loader = { |
||||
// G: { "@/core": { shortcut: true } },
|
||||
load(srcName, module) { |
||||
const G = loader.G; |
||||
// if (target.indexOf(module) >= 0) {
|
||||
// G["@/core"][module] = true;
|
||||
|
||||
// return true;
|
||||
// }
|
||||
if (module.startsWith('"bi.')) { |
||||
const key = search(srcName, module); |
||||
if (key) { |
||||
if (!G[key]) { |
||||
G[key] = {}; |
||||
} |
||||
const clzName = depts[module].clzName; |
||||
G[key][clzName] = true; |
||||
} |
||||
|
||||
return !!key; |
||||
} else { |
||||
const key = search(srcName, module); |
||||
if (key) { |
||||
if (!G[key]) { |
||||
G[key] = {}; |
||||
} |
||||
G[key][module] = true; |
||||
} |
||||
|
||||
return !!key; |
||||
} |
||||
}, |
||||
}; |
||||
|
||||
async function handleFile(srcName) { |
||||
await saveAndFixCode(srcName); |
||||
// 全局状态回归
|
||||
let G = (loader.G = {}); |
||||
|
||||
const sourceCode = fs.readFileSync(srcName).toString(); |
||||
if (sourceCode.match(/shortcut/g).length > 1) { |
||||
console.log('该文件存在多处BI.shorcut, 需要拆分...'); |
||||
const newTargets = divideFile(srcName); |
||||
newTargets.forEach(name => console.log(name)); |
||||
return; |
||||
} |
||||
|
||||
const result = /BI\.(.*?)\s=\sBI\.inherit\(/.exec(sourceCode); |
||||
|
||||
if (!result) { |
||||
// console.log(`已经es6过,替换 xtype => ${srcName}`);
|
||||
if (!/export class/.test(sourceCode)) { |
||||
// console.log("忽略文件", srcName);
|
||||
|
||||
return; |
||||
} |
||||
|
||||
// 处理 xtype
|
||||
const noXtypeCode = sourceCode.replace(/type:\s?"bi\.(.*?)"/g, v => { |
||||
const matchedSentence = v.replace(/type:\s?/, ""); |
||||
const loadSuccess = loader.load(srcName, matchedSentence); |
||||
if (loadSuccess) { |
||||
const clzName = depts[matchedSentence].clzName; |
||||
|
||||
return `type: ${clzName}.xtype`; |
||||
} else { |
||||
console.log(`xtype 替换失败 ${matchedSentence} `); |
||||
|
||||
return v; |
||||
} |
||||
}); |
||||
// 识别 import
|
||||
const importMap = parserImport(noXtypeCode); |
||||
|
||||
// 合并原来的 import 到 G
|
||||
lodash.forEach(importMap, (depts, module) => { |
||||
depts.forEach(dept => { |
||||
if (!G[module]) { |
||||
G[module] = {}; |
||||
} |
||||
|
||||
G[module][dept] = true; |
||||
}); |
||||
}); |
||||
|
||||
|
||||
// 合并包
|
||||
const crossPackages = fs.readdirSync("src").map(el => `@/${el}`); |
||||
lodash.forEach(G, (depts, module) => { |
||||
crossPackages.forEach(crosspackage => { |
||||
if (module.indexOf(crosspackage.replace(/^@\//, "")) >= 0) { |
||||
if (!G[crosspackage]) { |
||||
G[crosspackage] = {}; |
||||
} |
||||
Object.assign(G[crosspackage], depts); |
||||
} |
||||
}); |
||||
}); |
||||
const tmpG = {}; |
||||
lodash.forEach(G, (depts, module) => { |
||||
const flag = lodash.some( |
||||
crossPackages, |
||||
crosspackage => |
||||
module.indexOf(crosspackage) >= 0 && !module.startsWith("@"), |
||||
); |
||||
if (!flag) { |
||||
tmpG[module] = depts; |
||||
} |
||||
}); |
||||
|
||||
let circle = false; |
||||
// 处理循环依赖,base: ["@/case", "@/base", "@/widget"] 等于 base 不能直接引数组内的包
|
||||
const forbiddenCrossRules = { |
||||
base: ["@/case", "@/base", "@/widget"], |
||||
"case": ["@/case", "@/widget"], |
||||
widget: ["@/widget"], |
||||
component: ["@/component"], |
||||
core: ["@/core", "@base", "@/widget", "@/case"], |
||||
}; |
||||
|
||||
const forbiddenKeys = []; |
||||
const circleG = {}; |
||||
|
||||
lodash.forEach(G, (depts, module) => { |
||||
// 找出 rule
|
||||
const packages = Object.keys(forbiddenCrossRules); |
||||
|
||||
let key = packages.filter( |
||||
_package => srcName.indexOf(_package) >= 0, |
||||
); |
||||
if (key.length !== 1) { |
||||
throw new Error( |
||||
"理论不可能出现这个问题,需要 treecat 优化下找包逻辑1", |
||||
); |
||||
} |
||||
key = key[0]; |
||||
const rule = forbiddenCrossRules[key]; |
||||
|
||||
if (lodash.includes(rule, module)) { |
||||
circle = true; |
||||
|
||||
const deptsArr = Object.keys(depts); |
||||
if (deptsArr.filter(dept => !DEPTS[dept]).length > 0) { |
||||
throw new Error( |
||||
"理论不可能出现这个问题,需要 treecat 优化下找包逻辑2", |
||||
); |
||||
} |
||||
deptsArr |
||||
.filter(dept => DEPTS[dept]) |
||||
.forEach(dept => { |
||||
const value = `@${DEPTS[dept].replace(path.resolve("src"), "").replace(/\\/g, "/").replace(/\.js$/, "")}`; |
||||
if (!tmpG[value]) { |
||||
tmpG[value] = {}; |
||||
} |
||||
tmpG[value][dept] = true; |
||||
}); |
||||
forbiddenKeys.push(module); |
||||
} |
||||
}); |
||||
Object.assign(tmpG, circleG); |
||||
forbiddenKeys.forEach(key => { |
||||
delete tmpG[key]; |
||||
}); |
||||
|
||||
|
||||
// 较验手工 import 错误
|
||||
const map = {}; |
||||
let conflict = false; |
||||
|
||||
lodash.forEach(tmpG, (depts, module) => { |
||||
lodash.forEach(depts, (_, _import) => { |
||||
if (map[_import] && map[_import] !== module) { |
||||
conflict = true; |
||||
} |
||||
|
||||
map[_import] = module; |
||||
}); |
||||
}); |
||||
|
||||
conflict && ConflictImport.push(srcName); |
||||
circle && CircularDependency.push(srcName); |
||||
|
||||
|
||||
|
||||
G = tmpG; |
||||
|
||||
const noImportCode = noXtypeCode.replace( |
||||
/import {([\s\S]*?)} from "(.*?)";/g, |
||||
"", |
||||
); |
||||
|
||||
let I = ""; |
||||
Object.keys(G).forEach(key => { |
||||
let moduleKey = key; |
||||
if (moduleKey === path.basename(srcName).replace(/.js$/g, "")) { |
||||
return; |
||||
} |
||||
let i = ""; |
||||
Object.keys(G[moduleKey]).forEach(key => { |
||||
i += `${key}, `; |
||||
}); |
||||
|
||||
// 必须以 . 开头
|
||||
const moduleInValid = /^[^@.]/.test(moduleKey); |
||||
if (moduleInValid) { |
||||
moduleKey = `./${moduleKey}`; |
||||
} |
||||
|
||||
I += `import {${i}} from '${moduleKey}'\n`; |
||||
}); |
||||
const code = `${I}\n${noImportCode}`; |
||||
|
||||
await saveAndFixCode(srcName, code); |
||||
|
||||
return; |
||||
} |
||||
|
||||
G["@/core"] = { shortcut: true }; |
||||
|
||||
const clzName = result[1]; |
||||
|
||||
if (!clzName) { |
||||
console.log(`${srcName} 不需要 es6 化`); |
||||
|
||||
return; |
||||
} |
||||
|
||||
const superName = /inherit\(BI\.(.*?),/.exec(sourceCode)[1]; |
||||
|
||||
// const xtype = /BI.shortcut\(\"(.*?)\"/.exec(sourceCode)[1];
|
||||
|
||||
const collection = { |
||||
"static": {}, |
||||
attr: {}, |
||||
}; |
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const BI = { |
||||
[clzName]: clzName, |
||||
inherit(_, options) { |
||||
collection.methods = Object.keys(options) |
||||
.filter(key => typeof options[key] === "function") |
||||
.map(key => options[key]); |
||||
Object.keys(options) |
||||
.filter(key => typeof options[key] !== "function") |
||||
.forEach(key => { |
||||
collection.attr[key] = options[key]; |
||||
}); |
||||
|
||||
return collection.static; |
||||
}, |
||||
extend(targetClz, o) { |
||||
Object.assign(collection.static, o); |
||||
}, |
||||
shortcut(xtype) { |
||||
collection.xtype = xtype; |
||||
}, |
||||
}; |
||||
|
||||
// eslint-disable-next-line no-eval
|
||||
eval(sourceCode); |
||||
|
||||
let M = ""; |
||||
let E = ""; |
||||
let I = ""; |
||||
let A = ""; |
||||
|
||||
loader.load(srcName, superName); |
||||
|
||||
Object.keys(collection.attr).forEach(key => { |
||||
const value = collection.attr[key]; |
||||
if (typeof value === "function" || typeof value === "number") { |
||||
A += `\t${key} = ${value}\n`; |
||||
} else if (typeof value === "string") { |
||||
A += `\t${key} = "${value}"\n`; |
||||
} else if (typeof value === "object") { |
||||
if (objHaveFunction(value)) { |
||||
throw new Error("G"); |
||||
} else { |
||||
A += `\t${key} = ${JSON.stringify(value)}\n`; |
||||
} |
||||
} |
||||
}); |
||||
|
||||
// 静态方法
|
||||
Object.keys(collection.static).forEach(key => { |
||||
// console.log(key, collection.static[key], typeof collection.static[key])
|
||||
const value = collection.static[key]; |
||||
if (typeof value === "function" || typeof value === "number") { |
||||
E += `\tstatic ${key} = ${value}\n`; |
||||
} else if (typeof value === "string") { |
||||
E += `\tstatic ${key} = "${value}"\n`; |
||||
} else if (typeof value === "object") { |
||||
if (objHaveFunction(value)) { |
||||
throw new Error("G"); |
||||
} else { |
||||
E += `\tstatic ${key} = ${JSON.stringify(value)}\n`; |
||||
} |
||||
} |
||||
}); |
||||
|
||||
// 对函数进行替换
|
||||
collection.methods.forEach(el => { |
||||
let f = `${el.toString().replace(/^function/, el.name)}\n`; |
||||
|
||||
// 换 BI.Button.superclass,就说能不能跑吧
|
||||
for (let i = 0; i < 100; i++) { |
||||
f = f.replace(`BI.${clzName}.superclass`, "super"); |
||||
} |
||||
// 换 super._defaultConfig
|
||||
f = f.replace( |
||||
/super\._defaultConfig\.apply\(this,\sarguments\)/g, |
||||
"super._defaultConfig(...arguments)", |
||||
); |
||||
// 换 super.xxx.apply
|
||||
f = f.replace(/super\.(.*?)\.apply\(this,\sarguments\)/g, a => { |
||||
const f = /super\.(.*?)\.apply\(this,\sarguments\)/.exec(a); |
||||
|
||||
return `super.${f[1]}(...arguments)`; |
||||
}); |
||||
|
||||
// 尝试换掉所有的 BI.xxx. BI.xxx( BI.xxx[空白]
|
||||
f = f.replace(/BI\.(.*?)(\.|\(|\s|,)/g, matchedSentence => { |
||||
const match = /BI\.(.*?)(\.|\(|\s|,)/.exec(matchedSentence); |
||||
const target = match[1]; |
||||
const end = match[2]; |
||||
// 尝试加载 target
|
||||
const loadSuccess = loader.load(srcName, target); |
||||
if (loadSuccess) { |
||||
return target + end; |
||||
} else { |
||||
console.log(`BI 变量替换失败 BI.${target}`); |
||||
|
||||
return matchedSentence; |
||||
} |
||||
}); |
||||
|
||||
// 尝试对 xtype 进行替换
|
||||
f = f.replace(/"bi\.(.*?)"/g, matchedSentence => { |
||||
const loadSuccess = loader.load(srcName, matchedSentence); |
||||
if (loadSuccess) { |
||||
const clzName = depts[matchedSentence].clzName; |
||||
|
||||
return `${clzName}.xtype`; |
||||
} else { |
||||
// console.log(`(没事) xtype 替换失败 ${matchedSentence} `);
|
||||
|
||||
return matchedSentence; |
||||
} |
||||
}); |
||||
|
||||
M += `${f}\n`; |
||||
}); |
||||
|
||||
if (!collection.xtype) { |
||||
delete G["@/core"].shortcut; |
||||
} |
||||
|
||||
Object.keys(G).forEach(key => { |
||||
let moduleKey = key; |
||||
if (moduleKey === path.basename(srcName).replace(/.js$/g, "")) { |
||||
return; |
||||
} |
||||
let i = ""; |
||||
Object.keys(G[moduleKey]).forEach(key => { |
||||
i += `${key}, `; |
||||
}); |
||||
|
||||
// 必须以 . 开头
|
||||
const moduleInValid = /^[^@.]/.test(moduleKey); |
||||
if (moduleInValid) { |
||||
moduleKey = `./${moduleKey}`; |
||||
} |
||||
|
||||
I += `import {${i}} from '${moduleKey}'\n`; |
||||
}); |
||||
|
||||
const outputCode = ` |
||||
${I} |
||||
|
||||
${collection.xtype ? "@shortcut()" : ""} |
||||
export class ${clzName} extends ${superName} { |
||||
${collection.xtype ? `static xtype = "${collection.xtype}"` : ""} |
||||
|
||||
${A} |
||||
|
||||
${E} |
||||
|
||||
${M} |
||||
} |
||||
`;
|
||||
await saveAndFixCode(srcName, outputCode); |
||||
|
||||
return clzName; |
||||
} |
||||
|
||||
async function traverse(srcName) { |
||||
if (srcName.indexOf("__test__") >= 0) return; |
||||
|
||||
if (srcName.endsWith(".js")) { |
||||
try { |
||||
return await handleFile(srcName); |
||||
} catch (error) { |
||||
console.log(`文件处理失败 ${srcName} \n`); |
||||
console.error(error); |
||||
|
||||
return; |
||||
} |
||||
} else { |
||||
const stat = fs.statSync(srcName); |
||||
const flag = stat.isDirectory(); |
||||
if (flag) { |
||||
const files = fs.readdirSync(srcName); |
||||
// let indexContent = "";
|
||||
for (let i = 0; i < files.length; i++) { |
||||
const file = files[i]; |
||||
await traverse(path.resolve(srcName, file)); |
||||
// const clzName = await traverse(path.resolve(srcName, file));
|
||||
// const moduleName = path.basename(srcName).replace(/.js$/, "");
|
||||
// if (clzName) {
|
||||
// indexContent += `export { ${clzName} } from '${moduleName}'\n`;
|
||||
// }
|
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
const srcName = process.argv[2]; |
||||
|
||||
initDepts().then(async () => { |
||||
await traverse(srcName); |
||||
|
||||
// 对数据处理
|
||||
ConflictImport.forEach(el => { |
||||
console.log(`导入冲突 ${el}`); |
||||
}); |
||||
CircularDependency.forEach(el => { |
||||
console.log(`出现循环依赖(已经fixed) ${el}`); |
||||
}); |
||||
}); |
@ -1,172 +0,0 @@
|
||||
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; |
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in new issue