如何代码降重

目录

    • 一、使用的相关工具
    • 二、冗余代码的分类和压缩策略
      • 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.mzph.cn/news/82356.shtml

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

相关文章

Python(八十七)函数的定义与调用

❤️ 专栏简介:本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中,我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 :本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

九芯电子丨语音智能风扇,助您畅享智慧生活

回忆童年时期的传统机械风扇,那“古老”的扇叶连摆动看起来是那么吃力。在一个闷热的夏夜,风扇的噪音往往令人印象深刻。但在今天,静音家用风扇已取代了传统的机械风扇。与此同时,随着智能化的发展,智能家居已逐渐成为…

[计算机入门] 电源选项设置

3.10 电源选项设置 有时候我们的电脑一段时间没有用,会自己关掉屏幕或者直接睡眠,这是电源选项没有设置好导致的。 1、打开控制面板,打开其中的电源选项 2、点击左侧上方的选择关闭显示器的时间 3、进入到编辑计划设置界面,在…

大数据学习1.1-Centos8网络配置

1.查看虚拟网卡 2.配置网络信息 打勾处取消 记住箭头的数字 3.修改 网络连接 4.进入虚拟网络 5.进入属性 6.修改IPv4 5.将iIP和DNS进行修改 6.配置网络信息-进入修改网络配置文件 # 进入root用户 su root # 进入网络配置文件 cd /etc/sysconfig/network-scripts/ # 修改网络配…

thrift的简单使用

写在前面 本文一起看下一种由facebook出品的rpc框架thrift。 源码 。 1:开发步骤 1:编写thrift idl文件 2:根据thrift idl文件生成java模板代码 3:继承模板代码的*.Iface接口给出server的具体服务实现 4:使用模板的HelloWorldSe…

综合管廊安全监测,助力市政管廊智能化管理

综合管廊是一种集管线维护、建设、管理于一体的地下综合通道,可以将电力、通讯、燃气、供热、供水等工程管线集于一体,综合管廊对于城市建设具有重要意义,可以防止管线破裂,杜绝反复开挖路面,有效缓解交通拥堵&#xf…

散列查找—

1.除数取余法 2.直接定址法 3.平方取中法 处理冲突的方法 1.开放定址法 查找效率分析 2.平方探测法 3.伪随机序列法 4.再散列法

三步实现Mybatis(Mybatis-Plus)多数据源配置

前言 要实现多数据源可以采用dynamic-datasource或者mybatis-mate,本文就以dynamic-datasource为例 dynamic-datasource简介 springboot 快速集成多数据源的启动器 使用文档(opens new window) 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主…

基于Python和mysql开发的看图猜成语微信小程序(源码+数据库+程序配置说明书+程序使用说明书)

一、项目简介 本项目是一套基于Python和mysql开发的看图猜成语微信小程序,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者。 包含:项目源码、项目文档、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都…

netty之ByteBuf

Java NIO 提供了 ByteBuffer 作为它的字节容器,但是这个类使用起来过于复杂,而且也有些繁琐。ByteBuf是对java ByteBuffer的封装。 两个索引 ByteBuf有两个重要的索引,readerIndex和writeIndex。一个用于读取一个用于写入。这两个值初始值都…

adb操作及常用命令

问题:no devices/emulators found:adb devices 没有连接的设备 解决方案: 大概率是因为usb调试功能没有打开,可以查看手机设备是否开启usb调试功能 Android若未开启,可通过设置-关于手机,连续点击版本号7…

小程序自定义导航栏

小程序自定义导航栏🐤🐤 js data: {statusBarHeight: wx.getSystemInfoSync().statusBarHeight, // 状态栏高度navBarHeight: 44, // 导航栏高度},getSystemInfo() {//获取当前设备信息wx.getSystemInfo({success: res > {// 获取胶囊按钮信息let men…

Linux下的Docker安装,以Ubuntu为例

Docker是一种流行的容器化平台,它能够简化应用程序的部署和管理。 Docker安装 1、检查卸载老版本Docker(为保证安装正确,尽量在安装前先进行一次卸载) apt-get remove docker docker-engine docker.io containerd runc 2、Dock…

【LeetCode热题100】--15.三数之和

15.三数之和 注意:最后答案中不能包含重复的三元组 使用排序双指针 可以使用三重循环枚举三元组,但是需要哈希表进行去重操作,得到不包含重复三元组的最终答案,消耗量大量的时间和空间 对于不重复的本质,保持三重循环…

malloc是如何实现内存分配的?

文章目录 前言一、malloc实现原理概括?二、brk() 函数与mmap()函数三、mmap实现原理普通读写与mmap对比mmap内存映射实现过程mmap 的适用场景 前言 在C和C中,malloc函数是用于动态分配内存的常用函数。本文将深入探究malloc函数的内存分配实现机制&…

javafx学习记录

1.布局 2.选择重写或实现方法(select methods to override/implements) ctrl o 3.javafx有init方法,start方法,stop方法 4.定义一个按钮,使用系统默认浏览器访问网站 5.使窗口的关闭栏,缩小扩屏栏,代码是倒数第二行 6.设置模态窗口,默认关闭模态的 下…

9.18号作业

完善登录框 点击登录按钮后,判断账号(admin)和密码(123456)是否一致,如果匹配失败,则弹出错误对话框,文本内容“账号密码不匹配,是否重新登录”,给定两个按钮…

Gavin Wood 演讲全文:建设更具韧性以应变化的 Polkadot

我们非常激动能邀请到 Gavin Wood 博士来现场分享关于 Polkadot 的近况以及最新的进展,带来他对于《加密项目应该怎样应对当今世界的变化》的演讲分享。 🚩点击视频链接观看演讲实录:https://www.youtube.com/watch?vYw3mQNJ5UJQ&t1048s…

JWT 使用教程 授权 认证

JWT 1.什么是JWT JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally s…

JDBC基本概念

什么是JDBC JDBC概念 JDBC(Java DataBase Connectivity)是一套统一的基于Java语言的关系数据库编程接口规范。 该规范允许将SQL语句作为参数通过JDBC接口发送给远端数据库, …