UNPKG

hh-cli

Version:

huihua front end cli

311 lines (280 loc) 9.78 kB
/** * Created by yangxun on 2018/3/30. */ var fs = require('fs'); var colors = require('colors'); var path = require('path'); var moment = require('moment'); var AliOss = require('ali-oss'); var config = require('./config'); // var sharp = require('sharp'); var md5 = require('./md5.min'); var imagemin = require('imagemin'); var imageminJpegtran = require('imagemin-jpegtran'); var imageminPngquant = require('imagemin-pngquant'); var Co = require('co'); class OSS { constructor(){ this.dir = __dirname; let config = fs.readFileSync(this.dir + '/.ossconfig').toString(); this.rules = config.replace(/'/g, '"').split('\n').filter(line=>{return line.trim() != ''}); this.dateStr = moment().format('YYYYMMDD'); } /** * 执行命令 * @param type init|publish * @param file directory|file */ async commander(type, file){ if(type == 'init'){ this._OSSInit(file); return; } let rules = this._loadConfig(); let target = rules.path; if(file != undefined){ target = file; } if(target == ''){ await this._OSSPublish(rules, `${process.cwd()}`); } else{ await this._OSSPublish(rules, `${process.cwd()}/${target}`); } } /** * 加载publish 配置文件 * @returns {*} * @private */ _loadConfig(){ let cwd = process.cwd(); let configPath = `${cwd}/.ossconfig`, rules = this.rules; if(fs.existsSync(configPath) && fs.statSync(configPath).isFile()){ let config = fs.readFileSync(configPath).toString(); rules = config.replace(/'/g, '"').split('\n').filter(line=>{return line.trim() != ''}); } let ruleJson = {}; for(let i=0; i<rules.length; i++){ let rule = rules[i]; rule = rule.replace(/ *= */, '='); ruleJson[rule.split('=')[0]] = rule.split('=')[1]; } return ruleJson; } /** * 初始化oss init config * @private */ _OSSInit(type){ let cwd = process.cwd(); let configPath = `${cwd}/.ossconfig`; if(fs.existsSync(configPath) && fs.statSync(configPath).isFile()){ console.error('warn: This directory has been initialized'.red); return; } console.log('===== oss ====='.green); console.log('start init'.green); let data = fs.readFileSync(this.dir + '/.ossconfig').toString(); let rules = data.replace(/'/g, '"').split('\n').filter(line=>{return line.trim() != ''}); if(['html', 'picture', 'js', 'css', 'common'].indexOf(type)==-1){ type = 'common'; } let bucket = `hh-oss-${type}`, endpoint = config.alioss[type]; for(let i =0; i<rules.length; i++){ if(/^bucket/.test(rules[i])){ rules[i] = `bucket = ${bucket}`; } else if(/^endpoint/.test(rules[i])){ rules[i] = `endpoint = ${endpoint}`; } if(/^prefix/.test(rules[i])){ rules[i] = `prefix = hhcli/${this.dateStr}`; } } fs.writeFileSync(configPath, rules.join('\n')); //fs.copyFileSync(`${this.dir}/.ossconfig`, configPath); console.log('end init'.green); console.log('===== succeed ====='.green); } /** * 发布 * @param rules * @param target * @private */ async _OSSPublish(rules, target){ if(fs.existsSync(target)){ let stat = fs.statSync(target); if(stat.isFile()){ let extName = path.extname(target); if(rules.target.indexOf(extName)>-1 && extName != ''){ await this.uploadToOSS(rules, target); } } if(stat.isDirectory()){ let files = fs.readdirSync(target); for(let i =0; i<files.length; i++){ await this._OSSPublish(rules, `${target}/${files[i]}`); } } } else{ console.error(`${target} does not exist`.red); } } /** * 构建oss client * @param type * @returns {*} * @private */ _buildClient(rules, type){ /*if(['png', 'jpg', 'jpeg', 'gif', 'js', 'css', 'html', 'less'].indexOf(type)==-1){ return null; }*/ /*if(type == 'js' || type == 'css' || type == 'less'){ type = 'html'; } else if(['png', 'jpg', 'jpeg', 'gif'].indexOf('type')>-1){ type = 'picture'; } else if(type == 'html' && type != 'htm'){ type = 'html'; } else { type = 'common'; }*/ type = 'html'; let bucket = `hh-oss-${type}`, endpoint = config.alioss[type]; if(rules.bucket && rules.bucket != ''){ bucket = rules.bucket; } if(rules.endpoint && rules.endpoint != ''){ endpoint = rules.endpoint; } return new AliOss({ endpoint: endpoint, cname: true,//配合endpoint使用,如果指定了cname为true,则将endpoint视为用户绑定的自定义域名 bucket: bucket,//如果未指定bucket,则进行Object相关的操作时需要先调用useBucket接口(只需要调用一次) accessKeyId: rules.ossAccessKeyId, accessKeySecret: rules.ossAccessKeySecret }); } /** * 上传文件到oss * @param target */ async uploadToOSS(rules, target){ let type = path.extname(target), filePath = target.replace(process.cwd(), ''); let cwd = process.cwd(); let client = this._buildClient(rules, type.replace(/\./, '')), space = `${rules.prefix || 'hhcli'}`; // space = `${rules.prefix || 'hhcli'}${cwd.replace(path.dirname(cwd), '')}/${this.dateStr}`; if(rules.basedir === 'true'){ space += `${cwd.replace(path.dirname(cwd), '')}`; } if(['.png', '.jpg', '.jpeg', '.gif'].indexOf(type)>-1 && rules.zip === 'true'){ // let result = await this.sharpImage(type.replace(/\./, ''), target); let result = await this.imagemin(type.replace(/\./, ''), target); if(result.status == 0){ target = result.fileBuffer; } } let fileKey = `${space}${filePath}`; //修改名称 if(rules.md5Name.indexOf(type)>-1){ let key = ''; if(typeof target === 'string'){ key = md5(fs.readFileSync(target)); } else{ key = md5(target); } //有后缀的情况 if(/\.[^\.\/]*$/.test(fileKey)){ fileKey = fileKey.replace(/[^\/]*(\.[^\.]*)$/, `${key}$1`); } //无后缀的情况 else{ fileKey = fileKey.replace(/[^\/]*$/, key); } } return new Promise((resolve, reject)=>{ Co(function* () { var result = yield client.put(fileKey.replace(/\\/g, '/'), target); if(result.res && result.res.status == 200){ let url = result.url; /*if(['html', 'js', 'css'].indexOf(type.replace(/\./, ''))>-1){ url = url.replace(/^http:\/\//, 'https://'); }*/ if(url.indexOf('hh-oss-html')>-1){ url = url.replace(/^http:\/\//, 'https://'); } console.log(`【success】: ${url}`.green); resolve(result); } else{ console.log(`【failed】: ${result.name}`.red); } }).catch(function (err) { console.log(err); reject(err); }); }) } async imagemin(type, path){ return new Promise((resolve, reject)=>{ imagemin([path], { plugins: [ imageminJpegtran(), imageminPngquant({quality: '60-80'}) ] }).then(files => { resolve({ status: 0, fileBuffer: files[0].data, size: files[0].data.toString().length }); //=> [{data: <Buffer 89 50 4e …>, path: 'build/images/foo.jpg'}, …] }).catch(e=>{ resolve({ status: -1, fileBuffer: path }); }); }); } /** * 压缩图片 * @param type 图片类型 * @param path * @returns {Promise} */ async sharpImage(type, path){ return new Promise((resolve, reject)=>{ //压缩图片 let imgSharp = sharp(path); //.webp({quality: 70}) //.min() if(type == 'png'){ imgSharp = imgSharp.png({compressionLevel: 8}); } else if(type == 'jpg' || type == 'jpeg'){ imgSharp = imgSharp.jpeg({quality: 80}); } imgSharp.toBuffer().then(fileBuffer=>{ resolve({ status: 0, fileBuffer: fileBuffer, size: fileBuffer.toString().length }); }).catch(e=>{ resolve({ status: -1, fileBuffer: path }); }); }); } } module.exports = new OSS();