如何写批量压缩静态资源文件

wen 实用脚本 27

本文目录导读:

如何写批量压缩静态资源文件

  1. 使用构建工具(推荐)
  2. 使用命令行工具
  3. Node.js 脚本批量处理
  4. 使用Python脚本批量处理
  5. 配置文件方式

我来介绍几种批量压缩静态资源文件的方法,主要针对图片、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"
    }
  }
}

根据你的需求选择合适的方法:

  1. 开发环境:使用Webpack/Gulp等构建工具,自动化程度高
  2. 快速处理:使用命令行工具,简单直接
  3. 定制需求:自定义脚本,灵活性高
  4. 多语言环境:Node.js/Python脚本都可以

推荐使用Webpack + Gulp的组合,可以集成到开发流程中,实现自动化压缩。

抱歉,评论功能暂时关闭!