UNPKG

structure-graph-webpack-plugin

Version:
106 lines 2.9 kB
const path = require('path') const fs = require('fs') // const pluginName = 'StructureGraphPlugin' module.exports = class StructureGraphPlugin { defaultOptions = { targetName: 'structure.txt', ignoreDirectorys: [], ignoreFiles: [], dress: 'dashed' } constructor(options) { this.options = Object.assign(this.defaultOptions, options) } parser(file, pathStr) { const { ignoreDirectorys, ignoreFiles } = this.options pathStr = path.resolve(pathStr, file) let stat = fs.lstatSync(pathStr) let children = [] if(stat.isDirectory() && !ignoreDirectorys.includes(file)) { const files = fs.readdirSync(pathStr, 'utf8') children = files.filter(item => !ignoreFiles.includes(item)).map(item => { return this.parser(item, pathStr) }) } return { name: file, type: stat.isDirectory() ? 'directory' : 'file', children } } transfer(arr, projectName) { const { ignoreDirectorys, ignoreFiles } = this.options const ignoreList = ignoreDirectorys.concat(ignoreFiles) return (pathStr) => { let data = [ { name: projectName, children: [] } ] data[0].children = arr.filter(item => !ignoreList.includes(item)).map(item => { const file = this.parser(item, pathStr) return file }) return data } } generate(arr, level = -1) { let str = '' let mid = ' ' level ++ for(let i = 0, len = arr.length; i < len; i++) { let item = arr[i] if(!level) { str += `+-- ${item.name}\n` }else { str += ${mid.repeat(level)}+-- ${item.name}\n` } if(item.children) { str += this.generate(item.children, level) } } return str } generateSolid(arr, level = -1) { let str = '' let mid = '│ ' let majorFlag = '├─' let minorFlag = '└─' level ++ arr.sort((prev, next) => prev.children > next.children ? -1 : 1) for(let i = 0, len = arr.length; i < len; i++) { let item = arr[i] if (!level) { str += `${minorFlag} ${item.name}\n` } else { if(i === len -1) { str += ` ${mid.repeat(level - 1)}${minorFlag} ${item.name}\n` }else { str += ` ${mid.repeat(level - 1)}${majorFlag} ${item.name}\n` } } if(item.children) { str += this.generateSolid(item.children, level) } } return str } apply(compiler) { compiler.hooks.beforeCompile.tap(this.constructor.name, () => { const { targetName, dress } = this.options const rootDirectory = process.cwd() const files = fs.readdirSync(rootDirectory, 'utf8') const prjName = rootDirectory.split('/').slice(-1)[0] const file = path.resolve(rootDirectory, targetName) let structData = this.transfer(files, prjName)(path.resolve(rootDirectory)) let outputStr = '' if(dress === 'dashed') { outputStr = this.generate(structData) }else { outputStr = this.generateSolid(structData) } fs.writeFileSync(file, outputStr) }) } }