背景
项目随着时间的推移不断更新迭代,或者新项目从老项目迁移开发,项目变得越来越臃肿,无形中就存在了很多无用的文件.
大型的项目,如果仅靠人肉去识别,难度相当大,那么怎样能够自动检测哪些是无用的文件呢?
下面介绍使用useless-files-webpack-plugin
插件查找无用文件(版本1.0.1
)
安装
// npm
npm i useless-files-webpack-plugin -D
// yarn
yarn add -D useless-files-webpack-plugin
webpack配置
const UnusedFilesWebpackPlugin = require('useless-files-webpack-plugin')
plugins: [
new UselessFile({
root: './src', // 项目目录
output: './unused-files.json', // 输出文件列表
clean: false // 删除文件,
})
]
vue.config.js中配置
const UnusedFilesWebpackPlugin = require('useless-files-webpack-plugin')
module.exports = {
configureWebpack: (config) => {
config.plugins.push(
new UnusedFilesWebpackPlugin({
root: './src', // 项目目录
output: './unused-files.json', // 输出文件列表
clean: false, // 是否删除文件,
})
)
},
devServer: {
}
};
运行npm run build
打包完成后会在项目的根目录下生成一个unused-files.json文件, 保存着无用文件的列表。
然后自行根据列表中的提供路径,核对相应文件是否需要保留,手动删除即可。
clean配置true会自动删除,此选项请慎用。
源代码(1.0.1)
const fs = require('fs')
const glob = require('glob')
const path = require('path')
const shelljs = require('shelljs')
class CleanUnusedFilesPlugin {
constructor (options) {
this.opts = options
}
apply (compiler) {
let _this = this
compiler.plugin('after-emit', function (compilation, done) {
_this.findUnusedFiles(compilation, _this.opts)
done()
})
}
/**
* 获取依赖的文件
*/
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 (path, unusedList) {
const file = fs.readFileSync(path, 'utf-8')
const files = JSON.parse(file) || []
const result = unusedList.filter(unused => {
return !files.some(item => ~unused.indexOf(item))
})
return result
}
async findUnusedFiles (compilation, config = {}) {
const { root = './src', clean = false, output = './unused-files.json', exclude = false } = config
const pattern = root + '/**/*'
try {
const allChunks = await this.getDependFiles(compilation)
const allFiles = await this.getAllFiles(pattern)
let unUsed = allFiles
.filter(item => !~allChunks.indexOf(item))
if (exclude && typeof exclude === 'string') {
unUsed = this.dealExclude(exclude, 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 = CleanUnusedFilesPlugin