UNPKG

@mora/tinypng

Version:

基于 tinypng 封装的一个支持 `nodejs`、`命令行`和`webpack`的图片压缩工具

140 lines (139 loc) 5.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tinify = require("tinify"); var fs = require("fs-extra"); var path = require("path"); var warn = require("mora-scripts/libs/sys/warn"); var SVGO = require("svgo"); var TokenPicker_1 = require("mora-common/feature/TokenPicker"); var helper_1 = require("./helper"); var default_1 = (function () { function default_1(option) { var _this = this; this.option = option; this.fakeTokenMap = {}; var fakeTokens = option.tokens.map(function (token) { var fake = 'fake-' + helper_1.hash(token); _this.fakeTokenMap[fake] = token; return fake; }); if (option.recordFile && !fs.existsSync(option.recordFile)) { helper_1.writeFileSync(option.recordFile, '{}'); } this.tp = new TokenPicker_1.default(fakeTokens, option); this.svgo = new SVGO(option.svgo || { plugins: [{ removeTitle: true }] }); } default_1.prototype.tiny = function (source, target, option) { var _this = this; return new Promise(function (resolve, reject) { if (typeof target === 'object') { option = target; target = null; } option = Object.assign({}, _this.option, option); var cacheFn; var sourceBuffer = Buffer.isBuffer(source) ? source : null; if (typeof source === 'string' && !helper_1.isNetFile(source)) { sourceBuffer = fs.readFileSync(source); if (helper_1.isSvgFile(source)) { var svgo = option.svgo !== _this.option.svgo ? new SVGO(option.svgo) : _this.svgo; return svgo.optimize(sourceBuffer.toString(), function (rtn) { if (rtn.data) _this.tinySuccess(new Buffer(rtn.data), target, resolve, reject); else reject(rtn); }); } } var cacheDir = _this.option.cacheDir; if (cacheDir && sourceBuffer) { var cacheBuffer = getCache(cacheDir, sourceBuffer); if (cacheBuffer) return _this.tinySuccess(cacheBuffer, target, resolve, reject); cacheFn = function (destBuffer) { return setCache(cacheDir, sourceBuffer, destBuffer); }; } try { _this.tp.do(function (token, expire) { tinify.key = _this.fakeTokenMap[token]; tinypngProcess(_this.fakeTokenMap[token], source, option) .then(function (buffer) { if (cacheFn) cacheFn(buffer); _this.tinySuccess(buffer, target, resolve, reject); }) .catch(function (e) { return _this.tinyFailed(e, expire, resolve, reject); }); }); } catch (e) { reject(e); } }); }; default_1.prototype.tinySuccess = function (buffer, target, resolve, reject) { if (!target) resolve(buffer); fs.writeFile(target, buffer, function (err) { if (err) reject(err); else resolve(buffer); }); }; default_1.prototype.tinyFailed = function (e, expire, resolve, reject) { if (e instanceof tinify.AccountError) { warn(e.message); var d = new Date(); expire(new Date(d.getFullYear(), d.getMonth() + 1, d.getDate()).getTime()); } else { reject(e); } }; return default_1; }()); exports.default = default_1; function getCache(cacheDir, buffer) { try { var file = path.join(cacheDir, helper_1.hash(buffer)); var stat = fs.lstatSync(file); if (stat.isSymbolicLink()) file = fs.readlinkSync(file); return fs.readFileSync(file); } catch (e) { } } function setCache(cacheDir, srcBuffer, destBuffer) { var srcFile = path.join(cacheDir, helper_1.hash(srcBuffer)); var destFile = path.join(cacheDir, helper_1.hash(destBuffer)); helper_1.writeFileSync(destFile, destBuffer); if (srcFile !== destFile) fs.symlinkSync(destFile, srcFile); } function tinypngProcess(token, source, option) { var proxy = option.proxy, resize = option.resize; Object.assign(tinify, { key: token, proxy: proxy }); var tinySource; if (typeof source === 'string') { if (helper_1.isNetFile(source)) { tinySource = tinify.fromUrl(source); } else { tinySource = tinify.fromFile(source); } } else { tinySource = tinify.fromBuffer(source); } if (resize) tinySource = tinySource.resize(resize); return new Promise(function (resolve, reject) { tinySource.toBuffer(function (err, buffer) { if (err) { reject(err); } else { resolve(buffer); } }); }); }