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

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

月光魔力鸭

2018-12-14 08:40 阅读 813 喜欢 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


感谢支持!

赞赏支持
提交评论
评论信息 (请文明评论)
暂无评论,快来快来写想法...
推荐
做了一个阿里云开发者社区自动签到,想着能积攒一些换点啥东西,放在服务器上出现了各种错误。
有一个需求,需要公司的LOGO信息,但是没有,只有公司的名字,想着先生成个默认的(本来是可以通过前端判断然后合成的..但是不想改小程序了),于是开始准备处理。
互联网应用经常需要存储用户上传的图片,比如facebook相册。 facebook目前存储了2600亿张照片,总大小为20PB,每张照片约为80KB。用户每周新增照片数量为10亿。(总大小60TB),平均每秒新增3500张照片(3500次写请求),读操作峰值可以达到每秒百万次
最近有客户提出了这么一个需求:微信dat文件在解码后的图片无法按照时间进行排序。 是的,解码后的文件的时间都是解码的时间,由于软件比较多,当时没做自动更新,所以在这里做一个小工具,可以将对应的解码后的图片的时间修改为微信dat文件对应的时间
在平时nodejs练习过程中,可能会安装多个不同版本的nodejs,那么我们如何来轻松的管理和切换呢?推荐你一个nvm来试试水
通过pm2来实现nodejs应用的集群,不过我之前没做session共享,导致.. 登录不上啊 啊啊啊,无奈,又重新对redis进行了集成。
发布自己的nodejs应用后,需要进行管理,目前一般都pm2来进行管理,这里记录下常用的命令。
最近在折腾的时候又想写less了,但是换框架了,成了thinkjs,考虑到开发阶段一直编译编译less的情况..最终根据middleware的特点实现了一个超级简单的less中间件。