分享下自己的自动打包小工具

分享下自己的自动打包小工具

月光魔力鸭

2018-12-14 08:40 阅读 1031 喜欢 3 自动打包 nodejs命令

在开发项目过程中,经常需要将开发的项目部署到服务器上,但是每个环境都有每个环境的配置等等,如果每次打包的时候都要去调整(可能删除、替换等),那就很烦人了,这里分享下自己实现的几个简单的小工具(当然这个工具可能只对我自己有用),希望能够帮到你。

其实,思路和实现都很简单,无非就是复制、删除、调用命令而已。

开发环境-tomcat

之前的项目是直接通过myeclipse来往tomcat发布,这样打包的话,只需要把tomcat下的相关文件进行处理并打包即可。

主要的流程就是:

config.properties

根据流程,其实就可以抽离一些常用操作(比如:复制、重命名、删除等),然后通过json来配置要做的过程(这样能够适应同类的其他项目)。

代码: util.js 主要是用于抽取的一些操作,包括删除、复制、重命名等,具体的步骤请看下面的json文件。

let {join} = require('path');
let fs = require('fs');
class exeIssuse{
	constructor( json ){
		this.json = json ;
	}
	callisu () {
		if(this.json.length > 0){
			let isu = this.json[0];
			this.json = this.json.splice(1);
			this.name = isu.name;
			this.path = isu.path;
			this.actions = isu.actions;
			this.encodexml = isu.encodexml;
			let thiz = this;
			this.actions.forEach(function( info ){
				thiz.step(info);
			});
			this.packer();
		}else{
			console.log(`全部结束,已经没有需要打包的路径了。`);
			//打开文件夹
			require('child_process').exec('start '+__dirname);
		}
	}
	step ( info ){
		let type = info.key;
		let repath = info.repath || '/';
		let from = info.from || '';
		let to = info.to ||'';
		if(type === 'del'){
			this.del(repath,from);
		}else if( type === 'rename'){
			this.rename(repath,from,to);
		}else if(type === 'copy'){
			this.copy(repath,from,to);
		}
	}

	packer () {
		let name = this.name;
		let exec = require('child_process').exec;
		let topath = join(__dirname,this.name);
		let frompath = this.path;
		let cmd = 'jar cvf '+topath+' -C '+frompath+' .';
		var cp = exec(cmd);
		let thiz = this;
		cp.stdout.on('close',function(){
			console.log(`---${name}打包结束,等待10s后进行加密war包`)
		});
		cp.on('exit',function(){
			//10s后调用
			setTimeout(function(){
				thiz.encode();	
			},10000);
		})
	}

	//加密
	encode () {
		let thiz = this;
		let encodexml = this.encodexml;
		let exec = require('child_process').exec;
		let cmd = 'java -Xms128m -Xmx512m -jar allatori.jar '+encodexml;
		console.log(cmd);
		var cp = exec(cmd,function(err,stdout){
			console.log(err);
			console.log(stdout);
			console.log(`---war包加密结束,请查看`);
			thiz.callisu();
		});
		
		// cp.stdout.on('close',function(){
			
		// })
	}

	del ( repath , from ) {
		console.log(`删除文件:${from}`)
		let dir = join(this.path,repath);
		from = typeof from == 'string' ? [from] : from;

		from.forEach(function( item ){
			if(item !== ''){
				let filePath = join(dir,item);
				fs.unlinkSync(filePath);
			}
		});

	}

	copy ( repath, from , to){
		let topath = join(this.path,repath,to);
		console.log(`复制文件从${from}到${topath}`);
		var buffer = fs.readFileSync(from);
		fs.writeFileSync(topath,buffer);
	}
	rename ( repath, from ,to){
		
		let dir = join(this.path,repath);
		let fromPath = join(dir,from);
		let topath = join(dir,to);
		console.log(`重命名:${fromPath}——————${topath}`)
		fs.renameSync(fromPath,topath);
	}
}
module.exports = exeIssuse;

dev.json 开发环境的部署过程-操作步骤.定义一些操作类型以及相关的数据

