本文目录导读:

Git 钩子脚本可以通过在 pre-commit 或 pre-push 阶段运行体积检查来防止大文件或过大的包被提交,以下是几种实现方案:
检查单个文件大小
在 pre-commit 钩子中检查
创建 .git/hooks/pre-commit 文件:
#!/bin/bash
# 设置最大文件大小限制(10MB)
MAX_SIZE_MB=10
MAX_SIZE=$((MAX_SIZE_MB * 1024 * 1024))
# 获取暂存区中的文件列表
files=$(git diff --cached --name-only --diff-filter=ACM)
# 标记是否有大文件
has_large_files=false
for file in $files; do
if [ -f "$file" ]; then
# 获取文件大小
size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
if [ "$size" -gt "$MAX_SIZE" ]; then
echo "❌ 错误: 文件 '$file' 过大 (${size} 字节 / ${MAX_SIZE_MB}MB限制)"
has_large_files=true
fi
fi
done
if [ "$has_large_files" = true ]; then
echo "请优化文件大小后重新提交"
exit 1
fi
检查打包后的体积(针对前端项目)
检查 dist 目录大小
#!/bin/bash
# 检查构建输出目录大小
MAX_DIST_SIZE_MB=50
DIST_DIR="dist"
if [ -d "$DIST_DIR" ]; then
dist_size=$(du -sm "$DIST_DIR" | cut -f1)
if [ "$dist_size" -gt "$MAX_DIST_SIZE_MB" ]; then
echo "❌ 警告: dist目录体积过大 (${dist_size}MB / ${MAX_DIST_SIZE_MB}MB限制)"
exit 1
fi
fi
检查打包产物中的具体文件
针对 Webpack/Vite 构建产物
#!/bin/bash
# 检查特定的打包文件
MAX_CHUNK_SIZE_MB=1
BUILD_DIR="dist"
# 查找所有 JS 和 CSS 文件
find "$BUILD_DIR" -type f \( -name "*.js" -o -name "*.css" \) | while read -r file; do
size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
size_mb=$((size / 1024 / 1024))
if [ "$size_mb" -gt "$MAX_CHUNK_SIZE_MB" ]; then
echo "❌ 警告: ${file#./} 体积过大 (${size_mb}MB)"
exit 1
fi
done
使用 Node.js 脚本进行更精确的控制
创建 scripts/check-bundle-size.js:
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const MAX_SIZE_MB = 10;
const IGNORE_PATTERNS = ['node_modules', '.git', '*.map'];
function getFileSizeInMB(filePath) {
const stats = fs.statSync(filePath);
return stats.size / (1024 * 1024);
}
function shouldIgnore(filePath) {
return IGNORE_PATTERNS.some(pattern => {
if (pattern.startsWith('*')) {
return filePath.endsWith(pattern.slice(1));
}
return filePath.includes(pattern);
});
}
function checkLargeFiles() {
// 获取暂存区的文件
const files = execSync('git diff --cached --name-only --diff-filter=ACM')
.toString()
.trim()
.split('\n')
.filter(Boolean);
let hasLargeFiles = false;
files.forEach(file => {
if (shouldIgnore(file)) return;
if (fs.existsSync(file)) {
const sizeMB = getFileSizeInMB(file);
if (sizeMB > MAX_SIZE_MB) {
console.log(`❌ ${file}: ${sizeMB.toFixed(2)}MB (限制: ${MAX_SIZE_MB}MB)`);
hasLargeFiles = true;
} else if (sizeMB > MAX_SIZE_MB * 0.8) {
console.log(`⚠️ ${file}: ${sizeMB.toFixed(2)}MB (接近限制)`);
}
}
});
if (hasLargeFiles) {
process.exit(1);
}
}
checkLargeFiles();
集成到 pre-commit 钩子
完整的 pre-commit 脚本:
#!/bin/bash
echo "🔍 执行包体积检查..."
# 配置
MAX_FILE_SIZE_MB=10
MAX_TOTAL_SIZE_MB=100
EXCLUDE_PATTERNS="*.map node_modules/ dist/ coverage/"
# 检查单个文件大小
echo "检查单个文件大小..."
git diff --cached --name-only --diff-filter=ACM | while read file; do
if [ -f "$file" ]; then
# 跳过排除文件
skip=false
for pattern in $EXCLUDE_PATTERNS; do
if [[ "$file" == $pattern ]]; then
skip=true
break
fi
done
if [ "$skip" = false ]; then
size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
size_mb=$(echo "scale=2; $size / 1048576" | bc)
if (( $(echo "$size_mb > $MAX_FILE_SIZE_MB" | bc -l) )); then
echo "❌ 文件过大: $file (${size_mb}MB)"
exit 1
elif (( $(echo "$size_mb > $MAX_FILE_SIZE_MB * 0.8" | bc -l) )); then
echo "⚠️ 文件接近限制: $file (${size_mb}MB)"
fi
fi
fi
done
# 检查暂存文件总体积
echo "检查暂存文件总体积..."
total_size=0
git diff --cached --name-only --diff-filter=ACM | while read file; do
if [ -f "$file" ]; then
size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
total_size=$((total_size + size))
fi
done
total_size_mb=$(echo "scale=2; $total_size / 1048576" | bc)
if (( $(echo "$total_size_mb > $MAX_TOTAL_SIZE_MB" | bc -l) )); then
echo "❌ 暂存文件总体积过大: ${total_size_mb}MB"
exit 1
fi
echo "✅ 体积检查通过"
exit 0
使用 Git Hooks 管理工具
推荐使用 husky 管理钩子:
// package.json
{
"husky": {
"hooks": {
"pre-commit": "node scripts/check-bundle-size.js"
}
},
"scripts": {
"check:size": "node scripts/check-bundle-size.js"
}
}
注意事项
- 设置合理的阈值:根据项目特点和网络环境调整
- 考虑 Git LFS:对大文件使用 Git Large File Storage
- 忽略特定文件和目录:如
.map文件、node_modules - 考虑并行处理:对大项目使用
xargs或其他并行工具加速 - 提供详细信息:在输出中包含文件路径、大小和建议
这样可以在提交前自动检查包体积,避免意外提交过大的文件。