当前位置: 首页 > 后端技术 > Node.js

webpack删除重复文件的一个优化思路

时间:2023-04-03 13:24:42 Node.js

场景很多人都用webpack来打包文件。为了防止浏览器缓存,他们经常这样设置:文件并将其添加到文件名中。只要修改文件,就会生成不同的文件名。但是经过多次打包,我们经常会遇到这样的情况:/dist目录|--bundle-6ece9.js|--bundle-b41c3.js|--bundle-d303d.js|--index.html|--style-6ece9.css|--style-b41c3.css|--style-d303d.css除了我们的index.html不动如山,js和css文件好像派系。一段时间后。如何删除这些重复文件?解决方案-许多人推荐使用“clean-webpack-plugin”插件,它会在Webpack编译之前删除所有文件。优点:轻量级插件,易于配置。缺点:在大型项目中,如果只更改了一个文件而需要删除所有其他未更改的文件,这些文件的数量是可变的但对性能还是有一定的影响,所以性能上还有提升的空间这个插件。方案2写过Webpack插件的前端同事可能知道编译器对象和相关的事件钩子。这里有两个与本文相关的钩子:compile:开始编译,在创建编译对象之前;done:所有编译过程已经完成。方法一中的clean-webpack-plugin插件是在编译阶段删除target文件夹。如果要优化插件,思路是在done阶段删除上次打包后留下的废弃文件。这时候,就有了新的问题。在done阶段,项目中的所有文件都被编译并存储在dist文件夹中。如何区分哪些是本次打包生成的新文件,哪些是上一次打包生成的旧文件??这里,我们再介绍一下编译对象。compilation对象表示构建单个版本的webpack并生成编译资源的过程。编译对象可以访问所有模块及其依赖项(主要是循环依赖项)。了解了编译对象的概念之后,我们来介绍一下它的一个属性assets。compilation.assets的值是一个对象,其中每个属性名是这个包生成的文件的文件名,打印出来如下:assets:{'bundle-a82da.js':{existsAt:'...\\dist\\bundle-a82da.js'},'style-cc549.css':ConcatSource{children:[Object],existsAt:'...\\dist\\style-cc549.css',emitted:true},'index.html':{source:[Function:source],size:[Function:size],existsAt:'...\\dist\\index.html',emitted:true}}因此,通过assets属性我们解决了如何区分本次打包和之前打包生成的文件的问题。只需要遍历一次dist目录下的所有文件。如果文件的文件名没有包含在assets对象中,就说明这是一个“前朝遗迹”,直接解析。核心代码如下:buildDir=this.buildDir;compiler.plugin('done',function(compat){//获取资源数组对象constnewlyCreatedAssets=compat.compilation.assets;constunlinked=[];fs.readdir(path.resolve(buildDir),(err,files)=>{files.forEach(file=>{//删除当前打包资源组中不存在的文件if(!newlyCreatedAssets[file]){fs.unlink(path.resolve(buildDir+file));unlinked.push(file);}});if(unlinked.length>0){console.log('删除文件:',unlinked);}});});传入目标文件夹的目录url即可,如“./dist/”。为了方便使用插件,我做了一个插件上传到npm仓库。1.初始化npmnpminit2。安装模块npmiwebpack-remove-hashed-files--save-dev3。Modifywebpack.config.jsconstremoveFiles=require('webpack-remove-hashed-files');//你的打包目标文件夹//你的distnation文件夹constbuildDir='./dist/';//...修改plugins//...modifypluginsplugins:[newremoveFiles(buildDir)]源码,请看我的github仓库总结一下我的方法主要是判断文件是否为本次打包生成,减少删除文件的时间,但是相比clean-webpack-plugin插件,功能上还缺少删除白名单和文件名正则匹配等,这些有空再补充。另外可能有同事觉得clean-webpack-plugin不能满足某些需求。你不妨试试我的插件,说不定会有惊喜呢。参考看realWebpackpluginsHowtowriteaplugin?