50行代码实现Webpack组件使用次数统计

 更新时间:2021年03月07日 08:37:46   作者:又在吃鱼  
这篇文章主要介绍了50行代码实现Webpack组件使用次数统计,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

背景

最近有个领导想让我们搭组件库,然后我就想知道目前项目中使用的三方组件库哪些组件使用频率最高。本来想去咨询小伙伴,但是小伙伴太忙了,只能自己弄了。我就想能不能通过 webpack 来实现我的想法

效果

我们是用的 @material-ui,下面是组件使用情况

实现

我们知道 loader 的 source是文件的静态字符串如下图

最快的方案通过字符串统计用正则的方式一把梭,但是这样会有问题就是如果注释部分有的话也会被统计进去就不准确,所以我们可以通过 AST 的方式来实现,关于 ast 的概念有很多大佬都讲过了我就不啰嗦了

分析 AST

我这边是通过 @babel/parser 来分析的,我们先看下面这段代码在网站上的构成

import { Box } from '@material-ui/core';
import Autocomplete from '@material-ui/lab/Autocomplete';

我们可以看出路径  program => body ,然后声明类型是 type: ImportDeclaration,继续看如下构成

"source": {
     "type": "StringLiteral",
     "value": "@material-ui/core"
 },
 // 第二段
 "source": {
      type": "StringLiteral",
     "value": "@material-ui/lab/Autocomplete"
 },

我们发下这个字段里面的 value 有我们想要的包名所以第一段代码就是

const ast = parser.parse(source, {
      sourceType: 'module',
      plugins: ['jsx'],
 });
const getImport = 'ImportDeclaration';
const getMaterialImport = packageName || '@material-ui';
const importAst = ast.program.body.filter(
  // type 节点类型,这里我们去过滤 import 声明类型 同时去过滤
  (i) => i.type === getImport && i.source.value.includes(getMaterialImport),
);

拿到相关的 ast 数组下一步就要去拿到组件名字了, 通过观察我们发现 specifiers 标识符这个字段里面有两个字段包含组件名:imported、local

 

  • imported 表示从导出模块导出的变量
  • local 表示导入后当前模块的变量

这里我取的 local, 因为下面这种方式并不会出现 imported  这个字段

import Autocomplete from '@material-ui/lab/Autocomplete';

这个时候包的名字也拿到了后面就简单了直奔主题贴完整代码了

demo

const parser = require('@babel/parser');
const loaderUtils = require('loader-utils');
const total = {
  len: 0,
  components: {},
};
// 对象排序
const sortable = (obj) => Object.fromEntries(Object.entries(obj).sort(([, a], [, b]) => b - a));
module.exports = function(source) {
  console.log(source, '--');
  const options = loaderUtils.getOptions(this);
  const { packageName = '' } = options;
  const callback = this.async();
  if (!packageName) return callback(null, source);
  try {
    // 解析成 ast
    const ast = parser.parse(source, {
      sourceType: 'module',
      plugins: ['jsx'],
    });
    if (ast) {
      setTimeout(() => {
        const getImport = 'ImportDeclaration';
        const getMaterialImport = packageName;
        const importAst = ast.program.body.filter(
          // type 节点类型,这里我们去过滤 import 声明类型 同时去过滤
          (i) => i.type === getImport && i.source.value.includes(getMaterialImport),
        );
        total.len = total.len + importAst.length;
        for (let i of importAst) {
          const { specifiers = [] } = i;
          for (let s of specifiers) {
            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);
    } else callback(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组件次数统计内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详谈javascript中DOM的基本属性

    详谈javascript中DOM的基本属性

    DOM节点是一个对象,它有着一些属性。其中有些是只读的,有些可以直接进行更改(updated on-the-fly)。今天我们就来具体探讨下DOM的基本属性,希望对大家能有所帮助
    2015-02-02
  • JS重载实现方法分析

    JS重载实现方法分析

    这篇文章主要介绍了JS重载实现方法,结合实例形式分析了javascript重载的实现与使用方法,需要的朋友可以参考下
    2016-12-12
  • JS实现求5的阶乘示例

    JS实现求5的阶乘示例

    这篇文章主要介绍了JS实现求5的阶乘,结合实例形式分析了javascript基于循环及递归等操作实现阶乘运算的相关技巧,需要的朋友可以参考下
    2019-01-01
  • JavaScript简单实现鼠标移动切换图片的方法

    JavaScript简单实现鼠标移动切换图片的方法

    这篇文章主要介绍了JavaScript简单实现鼠标移动切换图片的方法,涉及JavaScript针对鼠标事件的响应及页面元素的动态变换技巧,需要的朋友可以参考下
    2016-02-02
  •  javascript数组中的findIndex方法 

     javascript数组中的findIndex方法 

    这篇文章主要介绍了javascript数组中的findIndex方法,findIndex() 方法返回传入一个测试条件函数符合条件的数组第一个元素位置,下面更多相关资料,需要的小伙伴可以参考一下
    2022-03-03
  • webpack DllPlugin xxx is not defined解决办法

    webpack DllPlugin xxx is not defined解决办法

    这篇文章主要介绍了webpack DllPlugin xxx is not defined解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • 关于Bootstrap弹出框无法调用问题的解决办法

    关于Bootstrap弹出框无法调用问题的解决办法

    这篇文章主要介绍了关于Bootstrap弹出框无法调用问题的解决办法的相关资料,需要的朋友可以参考下
    2016-03-03
  • js实现按座位号抽奖

    js实现按座位号抽奖

    本文主要介绍了js实现按座位号抽奖的示例代码。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-04-04
  • js 实现日期灵活格式化的小例子

    js 实现日期灵活格式化的小例子

    这篇文章介绍了js实现日期灵活格式化的小例子,有需要的朋友可以参考一下
    2013-07-07
  • 最简单的JS实现json转csv的方法

    最简单的JS实现json转csv的方法

    这篇文章主要介绍了最简单的JS实现json转csv的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01

最新评论