自从Node.js出现,它的好基友npm(node package manager)也是我们日常开发中必不可少的东西。npm让js实现了模块化,使得复用其他人写好的模块(搬砖)变得更加方便,也让我们可以分享一些自己的作品给大家使用(造轮子),今天这里我就给大家分享一个用命令行压缩图片的工具,它的用法大致是这样的:
// 全局安装后,在图片目录下,运行这行 $ tinyhere
这样就把文件夹内的图片进行压缩。这里压缩采用的是 tinypng 提供的接口,压缩率大致上是50%,基本可以压一半的大小。以前在写项目的时候,测试验收完成后总是要自己手动去压一次图片,后来想把这个枯燥重复的事自动化去完成(懒),但是公司脚手架又没有集成这个东西,就想自己写一个轮子做出来用用就好了。它的名字叫做tinyhere,大家可以去安装使用试一下
$ npm i tinyhere -g
2、npm简介
如果要写一个模块发布到npm,那么首先要了解一下npm的用法。
给这个模块建一个文件夹,然后在目录内运行npm init来初始化它的package.json,就是这个包的描述
// 个人比较喜欢后面带--yes,它会生成一个带默认参数的package.json $ npm init (--yes)
package.json详情:
{ "name": "pkgname", // 包名,默认文件夹的名字 "version": "1.0.0", "description": "my package", "main": "index.js", // 如果只是用来全局安装的话,可以不写 "bin": "cli", // 如果是命令行使用的话,必须要这个,名字就是命令名 "scripts": { "test": "echo \"Error: no test specified\" && exit 1" // npm run test对应的test }, "keywords": ['cli', 'images', 'compress'], "author": "croc-wend", "license": "MIT", ... }
更多配置信息可以参考一下vue的package.json的https://github.com/vuejs/vue/blob/dev/package.json
初始化完成之后,你就可以着手写这个包了,当你觉得你写好了之后,就可以发布到npm上面
npm login npm publish + pkgname@1.0.0 // 成功
这时,你在npm上面搜你的包名,你写在package.json 的信息都会被解析,然后你的包的页面介绍内容就是你的README.md
3、写这个包
包初始化好了之后,我们就可以开始写这个包了
对于这个压缩工具来说,要用到的素材只有两个,tinypng接口要用到的 api-key,需要压缩的图片,所以我对这两个素材需要用到的一些操作进行了以下分析:
我的初衷是想把这个命令写的尽量简单,让我可以联想到压缩图片=简单,所以我待定了整个包只有一个单词就能跑,是这样:
$ tinyhere
其他的操作都放在子命令和可选项上。
然后开始划分项目结构
大致上是这样,把全局命令执行的 tinyhere 放在bin目录下,然后subCommand负责提供操作函数,然后把可复用的函数(比如读写操作)抽离出来放在util上,比较复杂的功能单独抽离成一个文件,比如compress,然后导出一个函数给subCommand。至于存放用户的api-key,就存放在data下面的key里。
tinyhere的执行文件就负责解析用户的输入,然后执行subCommand给出的对应函数。
4、过程解析
压缩图片的这个包的过程是这样的:
1、解析当前目录内的所有图片文件,这里应该根据二进制流及文件头获取文件类型mime-type,然后读取文件二进制的头信息,获取其真实的文件类型,来判断它是否真的是图片文件,而不是那些仅仅是后缀名改成.png的假货
2、 如果用户有要求把压缩的图片存放到指定目录,那就需要生成一个文件夹来存放它们。那么,首先要判断这个路径是否合法,然后再去生成这个目录
3、判断用户的api-key的剩余次数是否足够这次的图片压缩,如果这个key不够,就换到下一个key,知道遍历文件内所有的key找到有可用的key为止。
4、图片和key都有了,这时可以进行压缩了。用一个数组把压缩失败的存起来,然后每次压缩完成都输出提示,在所有图片都处理完成后,如果存在压缩失败的,就询问是否把压缩失败的图继续压缩
5、这样,一次压缩就处理完成了。压缩过的图片会覆盖原有的图片,或者是存放到指定的路径里
ps:$ tinyhere deep >>> 把目录内的所有图片都进行压缩(含子目录)。这个命令和上述的主命令的流程有点不同,目前有点头绪,还没有开发完成,考虑到文件系统是树形结构,我目前的想法是通过深度遍历,把存在图片的文件夹当作一个单位,然后递归执行压缩。
其他: