JavaScript實(shí)現(xiàn)封裝一個(gè)快速生成目錄樹(shù)的全局腳本
說(shuō)在前面

我們?cè)诤芏嗟胤蕉伎梢钥吹接羞@樣的目錄樹(shù)結(jié)構(gòu),目錄樹(shù)可以很好的介紹項(xiàng)目中各文件目錄的用途,幫助讀者了解整個(gè)項(xiàng)目結(jié)構(gòu)。由于自己在項(xiàng)目中需要用到這個(gè)目錄樹(shù)來(lái)進(jìn)行項(xiàng)目結(jié)構(gòu)介紹,但是在網(wǎng)上簡(jiǎn)單的找了一下,沒(méi)找到自己想要的工具,于是就自己動(dòng)手?jǐn)]了一個(gè)。
思路分析
首先我們需要先明確一下我們這個(gè)工具需要實(shí)現(xiàn)的功能:
- 1、可以生成指定目錄的文件樹(shù)文件
- 2、可以方便地在任意目錄下生成
那么我們需要做的也就是以下兩步:
- 1、編寫(xiě)一個(gè)可以生成指定目錄文件樹(shù)的文件
- 2、將腳本封裝成全局腳本
為了方便插件的使用、提高用戶(hù)體驗(yàn),我們可以使用命令行交互的方式來(lái)獲取所需參數(shù)。
功能實(shí)現(xiàn)
一、使用命令行交互來(lái)獲取所需參數(shù)
編寫(xiě)腳本之前我們需要先明確一下需要的參數(shù)
- 1、需要生成文件樹(shù)的根目錄路徑;
- 2、生成過(guò)程中需要忽略的文件或目錄;
- 3、生成文件樹(shù)的深度;
- 4、生成的文件樹(shù)文件存放路徑;
這里使用到了我自己之前基于inquirer進(jìn)行二次封裝的@jyeontu/j-inquirer,與inquirer相比,@jyeontu/j-inquirer增加了文件夾選擇器的交互方式,我們可以直接使用其來(lái)選擇需要生產(chǎn)目錄樹(shù)的文件目錄和生成文件存放的位置。
@jyeontu/j-inquirer這個(gè)工具的具體使用手冊(cè)可以看這里:https://gitee.com/zheng_yongtao/node-scripting-tool/tree/master/src/JInquirer
const JInquirer = require("@jyeontu/j-inquirer");
const fs = require("fs");
const path = require("path");
async init() {
const options = this.getOptions();
let j = new JInquirer(options);
let res = await j.prompt();
this.config = res;
this.generateTree(res);
}
getOptions() {
const basePath = this.config.basePath || __dirname;
return [
{
type: "folder",
message: "請(qǐng)選擇文件夾:",
name: "basepath",
default: "",
pathType: "absolute",
dirname: basePath,
},
{
type: "input",
message: "請(qǐng)輸入需要過(guò)濾的文件名(英文逗號(hào)隔開(kāi)):",
name: "filterFile",
notNull: false,
},
{
type: "input",
message: "請(qǐng)輸入需要遍歷的層數(shù):",
name: "stopFloor",
notNull: false,
},
{
type: "folder",
message: "請(qǐng)選擇生成文件存放位置:",
name: "generatePath",
default: "",
pathType: "absolute",
dirname: basePath,
},
];
}獲取到我們需要的參數(shù)之后我們便可以開(kāi)始編寫(xiě)生成文件目錄樹(shù)的代碼了:
二、編寫(xiě)目錄文件樹(shù)生成邏輯
1、遞歸獲取文件目錄
遞歸結(jié)束條件為傳入?yún)?shù)的最大遍歷深度:if (floor > stopFloor) return;。
通過(guò)readdirSync可以獲取指定目錄下的所有文件列表,通過(guò)statSync方法獲取文件屬性,再通過(guò)isFile方法判斷是文件還是目錄,如果當(dāng)前遍歷到的為目錄,則需要遞歸遍歷該目錄下的所有文件……
processDir(dirPath, dirTree = [], floor = 1) {
const { stopFloor } = this.config;
if (floor > stopFloor) return;
let list = fs.readdirSync(dirPath);
list = list.filter((item) => {
return !this.isFilterPath(item);
});
list.forEach((itemPath) => {
const fullPath = path.join(dirPath, itemPath);
const fileStat = fs.statSync(fullPath);
const isFile = fileStat.isFile();
const dir = {
name: itemPath,
};
if (!isFile) {
dir.children = this.processDir(fullPath, [], floor + 1);
}
dirTree.push(dir);
});
return dirTree;
}2、過(guò)濾不需要的文件
有時(shí)候我們不希望打印出某些文件目錄(如:node_modules),我們?cè)谳斎肱渲玫臅r(shí)候可以進(jìn)行設(shè)置,遍歷文件目錄的過(guò)程中會(huì)過(guò)濾掉相關(guān)的文件。
isFilterPath(item) {
let { filterFile } = this.config;
filterFile = filterFile.split(",");
for (let i = 0; i < filterFile.length; i++) {
let reg = filterFile[i];
if (item.match(reg) && item.match(reg)[0] === item) return true;
}
return false;
}3、將文件樹(shù)列表轉(zhuǎn)換為字符串
前面我們生成的文件樹(shù)是以列表的形式保存,現(xiàn)在我們需要將其轉(zhuǎn)換成使用制表符連接的字符串的格式。
consoleTree(tree, floor = 1, str = "", adder = "───", isLast = false) {
str += adder;
for (let i = 0; i < tree.length; i++) {
if (floor === 1 && i === 0) {
this.fileTree += "\n" + "┌" + str + tree[i].name;
} else if (
(isLast || floor === 1) &&
i === tree.length - 1 &&
!tree[i].children
) {
this.fileTree += "\n" + "└" + str + tree[i].name;
} else {
this.fileTree += "\n" + "├" + str + tree[i].name;
}
if (tree[i].children)
this.consoleTree(
tree[i].children,
floor + 1,
str,
adder,
(isLast || floor === 1) && i === tree.length - 1
);
}
}4、將生成的目錄樹(shù)寫(xiě)入 txt 文件
前面我們已經(jīng)生成了字符串格式的目錄樹(shù),所以我們可以直接將生成的字符串寫(xiě)入 txt 文件即可,注意寫(xiě)入前我們需要先將原有內(nèi)容情況。
writeTree(filePath, content) {
this.clearTxt(filePath);
fs.writeFileSync(filePath, `${content}`);
}
clearTxt(filePath) {
this.fileTree = "";
fs.writeFileSync(filePath, "");
}三、封裝成全局插件
1、準(zhǔn)備一個(gè)腳本文件
創(chuàng)建一個(gè)文件 bin.js 作為啟動(dòng)腳本。
#!/usr/bin/env node
const path = require("path");
const GetFileTree = require("./GetFileTree.js");
const basePath = process.argv[2] || path.join(process.argv[1], "../");
console.log(process.argv, basePath);
const gft = new GetFileTree({ basePath });
gft.init();
2、package.json 中配置啟動(dòng)命令
在package.json文件中配置腳本啟動(dòng)命令,需要設(shè)置 bin 屬性,這個(gè)配置幫助我們將包內(nèi)的可執(zhí)行腳本文件注入系統(tǒng)環(huán)境。多個(gè)命令時(shí),支持對(duì)象配置命令:
{
"name": "mt-cli",
"version": "1.0.1",
"bin": {
"getFileTree": "./bin.js"
}
}3、上傳到 npm
登錄自己的 npm 賬號(hào)后可以使用命令將該包上傳到 npm 倉(cāng)庫(kù)。
npm publish
四、插件安裝使用
1、插件安裝
npm i -g getFileTree
2、插件使用
全局安裝后我們就可以在任意目錄下使用getFileTree 目錄絕對(duì)路徑命令來(lái)生成文件目錄樹(shù),如下:
getFileTree E:\myGitee\md文件夾

