- 作者:老汪软件技巧
- 发表时间:2024-08-31 15:01
- 浏览量:
最近业务需求,老后台项目迁出来一份,并且删掉了很多的功能菜单。也就导致了许多组件、接口无引用, 原则上都要删除。
开干!
删无引用文件倒是舒服,直接用webpack的useless-files-webpack-plugin插件即可。(我的写法是umi下的webpack配置。)
config.plugin('UselessFile').use(
new UselessFile({
root: './src', // 项目目录
out: './unused-files.json', // 输出文件列表
clean: true, // 是否删除文件,
exclude: /node_modules/ // 排除文件列表, 格式为文件路径数组
})
)
删无用的代码成了个大难题,无用代码主要集中为,无用的接口导出。
一开始想的也利用webpack。找来找去没找到插件,然后就想着能不能用tree-shaking做一些事,但研究后发现也没办法单独将tree-shaking提出来用做删除源文件代码。
有办法倒是可以自定义个插件,但有点超乎本人能力范畴了(后续深入学一下webpack,再回来尝试一下能否实现吧)。
没办法,只能用node了。迫于业务需要,先写了一段脚本将所有用到的接口路径扫了出来 ,至于删除。。。看后续需要吧。
脚本如下:
(略有些乱,实在没精力整理了现在。。。晚些整理一下倒是可以存到git上以备不时之需)
const fs = require('fs');
const path = require('path');
// 定义需要扫描的目录
const directoryPath = 'E:\\aproduct\\manage-pc\\src';
// const directoryPath = 'E:/';
let result = []
let z2 = []
// var regex = /pattern/g;
// var str = "A pattern match in pattern this pattern string";
// var match;
// while ((match = regex.exec(str)) !== null) {
// console.log("Found '" + match[0] + "' at index " + match.index);
// }
function getStringsBetweenPostParentheses(str) {
// const regex = /post\((.*?)\,/g;
const regex = /(import)(.*?)(services)/g;
const matches = [...str.matchAll(regex)]; // 将迭代器转换为数组
// console.log(matches, '222')
// 提取每个匹配项的捕获组(即post(和)之间的字符串)
return matches.map(match => match[0]);
}
function getStringsBetweenPostParentheses222(str, rgx) {
// const regex = /post\((.*?)\,/g;
// const regex = /(import)(.*?)(services)/g;
// const regex = new RegExp(`(${rgx})\\(([\s\S]*?)(request)([\s\S]*?)\\)`, 'g');
// const regex = /(getAdPositionList)\(([\s\S]*?)(request)([\s\S]*?)\)/g
// let regex = /(getAdPositionList)\(([\s\S]*?)(request)([\s\S]*?)\)/g
// regex = (regex + '').replace('getAdPositionList', regex)
const regex = new RegExp(`\\b(${rgx})\\s*\\(([\\s\\S]*?)(request)([\\s\\S]*?)\\)`, 'g');
const matches = [...str.matchAll(regex)]; // 将迭代器转换为数组
// console.log(regex, '222')
// 提取每个匹配项的捕获组(即post(和)之间的字符串)
return matches.map(match => match[4]);
}
// 递归函数,用于遍历目录并查找文件
function scanDirectory(dirPath) {
fs.readdir(dirPath, { withFileTypes: true }, (err, files) => {
if (err) {
console.error('Failed to read directory:', err);
return;
}
files.forEach(file => {
const fullPath = path.join(dirPath, file.name);
// 如果是目录,则递归调用
if (file.isDirectory()) {
scanDirectory(fullPath);
} else if (file.isFile() && (path.extname(file.name) === '.ts' || path.extname(file.name) === '.tsx')) {
// 检查JS文件是否包含"const"
fs.readFile(fullPath, 'utf8', (err, data) => {
if (err) {
console.error('Failed to read file:', err);
return;
}
// console.log(getStringsBetweenPostParentheses(data))
result = [...result, ...getStringsBetweenPostParentheses(data)]
// console.log(err, data)
// if (data.includes('const')) {
// console.log(`${fullPath} contains "const".`);
// }
// var regex = /(post)\((.*?)\,/g;
// var str = data;
// var match;
// while ((match = regex.exec(str)) !== null) {
// result.push(match[0])
// }
});
}
});
});
}
// 开始扫描
scanDirectory(directoryPath);
let zzz = []
function scanDirectory222(dirPath, str) {
fs.readdir(dirPath, { withFileTypes: true }, (err, files) => {
if (err) {
console.error('Failed to read directory:', err);
return;
}
files.forEach(file => {
const fullPath = path.join(dirPath, file.name);
// 如果是目录,则递归调用
if (file.isDirectory()) {
scanDirectory222(fullPath, str);
} else if (file.isFile() && (path.extname(file.name) === '.ts' || path.extname(file.name) === '.jsx')) {
// 检查JS文件是否包含"const"
fs.readFile(fullPath, 'utf8', (err, data) => {
if (err) {
console.error('Failed to read file:', err);
return;
}
// console.log(getStringsBetweenPostParentheses(data))
zzz = [...zzz, ...getStringsBetweenPostParentheses222(data, str)]
// console.log(err, data)
// if (data.includes('const')) {
// console.log(`${fullPath} contains "const".`);
// }
// var regex = /(post)\((.*?)\,/g;
// var str = data;
// var match;
// while ((match = regex.exec(str)) !== null) {
// result.push(match[0])
// }
});
}
});
});
}
setTimeout(() => {
let opt = result
let arr = []
opt.forEach((item) => {
// if (/\{(data:)/.test(item) || /\{(responseType:)/.test(item)) {
let op = (item + 'a').split('{')[1]
op = (op + 'a').split('}')[0]
op = (op + '').split(',').map((item) => item.trim())
arr.push(...op)
// }
})
const set = new Set(arr)
const filterData = Array.from(set)
console.log(filterData, filterData.length, 'f')
let chao = []
function cha(num = 0) {
const currdata = filterData.slice(num, num + 50)
if (currdata.length === 0) return
currdata.forEach((str) => {
scanDirectory222(directoryPath, str)
})
setTimeout(() => {
// console.log(zzz, 'zz')
let z4 = zzz.map((item) => {
const ls1 = (item + '').split('(')[1] + ''
const ls2 = ls1.split(',')[0]
return ls2
})
chao = [...chao, ...z4]
zzz = []
if (num < 550) {
cha(num + 59)
}
}, 1500)
}
cha(0)
setTimeout(() => {
const chaoset = new Set(chao)
const chaole = Array.from(chaoset)
console.log(chaole, chaole.length)
fs.writeFile('C:\\Users\\huawei\\Desktop\\api.txt', JSON.stringify(chaole, null, 2), 'utf8', (err) => {
if (err) {
console.error(err);
} else {
console.log('文件写入成功!');
}
});
}, 20000)
// console.log(filterData.length)
// const z3 = filterData.slice(248, 300)
// z3.forEach((str) => {
// scanDirectory222(directoryPath, str)
// })
// console.log(Array.from(set), Array.from(set).length)
// console.log(arr)
}, 1000)
// scanDirectory222(directoryPath, 'getAdPositionList')