likes
comments
collection
share

工程治理-如何删除无用文件和无用代码

作者站长头像
站长
· 阅读数 21

背景

2021年重写了一个代码量在50W行级别的项目,由于多人同时开发,且没有处理好公共模块分配,导致完成后产生了大量的无用文件无用代码,很影响开发体验,笔者在业余事件探索了工程化这一行为的可能性

删除无用文件

思路

  • 找到src下所有文件

  • 找到src下打包用到的文件

  • 将所有文件集合减去打包用到的文件,即为无用文件

实现

找到当前目录下所有文件

const fg = require('fast-glob');

const entries = fg.sync(['src/**/*.*'];

找到webpack打包用到的文件

webpackcompilation是管理资源的,查看官网得知, compilation文档上没有发现得到打包文件的方法,只能查看webpack源码,发现webpack提供了一个类型文件,找到了Compilation的定义

工程治理-如何删除无用文件和无用代码

经过逐个尝试,最终发现compilation.fileDependencies就是我们所需要的,且类型文档中并没有标注为私有,可以放心使用

这个时候我们只要找一个合适的compiler hook去操作compilation.fileDependencies,最终查阅文件使用的是compiler.hooks.afterEmit

class Plugin FindUnsedFiles {
    apply(compiler) {
        // 等到webpack输出文件之后执行
        compiler.hooks.afterEmit.tapAsync("FindUnsedFiles", (compilation, callback) => {
                // 打包用到的所有文件
                let assets = Array.from(compilation.fileDependencies)
        	callback();
        });
    }
}

删除无用代码

思路

  • 遍历所有的export语句

  • 遍历所有的import语句

  • export集合减去import集合

实现

可以看到思路非常简单,我们使用babel来操作AST非常容易实现,但是作为程序员,要发挥偷懒的良好品质,以前看到webpack有关tree-shaking的文档,说明webpack内部已经实现了找到无用export,搜一下源码有关unsed的关键词,找到了办法

export方法

let providedExports = compilation.chunkGraph.moduleGraph.getProvidedExports(module);

有被使用的export

let usedExports = compilation.chunkGraph.moduleGraph.getUsedExports(module, chunk.runtime);

完整代码

compilation.chunks.forEach(function (chunk) {
    compilation.chunkGraph.getChunkModules(chunk).forEach(module => {
        
        let providedExports = compilation.chunkGraph.moduleGraph.getProvidedExports(module);
        
        let usedExports = compilation.chunkGraph.moduleGraph.getUsedExports(module, chunk.runtime);
    });
}

使用

写完无用文件无用代码实现之后,准备发现到npm,发现社区已经有人很早实现了,大家使用webpack-deadcode-plugin即可,此文可以作为此插件实现原理分析

总结

  • 此方法只适用webpack,至于跨打包工具的删除无用文件无用代码的实现,目前根据AST实现了无用文件,思路也是一样,只是需要处理webpack打包各种importexport解析,代码已经写好,有空再开源了, 删除无用代码暂时没有计划实习