然后按照提示選擇或輸入相關(guān)的參數(shù)即可,生成的文件如下:

源碼地址
https://gitee.com/zheng_yongtao/node-scripting-tool/tree/master/src/getFileTree

到此這篇關(guān)于JavaScript實(shí)現(xiàn)封裝一個(gè)快速生成目錄樹(shù)的全局腳本的文章就介紹到這了,更多相關(guān)JavaScript目錄樹(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript canvas API內(nèi)容整理
在本篇文章里小編給大家分享的是關(guān)于javascript canvas API內(nèi)容整理,有需要的朋友們可以跟著學(xué)習(xí)參考下。2020-02-02
layui 數(shù)據(jù)表格拖動(dòng) 列、行 位置重新排序功能實(shí)現(xiàn)
這篇文章主要介紹了layui數(shù)據(jù)表格拖動(dòng)列、行位置重新排序功能實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-06-06
JavaScript中判斷函數(shù)是new還是()調(diào)用的區(qū)別說(shuō)明
具名函數(shù)的各種調(diào)用方式 在之前篇幅中已經(jīng)介紹過(guò)了。這篇看看如何判斷一個(gè)函數(shù)是被new調(diào)用的,還是被其它方式調(diào)用的。2011-04-04
jsonp的簡(jiǎn)單介紹以及其安全風(fēng)險(xiǎn)
JSONP原理就是動(dòng)態(tài)插入帶有跨域url的script標(biāo)簽,然后調(diào)用回調(diào)函數(shù),把我們需要的json數(shù)據(jù)作為參數(shù)傳入,通過(guò)一些邏輯把數(shù)據(jù)顯示在頁(yè)面上,這篇文章主要給大家介紹了關(guān)于jsonp的簡(jiǎn)單介紹以及其安全風(fēng)險(xiǎn)的相關(guān)資料,需要的朋友可以參考下2022-01-01
簡(jiǎn)單實(shí)現(xiàn)JavaScript圖片切換效果
這篇文章主要教大家如何簡(jiǎn)單實(shí)現(xiàn)JavaScript圖片切換效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
BootStrap的彈出框(Popover)支持鼠標(biāo)移到彈出層上彈窗層不隱藏的原因及解決辦法
彈出框(Popover)與工具提示(Tooltip)類(lèi)似,提供了一個(gè)擴(kuò)展的視圖。本文給大家介紹BootStrap的彈出框(Popover)支持鼠標(biāo)移到彈出層上彈窗層不隱藏的原因及解決辦法,喜歡的朋友參考下吧2016-04-04
js使用數(shù)組判斷提交數(shù)據(jù)是否存在相同數(shù)據(jù)
判斷提交數(shù)據(jù)是否存在相同數(shù)據(jù),在本文將為大家介紹使用數(shù)組做到這一點(diǎn),感興趣的朋友可以參考下2013-11-11

