vlambda博客
学习文章列表

【前端开发日常 - 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,
      isDirtrue,
      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,
            isDirfalse,
            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