如何代码降重

news2024/11/25 19:15:45

目录

    • 一、使用的相关工具
    • 二、冗余代码的分类和压缩策略
      • 2.1 无用代码
      • 2.2 重复代码
      • 2.3 相似代码
    • 三、长久治理机制
      • 3.1 git-hooks

一、使用的相关工具

以下工具都有各自详细说明的文档。除非有必要,下文不再对其相关使用作详细说明。

仓库代码查重工具:https://github.com/kucherenko/jscpd
文本在线diff工具:https://tool.chinaz.com/tools/diff
node轻量级git工具:https://github.com/steveukx/git-js
包与文件引用检查:https://github.com/depcheck/depcheck

二、冗余代码的分类和压缩策略

在这里插入图片描述

2.1 无用代码

无用代码是完全没有被引用的代码。
通过自然发现和depCheck工具,我们可以发现仓库中的无用代码。
我们可以直接删除无用代码。

注意!depCheck工具检查出的无用文件,不一定是真的没有用到。一些看似无用的文件可能会在动态路由构建或者在webpack打包过程中使用,注意甄别。

2.2 重复代码

重复代码是与存量代码内容相同的代码。
通过自然发现和jscpd工具,我们可以发现仓库中的重复代码。
我们可以提升代码的文件层级,然后修改目标引用,以此来解决重复代码。

2.3 相似代码

相似代码是与存量代码内容相似度高的代码。
通过自然发现和jscpd工具,我们可以发现仓库中的相似代码。
代码相似度高不意味着场景通用,对于相似代码需要有选择性的合并:

场景措施
输入输出处理公共format方法
trycatch处理全局捕获/封装请求方法

三、长久治理机制

代码重复度的优化非一日之功。健康的代码重复度需要长久治理机制的形成。

3.1 git-hooks

我的目的是希望在每一次commit之前,都对变更代码进行查重(就像lint-staged一样),那么我们可以构造以下流程:
在这里插入图片描述
package.json配置如下:

{
  ...
  "husky": {
    "hooks": {
      "pre-commit": "node ./scripts/repeat-check",
      ...
    }
  },
  "jscpd": {
    "threshold": 5,
    "reporters": [
      "html",
      "console"
    ],
    "ignore": [
      ".git",
      ...
    ],
    "format": [
      "javascript",
      "typescript",
      "jsx",
      "tsx"
    ],
    "absolute": true
  }
}

新增scripts/repeat-check.js:

/** @description 对当前git暂存区或更改区的代码,进行查重。若查重比超过预设阈值,阻止提交 */

const simpleGit = require('simple-git')();
const jscpd = require('jscpd');
const cloneDeep = require('lodash/cloneDeep');
const config = require('../package.json');

const { detectClones } = jscpd;
const threshold = config.jscpd.threshold || 5;

/** 获取暂存区或更改文件的目录 */
const getChangedFilePaths = (gitStatus) => {
  const stagedFilePaths = gitStatus.staged;
  const changedFilePaths = gitStatus.files.map((file) => file.path);

  return stagedFilePaths.length ? stagedFilePaths : changedFilePaths;
};

/** 获取百分比 */
const formatNumberToPercent = (num = 0) => {
  return Number(num * 100).toFixed(2);
};

/** 在所有重复比对中,筛选出与更改文件相关的 */
const getChangedClones = (clones, changedFilePaths) => {
  const changedFileArr = cloneDeep(changedFilePaths);

  return clones.filter((clone) => {
    const { duplicationA, duplicationB } = clone;
    const { sourceId: absolutePathA } = duplicationA;
    const { sourceId: absolutePathB } = duplicationB;
    const matchPath = changedFileArr.find(
      (changedPath) =>
        absolutePathA.indexOf(changedPath) > -1 || absolutePathB.indexOf(changedPath) > -1
    );

    if (matchPath) {
      changedFileArr.splice(changedFileArr.indexOf(matchPath), 1);
    }

    return matchPath;
  });
};

