在 webpack 编译后的阶段,通过检查编译过程中的依赖文件列表和所有文件列表,找出未被使用的文件,并将其输出到控制台。
相关文章
检测无用文件
功能清单
- 在 webpack 编译后的阶段注册一个钩子函数(afterEmit),用于在编译完成后执行自定义的操作。
- 通过getDependFiles方法获取 webpack 编译过程中产生的所有文件的依赖列表(即哪些文件被引用了)。
- 通过getAllFiles方法获取指定模式下的所有文件路径。
- 找出所有文件列表中未被使用的文件,即在依赖列表中没有被引用的文件。
- 输出未被使用的文件列表到控制台。
一、静态代码分析
使用静态代码分析工具来检测项目中未被引用的文件。这些工具可以扫描您的代码库,并识别出哪些文件没有被代码中的其他文件引用。一些常用的静态代码分析工具包括 ESLint、PMD、CodeQL 等。
二、webpack 打包分析
可以直接使用 useless-files-webpack-plugin
插件,也可以自定义一个插件来分析打包过程中未被使用的文件,过程如下。
1、获取项目目录所有的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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) }) }) }
|
2、获取依赖的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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) }) }
|
三、完整示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| const path = require('path'); const glob = require('glob');
class UnusedFilesPlugin { constructor(options) { this.options = options; }
apply(compiler) { compiler.hooks.afterEmit.tapAsync('UnusedFilesPlugin', async (compilation, callback) => { try { const dependedFiles = await this.getDependFiles(compilation); const allFiles = await this.getAllFiles(this.options.root);
const unusedFiles = allFiles.filter(file => !dependedFiles.includes(file));
console.log('Unused files:', unusedFiles);
callback(); } catch (error) { console.error('Error:', error); callback(error); } }); }
getAllFiles(pattern) { return new Promise((resolve, reject) => { glob(pattern, { nodir: true }, (err, files) => { if (err) { reject(err); return; } const resolvedFiles = files.map(file => path.resolve(file)); resolve(resolvedFiles); }); }); }
getDependFiles(compilation) { return new Promise((resolve, reject) => { const dependedFiles = Array.from(compilation.fileDependencies).filter(filepath => !filepath.includes('node_modules')); resolve(dependedFiles); }); } }
module.exports = UnusedFilesPlugin;
|