关于重复定义接口我想很多公司都有这样的问题,重复不仅使文件更大而且不好维护,接下来带大家使用科学的方法去统计
话不多说直接贴代码:
const fs = require('fs')
const path = require('path')
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
const types = require('@babel/types')
// 1.读取所有文件 2.获取所有文件的url 3.用所有的文件url
const apiMap = new Map()
const getAllUrls = function (file) {
if (!file) return
// 如果是文件夹
if (/.ts|.js/.test(file)) {
// 非文件夹
const sourceCode = fs.readFileSync(file, 'utf8')
const ast = parser.parse(sourceCode, {
sourceType: 'unambiguous',
plugins: ['typescript'],
})
traverse(ast, {
CallExpression(path) {
if (path.node.arguments) {
const urlObj = path.node.arguments[0]
const method = path.node.callee.property.name
if (types.isStringLiteral(urlObj)) {
// 获取url,重复url则记录文件名
const apiList = apiMap.get(urlObj.value)
const inParams = []
// 获取出入参
const parentNode = path.parentPath.node
if (parentNode.params) {
parentNode.params.forEach((node) => {
// 如果参数是对象
if (types.isObjectPattern(node) && node.properties) {
const paramObj = {}
node.properties.forEach((nodeProperty) => {
// 有初始值
if (types.isAssignmentPattern(nodeProperty.value)) {
paramObj[nodeProperty.value.left.name] =
nodeProperty.value.right.value
} else if (types.isIdentifier(nodeProperty.value)) {
// 没初始值
paramObj[nodeProperty.value.name] = 'undefined'
}
})
inParams.push(paramObj)
} else if (types.isIdentifier(node)) {
// 参数是普通形式
inParams.push(node.name)
} else if (types.isAssignmentPattern(node)) {
// 有初始值
inParams.push(`${node.left.name} = ${node.right.value}`)
}
})
}
const obj = {
[file]: {
入参: inParams,
请求方式: method,
},
}
apiList
? apiMap.set(urlObj.value, [...apiList, obj])
: apiMap.set(urlObj.value, [obj])
}
}
},
})
} else {
const files = fs.readdirSync(file, 'utf8')
if (!files) return
files.forEach((childFile) => {
getAllUrls(path.join(file, childFile))
})
}
}
// 获取所有url
getAllUrls('./src/api')
// 排序
const arrayObj = Array.from(apiMap)
.filter((item) => item[1].length > 1)
.sort((a, b) => b[1].length - a[1].length)
arrayObj.unshift(['重复api总数', arrayObj.length])
const result = new Map(arrayObj.map((i) => [i[0], i[1]]))
// 写入
fs.writeFileSync(
'apiMap.json',
JSON.stringify(Object.fromEntries(result), null, '\t')
)