UNPKG

momodevtools

Version:

file tools

352 lines (334 loc) 10 kB
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, };