场景
在一般的网页开发过程中,往往我们都要下载较多的切图,而这些切图未必都做了压缩,即使做了压缩,效果未必能达到理想效果。
要解决这种图片压缩问题,途径有很多
1. 手动将图片丢到xx站点,压缩好之后再放进项目
2. 让UI给已经压缩好的图
这些方式都得靠人工操作,人工操作往往存在一些不确定性,比如忘记了要压缩,也察觉不出来,如果是多人开发,问题会更大。下面我将列举一些常规的解决方案
1. 当代码提交时,拦截大图的提交,提醒开发人员手动压缩(之前博文有实现过)
2. 当提交代码时,主动压缩大图并自动提交(本期讨论重点)
本期将解决方案2展开讨论:主动压缩大图并自动提交
1.安装 Husky:
确保你已经在项目中安装了 Husky。如果还没有安装,可以使用以下命令:
npm install husky --save-dev
2.启用 Git 钩子:
运行以下命令以启用 Husky 钩子:
npx husky install
3.添加 pre-commit 钩子:
使用 Husky 添加 pre-commit 钩子:
npx husky add .husky/pre-commit "npx lint-staged"
4.安装 lint-staged:
为了配合 Husky,安装 lint-staged
来处理文件:
npm install lint-staged --save-dev
5.配置 lint-staged:
在 package.json
中添加 lint-staged
配置:
{ "lint-staged": { "**/*.{weapp,jpg,png}": "node scripts/compress-images.mjs" } }
6.编写图片压缩脚本(tinify):
安装相关依赖
pnpm install tinify fs-extra glob --save-dev
在项目中创建一个 scripts
文件夹,并在其中添加 compress-images.mjs 文件,内容如下:
程序所包含的逻辑
1. 压缩使用的是tinify压缩工具,官网 https://tinypng.com/
2. 它只压缩图片大于300kb的图
3. 压缩的图将覆盖原图
4. 只有在 git commit -m 'xx' 时会触发图片压缩
import tinify from 'tinify'; import fs from 'fs-extra'; // 设置你的 Tinify API key tinify.key = 'xxx'; const SIZE_LIMIT = 300 * 1024; // 300KB async function compressImage(filePath) { try { const stats = await fs.stat(filePath); // 检查文件大小和压缩标记 if (stats.size < SIZE_LIMIT) { console.log(`跳过 ${filePath} (小于300KB)`); return; } console.log(`压缩中: ${filePath}`); // 使用 tinify 压缩图片 const source = tinify.fromFile(filePath); await source.toFile(filePath); console.log(`压缩完成: ${filePath}`); } catch (error) { console.error(`压缩失败 ${filePath}:`, error); } } async function main() { try { // 获取待提交的文件列表 const files = process.argv.slice(2); console.log(`找到 ${files.length} 个图片文件`); // 并发压缩图片 await Promise.all(files.map(compressImage)); console.log('所有图片压缩完成!'); } catch (error) { console.error('发生错误:', error); process.exit(1); } } main();
其他场景
有时候你可能需要再已提交的图片中压缩图片,只需要运行一行命令就能处理整个项目的图片压缩
在package.josn 中 的scripts添加命令
"scripts": { "compress": "node scripts/compress-images.mjs" }
在scripts中创建compress-images.mjs,内容如下
程序所包含的逻辑
1. 压缩使用的是tinify压缩工具,官网 https://tinypng.com/
2. 它只压缩图片大于300kb的图
3. 图片压缩完之后会在图片同级目录生成一个文件已压缩标识 例如:我对a.png图片进行了压缩,那同级目录就会生成a.compress-marker 空白文件,只有每次压缩前都会判断这个文件有没有被压缩
4. 压缩的图将覆盖原图
import tinify from 'tinify'; import fs from 'fs-extra'; import {glob} from 'glob'; // 设置你的 Tinify API key tinify.key = 'xxx'; // 压缩标记文件 const COMPRESS_MARKER = '.compress-marker'; const SIZE_LIMIT = 300 * 1024; // 300KB async function compressImage(filePath) { try { const stats = await fs.stat(filePath); const markerPath = `${filePath}${COMPRESS_MARKER}`; // 检查文件大小和压缩标记 if (stats.size < SIZE_LIMIT || await fs.pathExists(markerPath)) { console.log(`跳过 ${filePath} (已压缩或小于300KB)`); return; } console.log(`压缩中: ${filePath}`); // 使用 tinify 压缩图片 const source = tinify.fromFile(filePath); await source.toFile(filePath); // 添加压缩标记 await fs.writeFile(markerPath, ''); console.log(`压缩完成: ${filePath}`); } catch (error) { console.error(`压缩失败 ${filePath}:`, error); } } async function main() { try { // 获取所有图片文件 // const files = glob.sync('**/*.{png,jpg,jpeg}', { // ignore: ['node_modules/**', 'dist/**'] // }); // 获取待提交的文件列表 const files = process.argv.slice(2); console.log(`找到 ${files.length} 个图片文件`); // 并发压缩图片 await Promise.all(files.map(compressImage)); console.log('所有图片压缩完成!'); } catch (error) { console.error('发生错误:', error); process.exit(1); } } main();
标签:git,console,filePath,hooks,压缩,tinify,js,error,图片 From: https://www.cnblogs.com/yz-blog/p/18600083