前端项目移除console日志(二)
上篇使用了 node 检测,但是这样消耗的时间比较长,现在还有一个更简单的方法,就是检测 git 暂存区的代码,如果有变动那么检测是否有 console 如果有执行脚本文件。
那就是 commit 之前执行脚本文件,检测是否有 console 如果有就报错不允许提交。
#!/bin/sh
# .husky/pre-commit
echo "pre-commit"
# 执行插件
pnpm remove-log
# 检测成功 pnpm remove-log 成功
if [ $? -eq 0 ]; then
	echo "pnpm remove-log 成功"
else
	echo "pnpm remove-log 失败"
fi
{
	"scripts": {
		"prepare": "husky install",
		// entry 项目入口 build_dir 构建目录
		"remove-log": "node scripts/remove-log.js entry=test_2/src/ build_dir=test_2/dist"
	}
}const { readFileSync, writeFileSync, existsSync, mkdirSync } = require("fs");
const { parseArgs } = require("util");
const { join } = require("path");
const { execSync } = require("child_process");
// 支持的扩展
const SUPPORTED_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".vue", ".html"];
// 排除的目录
const EXCLUDE_DIRS = [
	"node_modules",
	"dist",
	"build",
	".git",
	".husky",
	".vscode",
	"public",
];
const CONSOLE_REGEX =
	/console\.(log|info|warn|error|debug)\s*\((?:[^()"`]|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|\((?:[^()"`]|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)*\))*\);?/g;
// 获取 arg 环境变量
const { positionals } = parseArgs({
	allowPositionals: true,
	args: process.argv.slice(2),
});
// 构建目录
const params = {};
positionals.forEach(item => {
	const [key, value] = item.split("=").filter(Boolean);
	params[key] = value;
});
const BUILD_DIR = join(process.cwd(), params.build_dir);
// 获取 diff 的文件
const diffFiles = execSync("git diff --name-only --cached")
	.toString()
	.trim()
	.split("\n")
	.filter(
		item =>
			item.includes(params.entry) &&
			!EXCLUDE_DIRS.some(dir => item.includes(dir)) &&
			SUPPORTED_EXTENSIONS.some(ext => item.endsWith(ext))
	);
function onHandlerFile(filePath) {
	try {
		let content = readFileSync(filePath, "utf-8");
		const originalContent = content;
		content = content.replace(CONSOLE_REGEX, "");
		if (content !== originalContent) {
			if (!existsSync(BUILD_DIR)) mkdirSync(BUILD_DIR, { recursive: true });
			const relativePath = filePath.replace(
				join(process.cwd(), params.entry),
				""
			);
			const buildPath = join(BUILD_DIR, relativePath);
			writeFileSync(buildPath, content, { encoding: "utf-8" });
		}
	} catch (error) {
		console.error("处理文件失败", error);
		process.exit(1);
	}
}
// 开始执行
console.log("开始移除项目中的console语句...");
const startTime = Date.now();
diffFiles.forEach(file => {
	onHandlerFile(join(process.cwd(), file));
});
const endTime = Date.now();
console.log(`移除完成! 耗时: ${(endTime - startTime) / 1000}秒`);