UNPKG

unreferenced-files-webpack-plugin

Version:

A Webpack plugin to detect and optionally delete unused (unreferenced) files in your project.

82 lines (70 loc) 2.56 kB
const fs = require('fs'); const path = require('path'); class UnreferencedFilesPlugin { constructor(options = {}) { this.root = options.root || path.resolve(__dirname, 'src'); this.output = options.output || 'unreferenced-files.log'; this.extensions = options.extensions || [ '.js', '.ts', '.vue', '.scss', '.css', '.png', '.jpg', '.jpeg', '.gif', '.svg', '.mp3', '.mp4', '.webm', '.woff', '.woff2', '.ttf', '.eot', '.json' ]; this.excludeDirs = options.excludeDirs || ['node_modules', '__tests__']; this.outputJson = options.outputJson ?? true; this.autoDelete = options.autoDelete ?? false; } apply(compiler) { compiler.hooks.emit.tapAsync('UnreferencedFilesPlugin', (compilation, callback) => { const usedFiles = new Set([...compilation.fileDependencies].map(file => path.resolve(file))); const allFiles = this.getAllFiles(this.root).filter(file => { const ext = path.extname(file).toLowerCase(); return this.extensions.includes(ext); }); const unreferenced = allFiles.filter(file => !usedFiles.has(path.resolve(file))); const logText = `📦 Unreferenced Files (${unreferenced.length}):\n` + unreferenced.join('\n'); const logJson = JSON.stringify({ unreferencedFiles: unreferenced }, null, 2); console.log(logText); compilation.assets[this.output] = { source: () => logText, size: () => logText.length }; if (this.outputJson) { const jsonOutput = this.output.replace(/\.log$/, '.json'); compilation.assets[jsonOutput] = { source: () => logJson, size: () => logJson.length }; } if (this.autoDelete) { unreferenced.forEach(file => { try { fs.unlinkSync(file); console.log(`🗑️ Deleted unreferenced file: ${file}`); } catch (err) { console.warn(`⚠️ Failed to delete: ${file}`); } }); } callback(); }); } getAllFiles(dir, files = []) { if (this.excludeDirs.some(ex => dir.includes(ex))) return files; fs.readdirSync(dir).forEach(file => { const fullPath = path.join(dir, file); try { if (fs.statSync(fullPath).isDirectory()) { if (!this.excludeDirs.includes(file)) { this.getAllFiles(fullPath, files); } } else { files.push(fullPath); } } catch (e) {} }); return files; } } module.exports = UnreferencedFilesPlugin;