50行代码实现Webpack组件使用次数统计
背景
最近有个领导想让我们搭组件库,然后我就想知道目前项目中使用的三方组件库哪些组件使用频率最高。本来想去咨询小伙伴,但是小伙伴太忙了,只能自己弄了。我就想能不能通过webpack来实现我的想法
效果
我们是用的@material-ui,下面是组件使用情况
实现
我们知道loader的source是文件的静态字符串如下图
最快的方案通过字符串统计用正则的方式一把梭,但是这样会有问题就是如果注释部分有的话也会被统计进去就不准确,所以我们可以通过AST的方式来实现,关于ast的概念有很多大佬都讲过了我就不啰嗦了
分析AST
我这边是通过@babel/parser来分析的,我们先看下面这段代码在网站上的构成
import{Box}from'@material-ui/core'; importAutocompletefrom'@material-ui/lab/Autocomplete';
我们可以看出路径 program=>body,然后声明类型是type:ImportDeclaration,继续看如下构成
"source":{ "type":"StringLiteral", "value":"@material-ui/core" }, //第二段 "source":{ type":"StringLiteral", "value":"@material-ui/lab/Autocomplete" },
我们发下这个字段里面的value有我们想要的包名所以第一段代码就是
constast=parser.parse(source,{ sourceType:'module', plugins:['jsx'], }); constgetImport='ImportDeclaration'; constgetMaterialImport=packageName||'@material-ui'; constimportAst=ast.program.body.filter( //type节点类型,这里我们去过滤import声明类型同时去过滤 (i)=>i.type===getImport&&i.source.value.includes(getMaterialImport), );
拿到相关的ast数组下一步就要去拿到组件名字了,通过观察我们发现specifiers标识符这个字段里面有两个字段包含组件名:imported、local
- imported表示从导出模块导出的变量
- local表示导入后当前模块的变量
这里我取的local,因为下面这种方式并不会出现imported 这个字段
importAutocompletefrom'@material-ui/lab/Autocomplete';
这个时候包的名字也拿到了后面就简单了直奔主题贴完整代码了
demo
constparser=require('@babel/parser'); constloaderUtils=require('loader-utils'); consttotal={ len:0, components:{}, }; //对象排序 constsortable=(obj)=>Object.fromEntries(Object.entries(obj).sort(([,a],[,b])=>b-a)); module.exports=function(source){ console.log(source,'--'); constoptions=loaderUtils.getOptions(this); const{packageName=''}=options; constcallback=this.async(); if(!packageName)returncallback(null,source); try{ //解析成ast constast=parser.parse(source,{ sourceType:'module', plugins:['jsx'], }); if(ast){ setTimeout(()=>{ constgetImport='ImportDeclaration'; constgetMaterialImport=packageName; constimportAst=ast.program.body.filter( //type节点类型,这里我们去过滤import声明类型同时去过滤 (i)=>i.type===getImport&&i.source.value.includes(getMaterialImport), ); total.len=total.len+importAst.length; for(letiofimportAst){ const{specifiers=[]}=i; for(letsofspecifiers){ if(s.local){ const{name}=s.local; total.components[name]=total.components[name]?total.components[name]+1:1; } } } total.components=sortable(total.components); console.log(total,'total'); callback(null,source); },0); }elsecallback(null,source); }catch(error){ callback(null,source); } };
调用loader
{ test:/\.(jsx|)$/, exclude:/node_modules/, include:[appConfig.eslintEntry], use:[ { loader:path.resolve(__dirname,'./loader/total.js'), options:{ packageName:'@material-ui', }, }, ], },
一个简单的统计功能就完成了,当然可能还有其他更好的方式我只是提供这个想法,欢迎大家讨论
最后
做这个的意义是什么呢,比如是我们自己的组件库上线以后可以统计组件引用次数,并且以某个时间为维度比如说周。通过数据来分析我们组件库下个版本的优化方向,而且也可以做kpi汇报手段毕竟有数据支撑
到此这篇关于50行代码实现Webpack组件使用次数统计的文章就介绍到这了,更多相关Webpack组件次数统计内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。