useless-files-w5-webpack-plugin
Version:
watch webpack project useless files
115 lines (105 loc) • 3.16 kB
JavaScript
/**
* @author sanyuefeng
* @email 1171890071@qq.com
*/
const fs = require('fs')
const glob = require('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 new Promise((resolve, reject) => {
glob(pattern, {
nodir: true
}, (err, files) => {
if (err) {
throw err
}
const out = files.map(item => path.resolve(item))
resolve(out)
})
})
}
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