【前端开发日常 - 12】Node.js扫描文件目录
需求背景
1、最近在做一个自动上传前端打包的文件到CDN的功能,需要统计打包出来的文件,获得目录结构;
2、偶尔会在项目文档中需要使用目录结构,而每个文件单独去统计非常麻烦。
解决方案
因此决定用node.js写一个工具,扫描指定目录里面的所有文件,生成文件目录,方便在文档中使用,同时方便自动化发布。
核心代码
具体可以参考:https://github.com/YuQian2015/folder-scanner/blob/master/index.js ,之后会抽时间继续优化,支持更多特性。已经发布 NPM 包,在后面介绍使用方式。
const fs = require('fs');
const path = require('path');
class FolderScanner {
constructor({ location, rootFolder }) {
this.ROOT_FOLDER = rootFolder;
this.ROOT = location;
this.dirTree = []
}
getData() {
this.dirTree.length = 0;
this._scan(this.ROOT, this.ROOT_FOLDER, this.dirTree);
return this.dirTree
}
getTree() {
this.dirTree.length = 0;
this._scan(this.ROOT, this.ROOT_FOLDER, this.dirTree);
let str = ''
function generateTree(allTree, tree, depth = 0, inLastFolder = []) {
// console.log(depth, inLastFolder); // true表示父级是最后一个目录
let childDeep = depth
++childDeep
tree.forEach((item, index) => {
if (depth) {
if (depth > 1) {
for (let i = 0; i < depth - 1; i++) {
if (inLastFolder[i + 1]) {
str += ' '
} else {
str += '│ '
}
}
}
if (tree.length - 1 === index) {
str += '└── ';
}
if (tree.length - 1 > index) {
str += '├── ';
}
}
// 根目录和文件生成
str += item.name
if (item.isDir && item.children.length === 0) {
str += '/\n';
} else if (item.isDir && item.children.length) {
str += '\n';
generateTree(allTree, item.children, childDeep, inLastFolder.concat([tree.length - 1 === index]))
} else {
str += '\n';
}
});
}
generateTree(this.dirTree, this.dirTree);
return str
}
getFiles() {
this.dirTree.length = 0;
this._scan(this.ROOT, this.ROOT_FOLDER, this.dirTree);
let str = ''
function fileList(tree, path = '') {
tree.forEach((item, index) => {
// 根目录和文件生成
if (item.isDir && item.children.length === 0) {
str += '';
} else if (item.isDir && item.children.length) {
fileList(item.children, path + '/' + item.name)
} else {
str += '"' + path + '/'+ item.name + '",';
}
});
}
fileList(this.dirTree);
return `[${str}]`
}
_getIgnoreFolder(ignoreFile) {
const folderStr = fs.readFileSync(ignoreFile, 'utf8').split('\n')
return folderStr.map(item => item.replace('\r', ''))
}
_isDir(dir) {
return fs.statSync(dir).isDirectory()
}
_scan(root, folder, dt) {
const dir = path.resolve(root, folder)
// console.log(`开始扫描${dir}`);
const current = {
name: folder,
isDir: true,
children: []
};
dt.push(current)
let ignoreFolder = [];
const gitIgnoreFile = path.resolve(dir, '.gitignore');
if (fs.existsSync(gitIgnoreFile)) {
console.log('存在忽略文件');
ignoreFolder = this._getIgnoreFolder(gitIgnoreFile)
}
ignoreFolder.push('.git/', '.idea/');
const files = fs.readdirSync(dir);
// console.log('--------------------------------------->扫描出来的文件 V');
// console.log(files);
files.forEach(file => {
if (this._isDir(path.resolve(dir, file))) {
if (ignoreFolder.indexOf(`${file}/`) < 0) {
this._scan(dir, file, current.children);
}
} else {
if (ignoreFolder.indexOf(`${file}`) < 0) {
current.children.push({
name: file,
isDir: false,
children: []
})
}
}
})
}
}
module.exports = FolderScanner;
使用方式
安装
$ npm install @moyufed/folder-scanner
使用
const FolderScanner = require('@moyufed/folder-scanner');
const folderScanner = new FolderScanner({
location: 'F:/',
rootFolder: 'test-page'
});
console.log(folderScanner.getData());
console.log(folderScanner.getTree());
config [object]
属性描述 location
指定要扫描的文件夹所在位置 rootFolder
指定要扫描的文件夹
API
getData [Function]
返回文件结构数据 return array
getTree [Function]
返回文件结构树 return string
getFiles [Function]
返回包含的文件路径 return string