/** 打印更改文件相关的重复比对 */
const printChangedClones = (changedClones) => {
  console.log(`A total of ${changedClones.length} clones were found.\n`);
  changedClones.forEach((changedClone) => {
    const { format, duplicationA, duplicationB } = changedClone;
    const { start: startA, end: endA, sourceId: sourceIdA } = duplicationA;
    const { start: startB, end: endB, sourceId: sourceIdB } = duplicationB;
    const { line: startLineA, column: startColumnA } = startA;
    const { line: endLineA, column: endColumnA } = endA;
    const { line: startLineB, column: startColumnB } = startB;
    const { line: endLineB, column: endColumnB } = endB;

    console.log(`Clone found (${format}):`);
    console.log(` - ${sourceIdA} [${startLineA}:${startColumnA} - ${endLineA}:${endColumnA}]`);
    console.log(`   ${sourceIdB} [${startLineB}:${startColumnB} - ${endLineB}:${endColumnB}]\n`);
  });
};

const main = async () => {
  const gitStatus = await simpleGit.status();
  const changedFilePaths = getChangedFilePaths(gitStatus);

  const clones = await detectClones({
    ...config.jscpd,
    absolute: true,
    silent: true,
  });

  const changedClones = getChangedClones(clones, changedFilePaths);
  const duplicatedPercent = formatNumberToPercent(changedClones.length / changedFilePaths.length);

  printChangedClones(changedClones);

  if (duplicatedPercent > threshold) {
    console.log(
      `Too many clones(${duplicatedPercent}%), far over over the threshold(${threshold}%).`
    );
    process.exit(1);
  }

  process.exit(0);
};

main();

注意!pre-commit如果已经配置了lint-staged,再加上查重校验,commit耗时可能会比较长(这也是没办法的事情,毕竟全量代码走两次抽象语法树校验耗时是少不了的)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1022418.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WebStorm 2023年下载、安装教程、亲测有效

文章目录 简介安装步骤常用快捷键 简介 WebStorm 是JetBrains公司旗下一款JavaScript 开发工具。已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的…

PostgreSQL 主从复制故障切换

文章目录 前言环境准备搭建主从节点配置主从节点从节点加入主节点查看主从信息 主从故障切换 前言 PostgreSQL的主从复制是一种非常简单且常用的高可用性和可扩展性解决方案,本质上是将主服务器的数据复制到一个或多个从服务器上,从而提高系统的性能和可…

会话控制学习

文章目录 介绍cookieexpress中使用cookie获取cookie session配置区别 介绍 cookie express中使用cookie 退出登录就是删除cookie 获取cookie 添加中间键后,直接获取 session 配置 区别

Linux 内核代码是 AMD GPU 驱动代码

导读Linux 内核代码是 AMD GPU 驱动代码 1/7 的 Linux 内核代码是 AMD GPU 驱动代码 随着开发中的 Linux 6.6 内核增加了对更多即将推出的 Radeon 图形处理器的支持,现在内核中 AMD GPU 驱动代码的行数已超过 500 万行。其中很大一部分是 AMD 在每一代新版本中不断…

Python的协程异步IO(asyncio)详解

一、协程简介 1.1 定义 协程不是系统级线程,很多时候协程被称为“轻量级线程”、“微线程”、“纤程(fiber)”等。简单来说可以认为协程是线程里不同的函数,这些函数之间可以相互快速切换。 协程和用户态线程非常接近,用户态线程之间的切换…

一文告诉你为什么时序场景下 TDengine 数据订阅比 Kafka 好

在 TDengine 3.0 中,我们对流式计算、数据订阅功能都进行了再升级,帮助用户极大简化了数据架构的复杂程度,降低整体运维成本。TDengine 提供的类似消息队列产品的数据订阅、消费接口,本质上是为了帮助应用实时获取写入 TDengine 的…

第二证券:a股注册制什么意思?

A股施行新的注册原则已经是大势所趋。那么什么是A股注册制?A股注册制和现行的核准制的差异在哪里?关于出资者来说,A股注册制带来了什么样的影响?这篇文章将从多个角度进行分析,为咱们答复疑问。 一、什么是A股注册制&…

[git] rebase 合并多个commit

一、未使用 rebase 的提交数量 上图中 可以看到 有四提交 二、使用rebase git rebase -i head~2表示合并 最后的两个提交, 也就是vv1 和 vv2 回车会弹出: 修改为 pick:保留该commit(缩写:p) reword:保留该commit…

