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

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

月光魔力鸭

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


感谢支持!

赞赏支持
提交评论
评论信息(请文明评论)
暂无评论,快来快来写想法...
推荐
当我们做爬虫或其他的一些应用的时候,如果需要一些短信验证,但是又没有那么多手机号,又不能放人在那里一直输入的时候?怎么办?
获取文件夹内所有的文件。支持递归获取、异步或同步、过滤、返回信息处理。
在开发的时候,经常会有css js 文件的变更,然后部署后发现没有起到作用,最终发现是缓存的问题,如何来方便的解决
关于js的编译和压缩,之前做过一个小工具了,主要就是自己项目成员大都没有这部分的技能,导致发布的时候总需要去编译压缩下.. 最终做了个命令行小工具.. 问题不在这里,前一阵子做压缩的时候发现压缩后竟然是undefined.最终才发现是es6的语法问题。
目前了解的有两个模块可以实现二维码的模块,一个是node-qrcode ,这个算是比较大众的,不过环境比较复杂,所以...连看都没看;还有一个是小众的 qr-image ,这个比较简单,没有其他环境依赖,安装即可用,因为要实现一个简单的在线二维码生成,就先用这个试试水了
在使用marked来做md解析的时候,部分解析规则可能并不是很如意,比如说,我在md中写了a标签,但是这些标签都是在当前页面替换的,而我想要的是新打开窗口。
介绍几个日常开发中常用的几个小工具: anywhere / anywhere-auth / watchlessc / changeext
发布自己的nodejs应用后,需要进行管理,目前一般都pm2来进行管理,这里记录下常用的命令。