UNPKG

@daqi/useless-files-webpack5-plugin

Version:

watch webpack project useless files

120 lines (111 loc) 3.17 kB
const fs = require("fs"); const fg = require("fast-glob"); const path = require("path"); const shelljs = require("shelljs"); class CleanUnusedFilesW5Plugin { constructor(options) { this.opts = options; } apply(compiler) { let _this = this; if (compiler.plugin) { compiler.plugin("after-emit", function (compilation, done) { _this.findUnusedFiles(compilation, _this.opts); done(); }); } else { compiler.hooks.afterEmit.tap( "CleanUnusedFilesW5Plugin", (compilation) => { _this.findUnusedFiles(compilation, _this.opts); return true; } ); } } getDependFiles(compilation) { return new Promise((resolve, reject) => { const dependedFiles = [...compilation.fileDependencies].reduce( (acc, usedFilepath) => { if (!~usedFilepath.indexOf("node_modules")) { acc.push(usedFilepath); } return acc; }, [] ); resolve(dependedFiles); }); } getAllFiles(pattern) { return fg(pattern, { nodir: true, }) .then((files) => { return files.map((item) => path.resolve(item)); }) .catch((err) => { throw err; }); } dealExclude(paths, unusedList) { paths = paths.map((p) => path.resolve(p)); const result = unusedList.filter((unused) => { return !paths.includes(unused); }); return result; } async findUnusedFiles(compilation, config = {}) { const { root = "./src", clean = false, output = "./unused-files.json", exclude = false, excludeSuffix = [], } = config; let pattern = Array.isArray(root) ? root.map((path) => path + "/**/*") : [root + "/**/*"]; try { const allChunks = await this.getDependFiles(compilation); let getAllFiles = pattern.map((path) => this.getAllFiles(path)); let allFiles = await Promise.all(getAllFiles); allFiles = allFiles.flat(); let unUsed = allFiles.filter((item) => { let parse = path.parse(item); let ext = parse.ext; while (path.parse(parse.name).ext) { parse = path.parse(parse.name); ext = parse.ext + ext; } return !~allChunks.indexOf(item) && !excludeSuffix.includes(ext); }); if (exclude && (typeof exclude === "string" || Array.isArray(exclude))) { if (!Array.isArray(root)) { root = [root]; } let dealExclude = root .map((path) => { return exclude.map((excludeFile) => path + "/" + excludeFile); }) .flat(); unUsed = this.dealExclude(dealExclude, unUsed); } if (typeof output === "string") { fs.writeFileSync(output, JSON.stringify(unUsed, null, 4)); } else if (typeof output === "function") { output(unUsed); } if (clean) { unUsed.forEach((file) => { shelljs.rm(file); console.log(`remove file: ${file}`); }); } return unUsed; } catch (err) { throw err; } } } module.exports = CleanUnusedFilesW5Plugin;