[
{
	"name":"byyresource-dev.war",
	"path":"I:/tomcat7/webapps/byyresource/",
	"encodexml":"byyresource/config-war-dev.xml",
	"actions":[
		
		{
			"key":"del",
			"repath":"/WEB-INF/classes",
			"from":["config.properties","spring.xml","license.key","license.lic"]
		},{
			"key":"rename",
			"repath":"/WEB-INF/classes",
			"from":"config-dev.properties",
			"to":"config.properties"
		},
		{
			"key":"rename",
			"repath":"/WEB-INF/classes",
			"from":"spring-dev.xml",
			"to":"spring.xml"
		},{
			"key":"copy",
			"repath":"/WEB-INF/classes",
			"from":"e:/node/boyuyun/packer/dev/license.key",
			"to":"license.key"
		},{
			"key":"copy",
			"repath":"/WEB-INF/classes",
			"from":"e:/node/boyuyun/packer/dev/license.lic",
			"to":"license.lic"
		}
	]
}
]

app.js 该文件用于发起打包过程

/**删除文件、文件重命名,最后打包**/
let packer = require('./byyresource/dev.json');

let issue =require( './util');

if(packer.length == 0){
	console.log('no issuses');
	return;
}

let ins = new issue(packer);
ins.callisu();

剩下的,就是执行了。node app 然后等待结果就可以啦。

开发环境-springboot

后来,项目使用了spring-boot ,然后导致tomcat的一些东西没有了(可能我没找到),所以上面的打包过程就不适用了。

这个环境的大体流程是:

代码: app.js 这个项目目前只做了一个简单版本的,还没有通用到其他项目。过程也比较简单(只是多了个babel编译)

//对spring-boot项目进行打包处理
let fs = require('fs');
let {join} = require('path');
let {spawn} = require('child_process');

let TARGET = 'i:/wp2018/ByyTeaching'
let CURRENT = __dirname;
let ENV = 'jiqun';
//1.配置文件替换或者某些项目替换

function exeCmd(cmd,dir){
	return new Promise((resolve,reject)=>{
		let ls = spawn('cmd.exe',['/c'].concat(cmd),{
			cwd : dir
		});
		ls.stdout.on('data',(data)=>{
			// console.log(`stdout: ${data}`);	
		});
		ls.stderr.on('data', (data) => {
		  // console.log(`stderr: ${data}`);
		  reject(false);
		});
		ls.on('close',function(){
			console.log(cmd.join(' ')+'命令执行结束.')
			resolve();
		});
	});
}
function copy(sourcePath,targetPath){
	console.log(sourcePath);
	console.log(targetPath);
	return new Promise((resolve,reject)=>{
		let rs = fs.createReadStream(sourcePath);
		let ws = fs.createWriteStream(targetPath);
		rs.on('data',function(data){
			ws.write(data);
		});
		rs.on('close',function(){
			rs.close();
			ws.close();
			console.log('复制结束:'+sourcePath+'---'+targetPath);
			resolve();//复制结束

		})
	});
}
//删除目录下的所有文件
function delFile(fileUrl,flag){
	if (!fs.existsSync(fileUrl)) return;
    // 当前文件为文件夹时
    if (fs.statSync(fileUrl).isDirectory()) {
        var files = fs.readdirSync(fileUrl);
        var len = files.length,
            removeNumber = 0;
        if (len > 0) {
            files.forEach(function(file) {
                removeNumber ++;
                var stats = fs.statSync(fileUrl+'/'+file);
                var url = fileUrl + '/' + file;
                if (fs.statSync(url).isDirectory()) {
                    delFile(url,true);
                } else {
                    fs.unlinkSync(url);
                }
            });
            if(len == removeNumber && flag){
            	fs.rmdirSync(fileUrl);
            }
        } else if(len == 0 && flag){
            fs.rmdirSync(fileUrl);
        }
    } else {
        // 当前文件为文件时
        fs.unlinkSync(fileUrl);
        console.log('删除文件' + fileUrl + '成功');
    }
}

//开始执行

