清理无用文件肝的眼睛冒金星,不妨来试试webpack插件。
原理就是获取指定目录的全部文件,排除代码依赖的文件,就是不依赖的文件,也就是无用的文件,使用shelljs删除文件
插件仅限在webpack3、webpack4下使用
插件使用
javascript
const UnusedFilesWebpackPlugin = require('./unused-files-webpack-plugin')
plugins: [
//...其他插件
new UnusedFilesWebpackPlugin({
root: './src', // 项目目录
output: './unused-files.json', // 输出文件列表
clean: true, // 是否删除文件,true,删除;false,不删除
exclude: ['src/assets/font', 'src/assets/icon-font'], // 排除文件列表
})
]
插件源码
ini
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) {
let exclude = [];
if (Array.isArray(path)) {
// 兼容传入的是数组路径
exclude = path;
} else if (typeof path == "string") {
try {
// 读取文件里的数组字符串
const file = fs.readFileSync(path, "utf-8");
exclude = JSON.parse(file) || [];
} catch (error) {
console.log(error);
}
}
console.log(exclude, "exclude");
if (process.platform == "win32") {
// windows 需要兼容路径 D:\\workspace\\src\\App.vue
unusedList = unusedList.map(item => item.replace(/\\/g, "/"));
}
let result = unusedList.filter(unused => {
return !exclude.some(item => ~unused.indexOf(item));
});
return result;
}
async findUnusedFiles(compilation, config = {}) {
const {
root = "./src",
output = "./unused-files.json",
clean = false,
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) {
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;