《YOLOv5/YOLOv7/YOLOv8最新改进大作战》专栏介绍 CSDN独家改进创新实战 专栏目录

💡💡💡YOLOv5/YOLOv7/YOLOv8最新改进大作战,独家首发创新(原创),持续更新,适用于Yolov5、Yolov7、Yolov8等各个Yolo系列,专栏文章提供每一步步骤和源码,轻松带…

蓝牙资讯|2023年Q2中国可穿戴市场同比增长17%,蓝牙可穿戴发展迅猛

IDC 发布《中国可穿戴设备市场季度跟踪报告》显示,2023 年第二季度中国可穿戴设备市场出货量为 3,350 万台,同比增长 17.3%,是自 2022 年以来季度最大规模出货。 智能手表 Q2 出货量 942 万台,同比增长 11.5%。其中成人智能手表 4…

什么是好的企业文化?

企业文化可以归结为三个关键词:使命、愿景和价值观。使命就是公司为什么存在,愿景就是公司未来的目标,价值观就是公司内部共同的信仰和行为准则。 简单来说,企业文化就是一群人为了同一个目标而努力工作,不断追求梦想…

深度学习:从理论到实践,探索神经网络的奥秘

💂 个人网站:【工具大全】【游戏大全】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 寻找学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 介绍 深度学习是机器学…

尚硅谷大数据项目《在线教育之实时数仓》笔记002

视频地址:尚硅谷大数据项目《在线教育之实时数仓》_哔哩哔哩_bilibili 目录 第06章 数据仓库环境准备 P006 P007 P008 P009 P010 P011 P012 P013 P014 第06章 数据仓库环境准备 P006 P007 P008 http://node001:16010/master-status [atguigunode001 ~]$ …

低代码,向未来!云畅科技亮相2023世界计算大会

9月15日,2023世界计算大会在长沙北辰国际会议中心开幕,大会以“计算万物 湘约未来——计算产业新变革”为主题,由湖南省人民政府、工业和信息化部共同举办。 大会汇聚包括两院院士、国内外权威专家和知名企业家在内的150余位重要嘉宾&#xf…

武汉市中级工程师职称水平能力测试考试题型有哪些呢?

目前湖北中级职称评审,很多地方都需要组织水平能力测试,武汉市、襄阳、孝感、宜昌、荆州、鄂州、十堰等地级市都需要参加水平能力测试,但是水平能力测试每个地方要求又是不一样,目前湖北全省都没有统一的水平能力测试题库。 关于武…

计算机竞赛 深度学习 YOLO 实现车牌识别算法

文章目录 0 前言1 课题介绍2 算法简介2.1网络架构 3 数据准备4 模型训练5 实现效果5.1 图片识别效果5.2视频识别效果 6 部分关键代码7 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于yolov5的深度学习车牌识别系统实现 该项目较…

SpringBoot中级开发--事务配置管理(10)

事务在整个开发框架中是一个非常常用的功能,特别涉及到数据库操作。像Mysql,就有4个数据库级别: (1) READ UNCOMMITTED(读未提交):允许读取未提交的数据。这种级别的事务可以读取到其他事务未提交的数据,可…

docker部署最新版nacos(2.2.3)设置登录密码

最新版nacos(2.2.3)安装 1、下载 docker pull nacos/nacos-server2、启动nacos 如果nacos版本在2.0及以上,需要把8848、9848和9849三个端口映射出来,否则访问会404失败 docker run --env MODEstandalone --name nacos -d -p 8…

echarts统一纵坐标y轴的刻度线,刻度线对齐。

要求: 纵坐标刻度线对齐;刻度间隔为5;去掉千位默认的逗号;刻度最小是0. 效果图: 代码: yAxis: [{type: "value",position: "left",name: "kW",offset: 100,nameTextStyle:…

Android使用glide时报错“ ����: �޷�����Fragment Glide.with(getContext()) ^ �Ҳ���and”

在gradle.properties中添加下面两行代码 即可 android.useAndroidXtrue android.enableJetifiertrue