momodevtools
Version:
file tools
352 lines (334 loc) • 10 kB
JavaScript
const fs = require("fs");
const path = require("path");
let { fileInfo, banList } = require("../data/defaultConfig.json");
/**
* @description: 获取文件树
* @param {string} dir 文件目录路径
* @param {string[]} parents 父级填充的内容
* @param {boolean} showlog 显示log
* @param {boolean} firstRun listFilemap首次执行
* @param {number} fileLength 显示的宽度
* @return {object} 遍历的路径树
*/
let output = "";
async function listFilemap(
{
dir = path.resolve(__dirname, "..", "src"),
parents = [],
showlog = true,
firstRun = true,
isReturnMap = false,
},
fileLength = 65
) {
let _objRes = {
dir: dir,
childFiles: [],
children: {},
};
if (firstRun && isFile(dir)) {
return showlog ? console.error(`${dir}: 不是文件夹`) : "";
}
// 读取目录下的文件夹
let files = fs.readdirSync(dir, (err, files) => {
return files;
});
if (firstRun) {
if (isReturnMap) {
// 写的第一行内容
output = `路径:\n${path.dirname(dir)}\n${path.basename(dir)}\n`;
}
let filesSet = new Set(files);
if (filesSet.has("fileMapConfig.json")) {
try {
const fileMapConfig = require(path.resolve(dir, "fileMapConfig.json"));
fileInfo = Object.assign(fileInfo, fileMapConfig.fileInfo);
banList = Object.assign(banList, fileMapConfig.banList);
} catch (error) {
console.log(error);
}
}
}
// 遍历文件
await files.forEach(async (file, index) => {
let tempdir = `${path.resolve(dir, file)}`;
if (isBan(tempdir)) {
return showlog ? console.info(`${tempdir} 在禁止遍历列表不处理`) : "";
}
// 文件是否是结尾
let isEnd = index === files.length - 1;
if (isReturnMap) {
let { desc, menuInfo } = getfileDescInfo({
tempdir,
parents,
isEnd,
file,
fileLength,
});
// 填充数据
output += `${menuInfo}${desc}\n`;
}
// 如果是文件的处理
if (isFile(tempdir)) {
_objRes.childFiles.push({
short: file, // 文件名
full: tempdir, // 完整路径
});
} else {
let childParents = [].concat(...parents);
// 处理父组件 是不是 最后一个
childParents.unshift(isEnd ? " " : "|");
// 不是文件就是文件夹
_objRes.children[file] = await listFilemap({
dir: tempdir,
parents: childParents,
showlog,
firstRun: false,
isReturnMap,
});
}
});
if (isReturnMap && parents.length < 1) {
_objRes.output = output;
}
return _objRes;
}
// 获取文件信息
function getfileDescInfo({ tempdir, parents, isEnd, file, fileLength }) {
// 显示的行内容
let dirDeepShow = parents.reduce(
(total, cur) => {
return ` ${cur} ` + total;
},
isEnd ? " └── " : " ├── "
);
// 介绍的内容
let descInfo = " ";
// 填充的图标
let fillIcon = " ";
try {
// 更新文件说明
if (fileInfo[file]) {
descInfo = fileInfo[file];
} else if (isFile(tempdir)) {
// 读取页面中的 @description: 之后的文字
descInfo = fs.readFileSync(tempdir, "utf-8");
descInfo = descInfo.split("@description:");
descInfo = descInfo[1];
if (descInfo) {
descInfo = descInfo.split(/\n/);
descInfo = descInfo[0];
// 移除空格
descInfo = descInfo.replace(/\ +/g, "");
} else {
descInfo = fileType;
}
fillIcon = "·";
} else {
// 文件夹的处理
descInfo = "";
}
} catch (error) {}
let menuInfo = `${dirDeepShow}${file}`;
// 处理说明位填充空格对齐 这个80 是顶宽距离
descInfo = `${descInfo || ""}`;
let srcLength = menuInfo.length || 0;
let filliconlength = fileLength - srcLength;
filliconlength = filliconlength > 0 ? filliconlength : 5;
let fillSpace = new Array(filliconlength).fill(descInfo ? fillIcon : "");
fillSpace = fillSpace.reduce((total, current) => {
return "" + total + current;
});
return {
desc: `${fillSpace}${descInfo}`,
menuInfo,
};
}
/**
* @description: 判断制定路径是否是文件
* @param {type} fileName 文件名
* @return {boolean} true-是文件 / false-不是文件
*/
function isFile(fileName) {
return fs.statSync(fileName).isFile();
}
/**
* @description: 判断是否在禁用列表
* @param {string} fileName 文件名
* @return {boolean} true-在列表 / false-不在列表
*/
function isBan(fileName) {
fileName = path.basename(fileName);
if (/^\./.test(fileName)) {
return true;
} else if (banList.indexOf(fileName) > -1) {
return true;
} else {
return false;
}
}
/**
* @description: 递归创建目录 异步创
* @param {string} filePath 文件路径
* @param {function} errCallback 错误回调方法
* @return {boolean}
*/
//
const mkdirsSync = async (filePath, errCallback = (err) => err) => {
if (fs.existsSync(filePath)) {
return true;
} else {
if (mkdirsSync(path.dirname(filePath), errCallback)) {
fs.mkdirSync(filePath);
return true;
}
}
};
/**
* @description: 获取并保存文件树
* @param {string} dir 文件目录路径
* @param {string} outputPath 输出文件路径
* @param {string} outputPath 输出文件路径
* @param {boolean} showlog 显示log
*/
async function savefilemap(
dir = `${path.resolve(__dirname, "..", "")}`,
outputPath = `${path.resolve(__dirname, "FILEMAP.md")}`,
showlog = false
) {
await mkdirsSync(path.resolve(outputPath, ".."));
let treeData = await listFilemap({
dir,
showlog,
isReturnMap: true,
}).then((res) => res.output);
let _output = `# 文件目录\n\n\`\`\`${treeData}\n\`\`\`\n`;
fs.writeFileSync(outputPath, _output);
return { outputPath, output: _output };
}
// 便利当前目录下 的js 合并
function mapDir(d) {
const tree = {};
const [dirs, files] = _(fs.readdirSync(d)).partition((p) =>
fs.statSync(path.join(d, p)).isDirectory()
);
// 映射文件夹
dirs.forEach((dir) => {
tree[dir] = mapDir(path.join(d, dir));
});
// 映射文件
files.forEach((file) => {
if (path.extname(file) === ".js") {
tree[path.basename(file, ".js")] = require(path.join(d, file));
}
});
return tree;
}
// 从dir 路径获取 page的分包数据
const getPagesItem = async (pageEle, packetRoot) => {
const extname = path.extname(pageEle.short);
if (extname === ".vue") {
let _pagePath = pageEle.full;
switch (process.platform) {
//mac系统使用 一下命令打开url在浏览器
case "darwin":
// _pagePath = _pagePath.replace(`${packetRoot}/`, '');
_pagePath = _pagePath.split(`${packetRoot}/`)[1];
break;
// 默认win系统使用
default:
_pagePath = _pagePath.split(`${packetRoot}\\`)[1];
_pagePath = _pagePath.replace(/\\/g, "/");
}
_pagePath = _pagePath.replace(".vue", "");
const _jsonPath = pageEle.full.replace(pageEle.short, "main.json");
const itemData = {};
if (_pagePath) {
itemData.path = _pagePath;
}
if (fs.existsSync(_jsonPath)) {
const style = require(_jsonPath);
itemData.style = style;
} else {
itemData.style = {};
}
return itemData;
} else {
return null;
}
};
/*
* @Author: momokara
* @description: 获取文件列表
*/
const getPackagesfromPages = async (dir) => {
let { children: _NowPages } = await listFilemap({
dir,
showlog: false,
});
let subPages = {}; // 分包文件
let rootPage = []; // 启动页
for (const key in _NowPages) {
if (_NowPages.hasOwnProperty(key)) {
let _pages = [];
if (_NowPages[key].childFiles.length) {
_pages = await Promise.all(
_NowPages[key].childFiles.map(async (ele) => {
let item = await getPagesItem(ele, path.resolve(dir, "../"));
return item;
})
);
_pages = _pages.filter((e) => e);
rootPage = [...rootPage, ..._pages];
}
if (_pages.length < 1) {
const { dir: _childDir, children } = _NowPages[key];
let root = _childDir.replace(dir, "pages");
root = root.replace("\\", "/");
let pages = [];
const packetRoot = path.resolve("./", "src", "pages", key);
for (const childkey in children) {
if (children.hasOwnProperty(childkey) && children[childkey]) {
// 子代目录
children[childkey].childFiles.forEach(async (pageEle) => {
let itemData = await getPagesItem(pageEle, packetRoot);
if (itemData) pages.push(itemData);
});
// 子代子代目录
if (children[childkey].children) {
let ccobg = children[childkey].children;
for (const key in ccobg) {
if (Object.hasOwnProperty.call(ccobg, key)) {
const element = ccobg[key];
element.childFiles.forEach(async (pageEle) => {
let itemData = await getPagesItem(pageEle, packetRoot);
if (itemData) pages.push(itemData);
});
}
}
}
}
}
// subPages.push({
// root,
// pages
// })
subPages[key] = {
root,
pages,
};
}
}
}
return {
pages: rootPage,
subPackages: subPages,
};
};
module.exports = {
listFilemap,
savefilemap,
mapDir,
getPackagesfromPages,
mkdirsSync,
};