node命令行开发

 之前看冯博写的,自己也想写个试试,学习下先

初级的,来自幕客网

点击打开链接


之后再把他写的逐个分析,然后自己写个简单的


var deasync = require('deasync');
var fs = require("fs");
var colors = require("colors");
var gs = require('nodegrass');
var os = require("os");
var currentPath = process.cwd();
var child_process = require("child_process");
var Download = require('download');
var chokidar = require('chokidar');
var md5 = require("md5");
var spawn = require('child_process').spawn;
var templBaseUrl = "http://118.178.231.7:8000/easyme/";//"http://localhost/easyme/";
var lang = ["en-US.lang", "zh-CN.lang", "zh-HK.lang"];
var forever;
var nodeCache = {};
var cheerio = require('cheerio');
var nc = {
    readFileSync: function(path) {
        return JSON.stringify(nodeCache);
    },
    writeFileSync: function(path, content) {
        nodeCache = JSON.parse(content);
    }
}
function stringReplaceAll(str, AFindText, ARepText){
    var raRegExp = new RegExp(AFindText.replace(/([\(\)\[\]\{\}\^\$\+\-\*\?\.\"\'\|\/\\])/g,"\\$1"),"ig");
    return str.replace(raRegExp,ARepText);
}
function readTemplFileContent(url, isCompile, placeTextConfig) {
    var content = "";
    var isReturn = false;
    gs.get(url, function(data) {
        content = data;
        isReturn = true;
    });
    while(!isReturn) {
        deasync.runLoopOnce();
    }
    if(isCompile) {
        for(var key in placeTextConfig) {
            content = stringReplaceAll(content, key, placeTextConfig[key]);
        }
    }
    console.log(url.green + " 读取成功!".green);
    return content;
}
function writeTemplFileContentToApp(content, toDir) {
    fs.writeFileSync(toDir, content);
    console.log(toDir.green + " 创建成功!".green);
}
function execCmd(cmd) {
    if(os.platform() != "darwin") {
        cmd = stringReplaceAll(cmd, "/", "\\");
    }
    var isReturn = false;
    child_process.exec(cmd, {
        encoding: 'utf8',
        timeout: 0,
        maxBuffer: 5000 * 1024,
        killSignal: 'SIGTERM'
    },  function (error, stdout, stderr) {
        isReturn = true;
    });
    while(!isReturn) {
        deasync.runLoopOnce();
    }
}
function isFileExist(url) {
    return fs.existsSync(url);
}
function guid() {
    function S4() {
        return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
    }
    return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
exports.easyMe = {
    initApp: function() {
        new Download({mode: '755'})
            .get(templBaseUrl + "template.tar")
            .run(function (err, files) {
                execCmd("tar -xvf " + "template.tar");
                fs.unlink("template.tar");
                console.log("初始化应用".green + "----------[完成]".green);
            });
    },
    addWidget: function(widgetName) {
        if(!isFileExist("public/javascripts/widget/" + widgetName)) {
            execCmd("mkdir " + "public/javascripts/widget/" + widgetName);
            var widgetContent = readTemplFileContent(templBaseUrl + "widget.js", true, {"{$p}":widgetName});
            writeTemplFileContentToApp(widgetContent, "public/javascripts/widget/" + widgetName + "/" + widgetName +  ".js");
            writeTemplFileContentToApp("", "public/javascripts/widget/" + widgetName + "/" + widgetName +  ".css");
            writeTemplFileContentToApp("<div></div>", "public/javascripts/widget/" + widgetName + "/" + widgetName +  ".html");
            console.log("组件文件创建成功!".green);
        } else {
            console.log("组件文件已存在".yellow);
        }
    },
    deleteWidget: function(widgetName) {
        if(isFileExist("public/javascripts/widget/" + widgetName)) {
            execCmd("rm -rf " + "public/javascripts/widget/" + widgetName);
            console.log("删除".green + widgetName.green + "组件文件成功".green);
        } else {
            console.log("组件文件不存在".yellow);
        }
    },
    createPageHtml: function(pageName) {
        if(!isFileExist("views/" + pageName + ".html")) {
            var viewsContent = readTemplFileContent(templBaseUrl + "views.html", true, {"{$p}":pageName});
            writeTemplFileContentToApp(viewsContent, "views/" + pageName + ".html");
            console.log("主页面模板创建成功!".green);
        } else {
            console.log("主页面模板文件已存在".yellow);
        }
    },
    createTplHtml: function(pageName) {
        if(!isFileExist("views/tpl/" + pageName)) {
            execCmd("mkdir " + "views/tpl/" + pageName);
            writeTemplFileContentToApp("<div></div>", "views/tpl/" + pageName + "/init.html");
            console.log("子模板页面创建成功!".green);
        } else {
            console.log("子模板页面文件已存在".yellow);
        }
    },
    createPageLang: function(pageName) {
        if(!isFileExist("public/lang/" + pageName)) {
            execCmd("mkdir " + "public/lang/" + pageName);
            for(var index = 0; index < lang.length; index++) {
                writeTemplFileContentToApp("{}", "public/lang/" + pageName + "/" + lang[index]);
            }
            console.log("语言包文件创建成功!".green);
        } else {
            console.log("语言包文件已存在".yellow);
        }
    },
    createApi: function(pageName) {
        if(!isFileExist("public/api/" + pageName + ".js")) {
            writeTemplFileContentToApp("{}", "public/api/" + pageName + ".js");
            console.log("接口文件创建成功!".green);
        } else {
            console.log("接口文件已存在".yellow);
        }
    },
    createPageCss: function(pageName) {
        if(!isFileExist("public/stylesheets/" + pageName)) {
            execCmd("mkdir " + "public/stylesheets/" + pageName);
            writeTemplFileContentToApp("", "public/stylesheets/" + pageName + "/" + pageName + ".css");
            console.log("样式文件创建成功!".green);
        } else {
            console.log("样式文件已存在".yellow);
        }
    },
    createJs: function(pageName) {
        if(!isFileExist("public/javascripts/" + pageName)) {
            execCmd("mkdir " + "public/javascripts/" + pageName);
            var jsContent = readTemplFileContent(templBaseUrl + "init.js", true, {"{$p}":pageName});
            writeTemplFileContentToApp(jsContent, "public/javascripts/" + pageName + "/init.js");
            console.log("脚本文件创建成功!".green);
        } else {
            console.log("脚本文件已存在".yellow);
        }
    },
    createService: function(pageName) {
        if(!isFileExist("public/javascripts/service/" + pageName + "Service.js")) {
            var serviceContent = readTemplFileContent(templBaseUrl + "service.js", true, {"{$p}":pageName});
            writeTemplFileContentToApp(serviceContent, "public/javascripts/service/" + pageName + "Service.js");
            console.log("服务文件创建成功!".green);
        } else {
            console.log("服务文件已存在".yellow);
        }
    },
    createRoute: function(pageName) {
        if(!isFileExist("routes/" + pageName)) {
            execCmd("mkdir " + "routes/" + pageName);
            var routeContent = readTemplFileContent(templBaseUrl + "route.js", true, {"{$p}":pageName});
            writeTemplFileContentToApp(routeContent, "routes/" + pageName + "/" + pageName + ".js");
            console.log("路由文件创建成功!".green);
        } else {
            console.log("路由文件已存在".yellow);
        }
    },
    addRoute: function(pageName) {
        var routeContent = readTemplFileContent(templBaseUrl + "route.json", true, {"{$p}":pageName});
        var routeContentJson = JSON.parse(routeContent);
        var watchContent = fs.readFileSync("routes/watch.json");
        var watchContentJson = JSON.parse(watchContent);
        for(var index = 0; index < watchContentJson["request"].length; index++) {
            if(watchContentJson["request"][index]["route"] == routeContentJson["route"]) {
                console.log("路由项已存在!".green);
                return;
            }
        }
        watchContentJson["request"].push(routeContentJson);
        writeTemplFileContentToApp(JSON.stringify(watchContentJson, false, 4), "routes/watch.json");
        console.log("路由项添加成功!".green);
    },
    removePageHtml: function(pageName) {
        if(isFileExist("views/" + pageName + ".html")) {
            execCmd("rm -rf " + "views/" + pageName + ".html");
            console.log("删除".green + pageName.green + "主页面模板成功".green);
        } else {
            console.log("主页面文件不存在".yellow);
        }
    },
    removeTplHtml: function(pageName) {
        if(isFileExist("views/tpl/" + pageName)) {
            execCmd("rm -rf " + "views/tpl/" + pageName);
            console.log("删除".green + pageName.green + "子页面模板成功".green);
        } else {
            console.log("子页面模板文件不存在".yellow);
        }
    },
    removePageLang: function(pageName) {
        if(isFileExist("public/lang/" + pageName)) {
            execCmd("rm -rf " + "public/lang/" + pageName);
            console.log("删除".green + pageName.green + "语言文件成功".green);
        } else {
            console.log("语言文件不存在".yellow);
        }
    },
    removeApi: function(pageName) {
        if(isFileExist("public/api/" + pageName + ".js")) {
            execCmd("rm -rf " + "public/api/" + pageName + ".js");
            console.log("删除".green + pageName.green + "api文件成功".green);
        } else {
            console.log("api文件不存在".yellow);
        }
    },
    removePageCss: function(pageName) {
        if(isFileExist("public/stylesheets/" + pageName)) {
            execCmd("rm -rf " + "public/stylesheets/" + pageName);
            console.log("删除".green + pageName.green + "样式文件成功".green);
        } else {
            console.log("样式文件不存在".yellow);
        }
    },
    removeJs: function(pageName) {
        if(isFileExist("public/javascripts/" + pageName)) {
            execCmd("rm -rf " + "public/javascripts/" + pageName);
            console.log("删除".green + pageName.green + "脚本文件成功".green);
        } else {
            console.log("脚本文件不存在".yellow);
        }
    },
    removeService: function(pageName) {
        if(isFileExist("public/javascripts/service/" + pageName + "Service.js")) {
            execCmd("rm -rf " + "public/javascripts/service/" + pageName + "Service.js");
            console.log("删除".green + pageName.green + "服务文件成功".green);
        } else {
            console.log("服务文件不存在".yellow);
        }
    },
    removeRoute: function(pageName) {
        if(isFileExist("routes/" + pageName)) {
            execCmd("rm -rf " + "routes/" + pageName);
            console.log("删除".green + pageName.green + "路由文件成功".green);
        } else {
            console.log("路由文件不存在".yellow);
        }
    },
    updateRoute: function(pageName) {
        if(pageName == "index") {
            pageName = "";
        }
        var routeName = "/" + pageName;
        var watchContent = fs.readFileSync("routes/watch.json");
        var watchContentJson = JSON.parse(watchContent);
        for(var index = 0; index < watchContentJson["request"].length; index++) {
           if(watchContentJson["request"][index]["route"] == "/index" || watchContentJson["request"][index]["route"] == routeName) {
               watchContentJson["request"].splice(index, 1);
               writeTemplFileContentToApp(JSON.stringify(watchContentJson, false, 4), "routes/watch.json");
               break;
           }
        }
        console.log("更新路由成功".green);
    },
    trace: function() {
        forever = spawn('node', ["debug", "app.js"]);
        // 捕获标准输出并将其打印到控制台
        forever.stdout.on('data', function (data) {
            console.log(data.toString().blue);
        });
        // 捕获标准错误输出并将其打印到控制台
        forever.stderr.on('data', function (data) {
            console.log('standard error output:\n'.red + data);
        });
        process.stdin.on('readable', function() {
            var chunk = process.stdin.read();
            if (chunk !== null) {
                forever.stdin.write(chunk);
            }
        });
    },
    watch: function() {
        var watcher = chokidar.watch(["views", "routes", "public"], {
            persistent: true,
            ignored: "/(^|[\/\\])\../",
            ignoreInitial: false,
            followSymlinks: true,
            cwd: '.',
            disableGlobbing: false,
            usePolling: false,
            interval: 10,
            alwaysStat: true,
            binaryInterval: 10,
            alwaysStat: false,
            depth: 99,
            useFsEvents: true,
            awaitWriteFinish: {
                stabilityThreshold: 2000,
                pollInterval: 50
            },
            ignorePermissionErrors: false,
            atomic: true // or a custom 'atomicity delay', in milliseconds (default 100)

        });
        function execShell(callback, isFirstStart) {
            if(forever) {
                forever.kill("SIGTERM");
            }
            forever = spawn('node', ["app.js"]);
            // 捕获标准输出并将其打印到控制台
            forever.stdout.on('data', function (data) {
                console.log('standard output:\n'.green + data);
                callback();
            });
            // 捕获标准错误输出并将其打印到控制台
            forever.stderr.on('data', function (data) {
                console.log('standard error output:\n'.red + data);
                callback("error");
            });
        }
        execShell(function() {}, true);
        function ifwatchKeyExist(path, debugJson) {
            for(var key in debugJson) {
                if(debugJson[key]) {
                    return {
                        md5: debugJson[key]
                    };
                }
            }
            return false;
        }
        watcher.on('change', function(path, stats) {
            if(path.indexOf("cache") > -1 || path.indexOf("Cache") > -1) {
                return;
            }
            execShell(function(msg) {
                if(msg == "error") {
                    console.log("服务器代码错误!".red);
                } else {
                    console.log(path.green + " has be changed, the server is restarted....!".green);
                }
            }, false);
        }).on('error', function(error) {
            execShell(function() {
                console.log('Error happened'.red, error);
            }, false);
        }).on('ready', function() {
            console.log('The app is watched under your changed! good luck for your working!'.green);
        });
        process.on('SIGINT', function() {
            console.log("bey bey ....".yellow);
            forever.kill("SIGTERM");
            process.exit();//退出当前进程
        });
        process.on("exit", function() {
            forever.kill("SIGTERM");
        });
    },
    buildTester: function() {
        var rootDir = "views/tpl";

        function buildTestFile(path) {
            var html = fs.readFileSync(path).toString();
            $ = cheerio.load(html, {decodeEntities: false, xmlMode: true, recognizeSelfClosing: true});
            var allEles = $("*");
            var tagList = {};
            var middleHtml = "";
            for (var index = 0; index < allEles.length; index++) {
                tagList[$(allEles[index]).get(0).tagName] = "";
            }
            function inferClose(middleHtml) {
                var leftMarkCount = 0;
                var rightMarkCount = 0;
                for (var c = 0; c < middleHtml.length; c++) {
                    if (middleHtml[c] == "{") {
                        leftMarkCount++;
                    } else if (middleHtml[c] == "}") {
                        rightMarkCount++;
                    }
                }
                if (leftMarkCount != rightMarkCount) {
                    return false;
                } else {
                    return true;
                }
            }

            function inferNameExsist(middleHtml) {
                var nodeEle = $("<template " + middleHtml + " />");
                var nameAttr = nodeEle.attr("name");
                if (typeof nameAttr == "undefined") {
                    return true;
                }
                return false;
            }

            function parseTag(startTag, start, end) {
                end = html.indexOf(">", end + 1);
                middleHtml = html.substring(start, end);
                var isClose = inferClose(middleHtml);
                if (!isClose) {
                    parseTag(startTag, start, end);
                } else {//为html节点添加name属性
                    var nameAttr = "";
                    if (inferNameExsist(middleHtml)) {//如果没有name属性,添加name属性
                        var headHtml = html.substring(0, start);
                        var footHtml = html.substring(start, html.length);
                        nameAttr = " name=" + "'T_" + guid().split("-")[0].substring(0, 4) + "'" + " ";
                        html = headHtml + nameAttr + footHtml;
                    }
                    if (html.indexOf(startTag, end + nameAttr.length) > -1) {
                        parseTag(startTag, html.indexOf(startTag, end + nameAttr.length) + startTag.length, html.indexOf(startTag, end + nameAttr.length));
                    }
                }
            }

            for (var tag in tagList) {
                var startTag = "<" + tag;
                parseTag(startTag, html.indexOf(startTag) + startTag.length, html.indexOf(startTag));//从零开始寻找
            }
            fs.writeFileSync(path, html);
            console.log(path.green + "-------ok".green);
        }

        var pa = fs.readdirSync(rootDir);
        pa.forEach(function (ele, index) {
            var info = fs.statSync(rootDir + "/" + ele);
            if (info.isDirectory()) {
                var dirPath = rootDir + "/" + ele;
                fs.readdir(dirPath, function (err, files) {
                    files.forEach(function (filename) {
                        if (filename.indexOf(".html") > -1) {
                            buildTestFile(dirPath + "/" + filename);
                        }
                    });
                });
            }
        });
    }
}

index文件

var easyMe = require("./easyme").easyMe;
var program = require("commander");
var fs = require("fs");
program
    .version("0.0.1")
    .option("-i,--init", "init app")
    .option("-c,--create <string>", "create a single page")
    .option("-r,--remove <string>", "remove a sigle page")
    .option("-a,--addWidget <string>", "add a sigle widget")
    .option("-d,--deleteWidget <string>", "delete a sigle widget")
    .option("-w,--watch", "watch the app change, restart the server back")
    .option("-t,--trace", "trace the code execution environment")
    .option("-b,--build", "add test mark on every tag into tester write auto test script easyly")
    .parse(process.argv);
if(program.init) {
    if(program.init.toString() == "") {
        console.log("param is error".red);
        return;
    }
    easyMe.initApp();
}
if(program.create) {//创建单页面
    var pageName = program.create.toString();
    easyMe.createPageHtml(pageName);//创建html模板
    easyMe.createTplHtml(pageName);
    easyMe.createPageLang(pageName);//创建语言模板
    easyMe.createApi(pageName);//创建api模板
    easyMe.createPageCss(pageName);//创建css模板
    easyMe.createJs(pageName);//创建javascript文件模板
    easyMe.createService(pageName);//创建service文件模板
    easyMe.createRoute(pageName);//创建路由文件模板
    easyMe.addRoute(pageName);//增加路由表
}
if(program.remove) {//删除单页面
    var pageName = program.remove.toString();
    easyMe.removePageHtml(pageName);
    easyMe.removeTplHtml(pageName);
    easyMe.removePageLang(pageName);
    easyMe.removeApi(pageName);
    easyMe.removePageCss(pageName);
    easyMe.removeJs(pageName);
    easyMe.removeService(pageName);
    easyMe.removeRoute(pageName);
    easyMe.updateRoute(pageName);
}
if(program.addWidget) {//创建单组件
    var widgetName = program.addWidget.toString();
    easyMe.addWidget(widgetName);
}
if(program.deleteWidget) {//删除单组件
    var widgetName = program.deleteWidget.toString();
    easyMe.deleteWidget(widgetName);
}
if(program.watch) {
    easyMe.watch();
}
if(program.trace) {
    easyMe.trace();
}
if(program.build) {
    easyMe.buildTester();
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值