exeCmd(['jar','-cvf','byyteaching.war','./'],TARGET)
.then(()=>{
	//复制
	return copy(join(TARGET,'byyteaching.war'),join(CURRENT,'source','base','byyteaching.war'));
})
.then(()=>{
	//执行解压命令
	return exeCmd(['jar','-xvf','byyteaching.war'],join(CURRENT,'source','base'));
})
.then(()=>{
	//删除war包
	delFile(join(CURRENT,'source','base','byyteaching.war'));
	delFile(join(TARGET,'byyteaching.war'));
})
.then(()=>{
	//替换application.yml 文件
	let applicationPath = join(CURRENT,'source','base','src','main','resources','application.yml');
	delFile(applicationPath);
	return copy(join(CURRENT,ENV,'application.yml'),applicationPath);
})
.then(()=>{
	//复制license
	let licensePath = join(CURRENT,'source','base','src','main','resources','license.key');
	return copy(join(CURRENT,ENV,'license.key'),licensePath);
})
.then(()=>{
	//复制license
	let licensePath = join(CURRENT,'source','base','src','main','resources','license.lic');
	return copy(join(CURRENT,ENV,'license.lic'),licensePath);
})
.then(()=>{
	//执行js编译
	return exeCmd(['node','index',join(CURRENT,'source','base','src','main','resources','static','js')],join(CURRENT,'babel'));
})
.then(()=>{
	//执行打包命令
	return exeCmd(['mvn','package'],join(CURRENT,'source','base'));
})
.then(()=>{
	//复制war包到目标地址
	return copy(join(CURRENT,'source','base','target','byyteaching.war'),join(CURRENT,'source',ENV,'byyteaching.war'));
})
.then(()=>{
	//打开文件夹
	exeCmd(['start',join(CURRENT,'source',ENV)],join(CURRENT,'source',ENV));
})
.then(()=>{
	//删除base下的源文件
	delFile(join(CURRENT,'source','base'));
})

啦啦啦,解放了双手(虽然只是一小会,但是能够通过简单的命令来实现也是很得意的../大神不要踩/)


可能我的代码只能我来用,但是如果能够给你提供一点点..哪怕一点点小小的灵感或思路,那我也很高兴啦。

转载请注明出处: https://chrunlee.cn/article/nodejs-package-tool.html


感谢支持!

赞赏支持
提交评论
评论信息 (请文明评论)
暂无评论,快来快来写想法...
推荐
近期有个小工具,需要使用到本地数据库,想使用sqlite ,本来以为是个手到擒来的活... 没成想卡在了开始上。
前段时间学习到了nodejs的net模块这部分,正好想实现一个局域网内的文件下载小demo,噔噔噔噔... 兴趣推动 ,马上搞一搞。
当我们做爬虫或其他的一些应用的时候,如果需要一些短信验证,但是又没有那么多手机号,又不能放人在那里一直输入的时候?怎么办?
学习爬虫的时候突然有想到想做一个音乐播放小站,可以给自己或朋友听,但是音乐哪里来呢??想到自己常听的豆瓣FM,就越发的想把这些音乐都拿下来,因此有了下文通过豆瓣FM批量抓取上万首音乐,目前已经3W+。
前几天给朋友帮忙,想要一个一模一样的网站...自告奋勇去帮忙.. 结果发现之前一直没处理过类似的情况,虽然也写过爬虫,不过看了下网站,也不算麻烦。于是简单实现了这个自动抓站的功能,最终整理成为一个自动抓站的工具,能省很多的事情。
有一个需求,需要公司的LOGO信息,但是没有,只有公司的名字,想着先生成个默认的(本来是可以通过前端判断然后合成的..但是不想改小程序了),于是开始准备处理。
在我们做运维或者小工具的时候,总会有些需要提醒的事情,比如服务器宕机或者天气提醒,但是发email又会不够及时或者可能会忽略,那么短信就是一个不错的选择了
在使用marked来做md解析的时候,部分解析规则可能并不是很如意,比如说,我在md中写了a标签,但是这些标签都是在当前页面替换的,而我想要的是新打开窗口。