@mora/tinypng
Version:
基于 tinypng 封装的一个支持 `nodejs`、`命令行`和`webpack`的图片压缩工具
140 lines (139 loc) • 5.2 kB
JavaScript
;
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);
}
});
});
}