本文目录导读:

我来介绍几种批量压缩静态资源文件的方法,主要针对图片、CSS和JS文件。
使用构建工具(推荐)
Webpack 批量压缩
// webpack.config.js
const TerserPlugin = require('terser-webpack-plugin'); // JS压缩
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); // CSS压缩
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin'); // 图片压缩
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, // 删除console
},
},
}),
new CssMinimizerPlugin(),
],
},
plugins: [
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.squooshMinify,
options: {
encodeOptions: {
mozjpeg: { quality: 75 },
png: { quality: 80 },
webp: { lossless: 1 },
},
},
},
}),
],
};
Gulp 批量压缩
// gulpfile.js
const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
const uglify = require('gulp-uglify');
const cleanCSS = require('gulp-clean-css');
// 批量压缩图片
gulp.task('images', () =>
gulp.src('src/images/**/*.{jpg,png,gif,svg}')
.pipe(imagemin([
imagemin.mozjpeg({ quality: 75, progressive: true }),
imagemin.optipng({ optimizationLevel: 5 }),
imagemin.svgo({
plugins: [{ removeViewBox: false }]
})
]))
.pipe(gulp.dest('dist/images'))
);
// 批量压缩JS
gulp.task('scripts', () =>
gulp.src('src/js/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('dist/js'))
);
// 批量压缩CSS
gulp.task('styles', () =>
gulp.src('src/css/**/*.css')
.pipe(cleanCSS({ compatibility: 'ie8' }))
.pipe(gulp.dest('dist/css'))
);
// 同时执行所有任务
gulp.task('compress', gulp.parallel('images', 'scripts', 'styles'));
使用命令行工具
批量压缩图片
# 安装工具
npm install -g imagemin-cli
# 批量压缩所有图片
imagemin src/images/* --out-dir=dist/images
# 递归压缩
imagemin src/images/**/* --out-dir=dist/images
# 指定格式和质量
imagemin src/images/*.{png,jpg} --out-dir=dist/images --plugin.png.quality=80
批量压缩JS
# 安装工具 npm install -g uglify-js # 批量压缩所有JS文件 for file in src/js/*.js; do uglifyjs "$file" --compress --mangle --output "dist/js/$(basename $file)" done
Node.js 脚本批量处理
// compress-assets.js
const fs = require('fs-extra');
const path = require('path');
const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');
const imageminPngquant = require('imagemin-pngquant');
const UglifyJS = require('uglify-js');
const CleanCSS = require('clean-css');
/**
* 批量压缩资源文件
*/
class AssetCompressor {
constructor(config = {}) {
this.config = {
inputDir: config.inputDir || './src',
outputDir: config.outputDir || './dist',
...config
};
}
// 压缩图片
async compressImages() {
const imageDir = path.join(this.config.inputDir, 'images');
const outputDir = path.join(this.config.outputDir, 'images');
await fs.ensureDir(outputDir);
const files = await imagemin([`${imageDir}/*.{jpg,png}`], {
destination: outputDir,
plugins: [
imageminMozjpeg({ quality: 75 }),
imageminPngquant({ quality: [0.6, 0.8] })
]
});
files.forEach(file => {
const originalSize = fs.statSync(path.join(imageDir, path.basename(file.destinationPath))).size;
const compressedSize = file.data.length;
console.log(`✓ 图片压缩: ${path.basename(file.destinationPath)} (${formatBytes(originalSize)} → ${formatBytes(compressedSize)})`);
});
}
// 压缩JS文件
async compressJS() {
const jsDir = path.join(this.config.inputDir, 'js');
const outputDir = path.join(this.config.outputDir, 'js');
await fs.ensureDir(outputDir);
const files = fs.readdirSync(jsDir).filter(file => file.endsWith('.js'));
files.forEach(file => {
const inputPath = path.join(jsDir, file);
const outputPath = path.join(outputDir, file);
const code = fs.readFileSync(inputPath, 'utf8');
const result = UglifyJS.minify(code, {
compress: { drop_console: true },
mangle: true
});
fs.writeFileSync(outputPath, result.code);
const originalSize = code.length;
const compressedSize = result.code.length;
console.log(`✓ JS压缩: ${file} (${formatBytes(originalSize)} → ${formatBytes(compressedSize)})`);
});
}
// 压缩CSS文件
async compressCSS() {
const cssDir = path.join(this.config.inputDir, 'css');
const outputDir = path.join(this.config.outputDir, 'css');
await fs.ensureDir(outputDir);
const files = fs.readdirSync(cssDir).filter(file => file.endsWith('.css'));
files.forEach(file => {
const inputPath = path.join(cssDir, file);
const outputPath = path.join(outputDir, file);
const css = fs.readFileSync(inputPath, 'utf8');
const minified = new CleanCSS({ level: 2 }).minify(css);
fs.writeFileSync(outputPath, minified.styles);
const originalSize = css.length;
const compressedSize = minified.styles.length;
console.log(`✓ CSS压缩: ${file} (${formatBytes(originalSize)} → ${formatBytes(compressedSize)})`);
});
}
// 执行所有压缩
async run() {
console.log('开始批量压缩资源文件...\n');
console.log('=== 压缩图片 ===');
await this.compressImages();
console.log('\n=== 压缩JS ===');
await this.compressJS();
console.log('\n=== 压缩CSS ===');
await this.compressCSS();
console.log('\n✓ 全部压缩完成!');
}
}
// 辅助函数
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
// 使用示例
const compressor = new AssetCompressor({
inputDir: './src',
outputDir: './dist'
});
compressor.run().catch(console.error);
使用Python脚本批量处理
# compress_assets.py
import os
from pathlib import Path
from PIL import Image
import csscompressor
import jsmin
class AssetCompressor:
def __init__(self, input_dir, output_dir):
self.input_dir = Path(input_dir)
self.output_dir = Path(output_dir)
self.output_dir.mkdir(parents=True, exist_ok=True)
def compress_images(self):
"""批量压缩图片"""
image_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.webp'}
for image_path in self.input_dir.rglob('*'):
if image_path.suffix.lower() in image_extensions:
output_path = self.output_dir / image_path.relative_to(self.input_dir)
output_path.parent.mkdir(parents=True, exist_ok=True)
img = Image.open(image_path)
# 压缩图片
if image_path.suffix.lower() in ('.jpg', '.jpeg'):
img.save(output_path, 'JPEG', quality=75, optimize=True)
elif image_path.suffix.lower() == '.png':
img.save(output_path, 'PNG', optimize=True)
elif image_path.suffix.lower() == '.webp':
img.save(output_path, 'WEBP', quality=80)
original_size = image_path.stat().st_size
compressed_size = output_path.stat().st_size
ratio = compressed_size / original_size
print(f"✓ {image_path.name}: {original_size/1024:.1f}KB → {compressed_size/1024:.1f}KB ({ratio:.1%})")
def compress_css(self):
"""批量压缩CSS文件"""
for css_path in self.input_dir.rglob('*.css'):
output_path = self.output_dir / css_path.relative_to(self.input_dir)
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(css_path, 'r', encoding='utf-8') as f:
original_css = f.read()
compressed_css = csscompressor.compress(original_css)
with open(output_path, 'w', encoding='utf-8') as f:
f.write(compressed_css)
original_size = len(original_css)
compressed_size = len(compressed_css)
ratio = compressed_size / original_size
print(f"✓ {css_path.name}: {original_size/1024:.1f}KB → {compressed_size/1024:.1f}KB ({ratio:.1%})")
def compress_js(self):
"""批量压缩JS文件"""
for js_path in self.input_dir.rglob('*.js'):
output_path = self.output_dir / js_path.relative_to(self.input_dir)
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(js_path, 'r', encoding='utf-8') as f:
original_js = f.read()
compressed_js = jsmin.jsmin(original_js)
with open(output_path, 'w', encoding='utf-8') as f:
f.write(compressed_js)
original_size = len(original_js)
compressed_size = len(compressed_js)
ratio = compressed_size / original_size
print(f"✓ {js_path.name}: {original_size/1024:.1f}KB → {compressed_size/1024:.1f}KB ({ratio:.1%})")
def run(self):
print("开始批量压缩资源文件...")
print("\n=== 压缩图片 ===")
self.compress_images()
print("\n=== 压缩CSS ===")
self.compress_css()
print("\n=== 压缩JS ===")
self.compress_js()
print("\n✓ 全部压缩完成!")
if __name__ == "__main__":
compressor = AssetCompressor(
input_dir='./src',
output_dir='./dist'
)
compressor.run()
配置文件方式
// compress-config.json
{
"images": {
"input": "./src/images/**/*",
"output": "./dist/images",
"quality": 75,
"formats": ["jpg", "png", "gif", "svg"],
"options": {
"jpg": { "progressive": true, "quality": 75 },
"png": { "optimizationLevel": 5, "quality": [0.6, 0.8] },
"svg": { "plugins": ["removeViewBox", "cleanupAttrs"] }
}
},
"js": {
"input": "./src/js/**/*.js",
"output": "./dist/js",
"options": {
"compress": { "drop_console": true },
"mangle": true
}
},
"css": {
"input": "./src/css/**/*.css",
"output": "./dist/css",
"options": {
"level": 2,
"compatibility": "ie8"
}
}
}
根据你的需求选择合适的方法:
- 开发环境:使用Webpack/Gulp等构建工具,自动化程度高
- 快速处理:使用命令行工具,简单直接
- 定制需求:自定义脚本,灵活性高
- 多语言环境:Node.js/Python脚本都可以
推荐使用Webpack + Gulp的组合,可以集成到开发流程中,实现自动化压缩。