查找缺少catch的位置
const parser = require("@babel/parser");
const t = require("@babel/types");
const traverse = require("@babel/traverse").default;
const fs = require("fs");
const path = require("path");
// 从命令行参数中获取文件路径,默认为../src
const rootPath = process.argv[2] || "../src";
// 存储babel编译错误的信息
const babelErrorInfo = [];
/**
* 校验expression
*/
function testExpression(expression) {
if (expression && expression.type === "CallExpression" && expression.callee.type === "MemberExpression") {
if (
t.isIdentifier(expression.callee.property, { name: "then" })
|| (t.isLiteral(expression.callee.property) && expression.callee.property.value === "then")
) {
return true;
}
if (
(
t.isIdentifier(expression.callee.property, { name: "finally" })
|| (t.isLiteral(expression.callee.property) && expression.callee.property.value === "finally")
)
&& testExpression(expression.callee.object)
) {
return true;
}
}
return false;
}
/**
* 发现指定文件中的promise.then没有catch
* @param {文件路径} sourcePath
*/
function findMissingCatch(sourcePath) {
sourcePath = path.resolve(__dirname, sourcePath);
const code = fs.readFileSync(sourcePath).toString();
const ast = parser.parse(code, { sourceType: "module", plugins: ["jsx", "typescript", "decorators"] });
traverse(ast, {
ExpressionStatement(nodePath) {
const { node } = nodePath;
const { expression } = node;
if (testExpression(expression)) {
const { line, column } = expression.loc.end;
console.log(`${sourcePath}:${line}:${column}`);
}
}
});
}
/**
* 扫描指定目录下的文件,找到所有js和ts文件
*/
function scanDir(dirPath) {
dirPath = path.resolve(__dirname, dirPath);
const files = [];
if (fs.statSync(dirPath).isDirectory()) {
files.push(...fs.readdirSync(dirPath).map((file) => path.join(dirPath, file)));
} else {
files.push(dirPath);
}
files.forEach((file) => {
const filePath = file;
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
// 跳过node_modules
if (/node_modules/.test(filePath)) {
return;
}
scanDir(filePath);
} else if (stat.isFile()) {
if (/\.[tj]sx?$/.test(filePath)) {
try {
findMissingCatch(filePath);
} catch (error) {
babelErrorInfo.push(`${filePath}:${error.loc.line}:${error.loc.column}`);
}
}
}
});
}
function scan(sourcePath) {
console.log("-----------------promise missing catch-----------------");
scanDir(sourcePath);
if (babelErrorInfo.length) {
console.log("-----------------文件语法错误 error-----------------");
babelErrorInfo.forEach((item) => {
console.log(item);
});
}
console.log("-----------------复制错误链接到剪切板,打开vscode,command+p,粘贴,回车,定位到错误行-----------------");
}
scan(rootPath);