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组件次数统计内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • webpack打包js的方法

    Webpack 是一个前端资源加载/打包工具.它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源. 在代码实践之前,先说一写webpack的基础知识. 1.为什要使用WebPack 现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包.为了简化开发的复杂度,前端社区涌现出了很多好的实践方法 模块化,让我们可以把复杂的程序细化为小的文件; 类似于TypeScript这种在JavaScript基础上拓展的开发语言:使我们能

  • webpack中引用jquery的简单实现

    1.首先需要添加项目中jquery的依赖 npm install jquery --save-dev 2.参考配置代码: var webpack = require("webpack"); var path = require("path"); module.exports = { entry:{ home:"./src/js/home.js", -- }, output:{ path:__dirname+"/dist/js"

  • webpack实现热加载自动刷新的方法

    本文介绍了webpack实现热加载自动刷新的方法,分享给大家,具体如下: 一.webpack-dev-server 一个轻量级的服务 功能:修改代码及时呈现到浏览器上. 第一步:安装 npm install webpack-dev-server -g 第二步:写入到依赖 npm install webpack-dev-server --save-dev 第三步:修改webpack配置文件 module.exports = { entry:"./js/index.js", output:

  • Webpack实现按需打包Lodash的几种方法详解

    前言 在数据操作时,Lodash 就是我的弹药库,不管遇到多复杂的数据结构都能用一些函数轻松拆解. ES6 中也新增了诸多新的对象函数,一些简单的项目中 ES6 就足够使用了,但还是会有例外的情况引用了少数的 Lodash 函数.一个完整的 Lodash 库,即使是压缩后,现最新版本也有 71k 的体积.不能为了吃一口饭而买下一个饭店啊. 针对这个问题,其实已经有很多可选方案了. 函数模块 Lodash 中的每个函数在 NPM 都有一个单独的发布模块.NPM: results for 'loda

  • 详解webpack import()动态加载模块踩坑

    import webpack根据ES2015 loader 规范实现了用于动态加载的import()方法. 这个功能可以实现按需加载我们的代码,并且使用了promise式的回调,获取加载的包. 在代码中所有被import()的模块,都将打成一个单独的包,放在chunk存储的目录下.在浏览器运行到这一行代码时,就会自动请求这个资源,实现异步加载. 这里是一个简单的demo. import('lodash').then(_ => { // Do something with lodash (a.k.

  • webpack常用配置项配置文件介绍

    一.webpack基础 1.在项目中生成package.json:在项目根目录中输入npm init,根据提示输入相应信息.(也可以不生成package.json文件,但是package.json是很有用的,所有建议生成) 2.安装webpaack a.在全局中安装webpack:npm install webpack -g b.将webpack安装到项目并将webpack写入package.json的devDependencies中:进入项目根目录,然后在命令行中输入npm install w

  • 基于vuejs+webpack的日期选择插件

    基于vuejs+webpack环境使用的日期选择插件,希望大家喜欢. 支持单选和多选日期 支持限定开始和结束日期范围选择. 支持小时分钟 需要引入fontawesome.io 的图标库. Options :show 是否显示 :type date|datetime :value 默认值 :begin 可选开始时间 :end 可选结束时间 :x 显示x坐标 :y 显示y坐标 :range 是否多选 test.vue <template> <input type="text&quo

  • 详解如何使用webpack打包Vue工程

    使用webpack打包Vue工程 前言 入行一年,从什么都不懂的小白,到现在什么都懂一点的小白,也算是飞跃了.感叹一下现在的前端,从nodejs出来到现在各种各样的工具如雨后春笋般的出现.大神们疯狂的造轮子,玩的不亦乐乎.我等小白们,疯狂追赶,学的心肝脾肺都快衰竭.而我的精力也仅限浅尝辄止,但是学多一点总有好处的.本篇文章就是介绍如何使用webpack构建前端工程. 目标 本次的工程以Vue.js为主角,Vue.js是一款小巧优雅而且强大的轻量级mvvm框架,配合webpack模块化打包.制作出

  • 深入理解Webpack 中路径的配置

    前言 Webpack2 中有很多涉及路径参数配置,若不知其所以然,很容易混淆出错.本文尽可能的汇集了 Webpack2 中涉及路径的配置,力争深入浅出. context context 是 webpack 编译时的基础目录,入口起点(entry)会相对于此目录查找. 默认值为当前目录,webpack设置 context 默认值代码 可以本地下载: this.set("context", process.cwd()); process.cwd()即webpack运行所在的目录(等同pac

  • 详解webpack的proxyTable无效的解决方案

    最近遇到这个需要单页访问跨域后台的问题. 可以按照如下设置: proxyTable: { '/list': { target: 'http://api.xxxxxxxx.com', pathRewrite: { '^/list': '/list' } } } 这样我们在写url的时候,只用写成/list/1就可以代表api.xxxxxxxx.com/list/1. 那么又是如何解决跨域问题的呢?其实在上面的'list'的参数里有一个changeOrigin参数,接收一个布尔值,如果设置为true

  • html-webpack-plugin修改页面的title的方法

    vue-cli2.X:修改config目录下index.js const title = '标题1' // const title = '标题2' // const title = '标题3' module.exports = {     title: title,     dev: { ... },     build: { ... },     test: { ... } 接着就可以在webpack.dev.conf.js, webpack.prod.conf.js中的HtmlWebpack

随机推荐