Authored by weiqingting

yo 基本框架

*.iml
.idea/
.ipr
.iws
*~
~*
*.diff
*.patch
*.bak
.DS_Store
Thumbs.db
.project
.*proj
.svn/
*.swp
*.swo
*.pyc
*.pyo
.build
node_modules
_site
sea-modules
spm_modules
.cache
dist
coverage
.sass-cache
*.config
*.njsproj
bin
obj
*.log
... ...
/*下载最新node v5.10.1*/
var path = require('path');
var express = require('express');
var app = express();
var App = express();
var Router = express.Router();
var Scan=require("./libs/Scan");
// 记录下当前文档的路径
global.root=__dirname;
/*获取配置接口信息*/
var apiCofig={
host:"xxxx"
root:__dirname,
apps:path.join(__dirname,"apps"),
domain:"http://192.168.102.202:8088/platform",
port:3000,
log:{
consoles:["log"]
},
mock:true
}
// 记录下当前文档的路径
global.apps=apiCofig.apps;
/*日志配置和Console*/
var Console=require("./libs/Console");
Console(apiCofig.log);
console.log("YOHO!");
/*接口层*/
var Interfacer=require("./libs/Interfacer");
var InterRegisters= new Interfacer(apiCofig);
InterRegisters.register(require("./apps/module/Interfaces/index.js"));
Scan("./apps/{.*}/interfaces/{.*}.js").forEach(function(src){
InterRegisters.register(require(".\/"+src));
});
/*View层*/
// var Interfaces=new Emitter();
// require("./apps/module/Interfaces/index.js")(Interfaces);
/*过滤器*/
var Filter=require("./libs/Filter");
var FilterRegisters= new Filter(InterRegisters);
Scan("./filters.js").forEach(function(src){
require(".\/"+src)(FilterRegisters);
});
/*控制器层*/
var Controller=require("./libs/Controller");
var ContRegisters=new Controller(InterRegisters);
require("./apps/module/controllers/index.js")(ContRegisters);
Scan("./apps/{.*}/controllers/{.*}.js").forEach(function(src){
require(".\/"+src)(ContRegisters);
});
app.get('/', function(req,res){
ContRegisters.emit("/",req,res);
/*路由控制*/
var KLH=function(obj,method,guid){
return function(req,res){
obj[method].call(obj,guid,req,res);
}
}
ContRegisters.routers.forEach(function(router){
var ROU=Router.route([router.url]);
var args=FilterRegisters.use(router.url,router.method).
concat(KLH(ContRegisters,"emit",router.guid));
ROU[router.method].apply(ROU,args);
});
App.use('/', Router);
/*View 设置*/
var Viewer=require("./libs/Viewer");
var Viewer=new Viewer(app,require("handlebars"));
app.set('view engine', 'html');
app.engine('html', Viewer.engine);
var Viewer=new Viewer(App,require("handlebars"));
App.set('view engine', 'html');
App.engine('html', Viewer.engine);
var server = app.listen(3000, function () {
var server = App.listen(apiCofig.port, function () {
var host = server.address().address;
var port = server.address().port;
});
\ No newline at end of file
... ...
function ContModel(app){
app.define("/",["key","key2"],function(key,key2){
return {
key:key,
key2:key2
};
});
}
module.exports=ContModel;
\ No newline at end of file
function ContModel(app){
/*
get 方法总结
参数 router,views,apis,callback
规则 router+(views|apis|callback)
*/
/*打开一个页面*/
app.get("/1","module.index");
/*根据数据接口 渲染一个页面*/
app.get("/2","moduleA.index",["UserA-login"]);
/*适配器*/
app.get("/3","moduleA.index",["UserA-login"],function(key1){
key1.userName="我修改了适配器";
return key1;
});
/*express 基本功能*/
app.get("/4",function(req,res){
/*注意 render 的View*/
res.render("moduleA.index",{});
});
/**/
app.get("/5",["UserA-login"],function(key1,req,res){
/*注意 render 的View*/
res.json(key1);
});
/*
POST 方法总结
参数 router,apis,callback
规则 router+(apis|callback)
*/
/*过滤器*/
// app.filters("/*","*",["UserA-login"],function(key1,req,res,next){
// });
}
module.exports=ContModel;
\ No newline at end of file
... ...
module.exports={
namespace:"userLogin",
apis:{
"user.login":{
url:"/Login",
methort:"POST",
input:[
{name:"username",type:"String"},
{name:"password",type:"String"}
]
}
}
}
\ No newline at end of file
module.exports={
namespace:"Role",
apis:{
"getrole":{
url:"/supplier/supplier/getSupplier",
method:"POST",
params:[
{name:"id",type:"Number"}
]
}
}
}
\ No newline at end of file
... ...
module.exports={
namespace:"User",
apis:{
"login":{
url:"/supplier/supplier/getSupplier",
method:"POST",
params:[
{name:"id",type:"Number"}
]
}
}
}
\ No newline at end of file
... ...
... ... @@ -4,8 +4,9 @@
<title></title>
</head>
<body>
<h1>index {{key}}</h1>
<h1>index {{key2}}</h1>
<h1>layout {{>layout}}</h1>
<h1>Views Index 文件 {{UserA-login.code}}</h1>
<div>Views Index 文件 <strong>part</strong> {{>part}}</div>
<div>Views Index 文件 <strong>layout/A</strong> {{>layout/A}}</div>
<div>Views Index 文件 <strong>part</strong> {{>../../moduleA/views/index}}</div>
</body>
</html>
... ...
Layout {{key1}}
<h4>Layout 引用 {{> layout2 }}</h4>
\ No newline at end of file
View Layout A {{key1}}
{{>../../../moduleA/views/index}}
... ...
Layout2 {{key2}}
\ No newline at end of file
part {{key2}}
\ No newline at end of file
... ...
module.exports={
namespace:"RoleA",
apis:{
"getrole":{
url:"/supplier/supplier/getSupplier",
method:"POST",
params:[
{name:"id",type:"Number"}
]
}
}
}
\ No newline at end of file
... ...
module.exports={
namespace:"UserA",
apis:{
"login":{
url:"/supplier/supplier/getSupplier",
method:"POST",
params:[
{name:"id",type:"Number"}
]
}
}
}
\ No newline at end of file
... ...
我是 moduleA views index 文件
../../module/view/part {{> ../../module/views/part}}
... ...
module.exports=function(Filter){
Filter.define("\/2","get",function(req,res,next){
res.end("please login...");
// next();
});
};
\ No newline at end of file
... ...
/*
*重写Console 包含日志
*logsConfig 包含之日相关设置
logsConfig:{
consoles:["log"]//选择启动console的选择方法,
src:"日志输出"
}
*/
module.exports=function(logsConfig){
var Consoles=['log', 'info', 'warn', 'error', 'dir', 'assert'];
var log=console.log;
console.log = function(){
var args=[].slice.call(arguments, 0);
args[0]="log:"+args[0];
log.apply(console, args);
};
console.error = function(){
var args=[].slice.call(arguments, 0);
args[0]="error:"+args[0];
log.apply(console, args);
};
function difference(array1,array2){
return array1.filter(function(item,value){
return !(array2.indexOf(item)>-1);
});
}
if(logsConfig.consoles){
var invalidCons=difference(Consoles,logsConfig.consoles);
console.log(invalidCons);
invalidCons.forEach(function (f) {
console[f] = function () {
};
return false;
});
return false;
}
}
\ No newline at end of file
... ...
var path=require('path');
var util = require('util');
var md5 = require('md5');
var Emitter=require('events');
/*重写控制器*/
var Emitter=require("./__Emitter");
var toString= Object.prototype.toString;
var Controller=function(interfaces){
this.interfaces=interfaces;
this.routers=[];
Emitter.call(this);
};
util.inherits(Controller,Emitter);
Controller.prototype.define=function(router,interfaces,callback){
/*解析 req 规则*/
Controller.prototype.__parseReq=function(req){
return{
defRes:req.xhr?"json":"render"
}
}
Controller.prototype.__define=function(method,router,view,apis,callback){
var me=this;
me.on(router,function(){
/*参数验证*/
var guid=md5(router+":"+method)
me.on(guid,function(){
var args=[].slice.call(arguments, 0);
var req=args[0],res=args[1];
/*如果接口不存在 就实现express 原来的方法*/
if(!apis.length){
if(callback){
callback.apply({},args);
}else{
res.render(view);
}
return;
}
args.push(function(err,interfaces,names){
//callback
var model={};
if(typeof callback=="function"){
model=callback.apply({},interfaces.concat(args));
}else{
interfaces.forEach(function(item,index){
model[names[index]]=item;
});
}
if(model){
if(view&&method=="get"&&!req.xhr){
res.render(view,model);
}else{
res.json(model);
}
}
});
//调用接口获取数据
var interfaces=me.interfaces.require.apply(me.interfaces,[interfaces].concat(args));
me.interfaces.require.apply(me.interfaces,[apis].concat(args));
});
var model=callback.apply({},interfaces.concat(args));
// 重写View
// args[1].send(viewdata);
var filePath=path.resolve(global.root,"apps/module","views/index");
args[1].render(filePath,model);
me.routers.push({
guid:guid,
url:router,
method:method
});
};
}
Controller.prototype.get=function(router,views,apis,callback){
var me=this;
if(toString.call(views)=='[object Array]'){
callback=apis;
apis=views;
views=null;
}else if(typeof views =='function'){
callback=views;
apis=[];
views=null;
}
if(typeof apis=="function"){
callback=apis;
apis=[];
}
apis=apis||[];
me.__define("get",router,views,apis,callback);
}
Controller.prototype.post=function(router,apis,callback){
var me=this;
if(typeof apis=="function"){
callback=apis;
apis=[];
}
me.__define("post",router,null,apis,callback);
}
module.exports= Controller;
... ...
var path=require('path');
var util = require('util');
var md5 = require('md5');
var Emitter=require('events');
var Filter=function(interfaces){
this.rules=[];
this.interfaces=interfaces;
Emitter.call(this);
};
util.inherits(Filter,Emitter);
Filter.prototype.define = function(router,method,apis,callback) {
var me=this,guid=md5(router+":"+method);
if(typeof apis=="function"){
callback=apis;
apis=[];
}
me.rules.push({
guid:guid,
router:router,
method:method
});
me.on(guid,function(){
var args=[].slice.call(arguments, 0);
var req=args[0],res=args[1];
if(!apis.length){
callback.apply({},args);
return;
}
args.push(function(err,interfaces,names){
callback.apply({},interfaces.concat(args));
});
me.interfaces.require.apply(me.interfaces,[apis].concat(args));
});
};
Filter.prototype.use=function(router,method){
var me=this,rules=[],func=[];
rules=me.rules.filter(function(rule,index){
return new RegExp(rule.router,'g').test(router)
&&new RegExp(rule.method,'ig').test(method);
});
rules.forEach(function(rule){
func.push(function(req,res,next){
me.emit(rule.guid,req,res,next);
});
});
return func;
}
module.exports= Filter;
... ...
var util = require('util');
var Emitter=require('events');
var Request = require('request');
var async=require('async');
/*接口*/
var Emitter=require("./__Emitter");
var Interfacer=function(){
var Interfacer=function(config){
this.config=config;
this.apis={};
Emitter.call(this);
};
util.inherits(Interfacer,Emitter);
... ... @@ -13,22 +17,55 @@ Interfacer.prototype.register = function(mos) {
var me=this,name=mos.namespace;
for(var key in mos.apis){
/*需要进行验证判断*/
me.apis[name+"."+key]=mos.apis[key];
me.apis[name+"-"+key]=mos.apis[key];
}
};
function __requestApi(config,apiOpt,req,callback){
var data={};
apiOpt.params.forEach(function(param){
data[param.name]=req.param(param.name)||"1454";
});
var options={
url:config.domain+apiOpt.url,
method:apiOpt.method,
//数据组装
qs:apiOpt.method.toUpperCase()=="GET"?data:undefined,
// form:apiOpt.method.toUpperCase()=="GET"?undefined:data//,
body:apiOpt.method.toUpperCase()=="GET"?undefined:JSON.stringify(data),
headers: apiOpt.headers||{
'Content-Type' : 'application/json'
}
};
Request(options,function(error, response, body){
if(error){
return callback(error,null);
}
return callback(null,JSON.parse(body));
});
}
/*
* {mos} 接口key 数组 比如[key1,key2] 后面可能要兼容字符串 比如 传key1
*/
Interfacer.prototype.require=function(mos,req,res){
var me=this;
// console.log(me.apis);
//{
// "userLogin.user.login":{
// route:"xxxx"
// }
// }
return ["我来自接口数据key1","我来自接口数据key2"];
Interfacer.prototype.require=function(mos,req,res,cb){
var me=this,funcs=[],names=[];
mos.forEach(function(name){
if(me.apis.hasOwnProperty(name)){
funcs.push(function(callback){
__requestApi(me.config,me.apis[name],req,callback);
});
names.push(name);
}
});
if(funcs.length!=mos.length){
return {err:"某个key 可能不存在!"};
}
async.parallel(funcs, function(err, results){
if(err){
return cb(err,null,names);
}
cb(null,results,names);
});
};
... ...
/*桩数据规则*/
\ No newline at end of file
... ...
var fs = require('fs');
var path = require('path');
module.exports=function(url){
var tokens=[],files=[],dir="";
url.split(/\/\{|\}/).forEach(function(item,index) {
if(item){
tokens.push({
value:item,
expr:index%2?true:false
});
}
});
function scanFolder(src) {
var stats,fileList = [],
folderList = [],
walk = function (src, fileList, folderList) {
files = fs.readdirSync(src);
files.forEach(function (item) {
var tmpPath = path.join(src, item);
stats = fs.statSync(tmpPath);
if (stats.isDirectory()) {
walk(tmpPath, fileList, folderList);
folderList.push(tmpPath);
} else {
fileList.push(tmpPath);
}
});
};
walk(src, fileList, folderList);
return {
'files': fileList,
'folders': folderList
}
}
if(fs.statSync(tokens[0].value).isFile()){
return [path.normalize(tokens[0].value)];
}
url=url.replace(/^\W+/g,'').replace(/\//g,'\\\\').replace(/\{/g,'(').replace(/\}/g,'?)');
var regex = new RegExp("^"+url+"$");
var obj=scanFolder(tokens[0].value),result=[];
if(path.extname(url)){
result=obj.files.filter(function(item){
return regex.test(item);
});
}
return result;
}
... ...
/* 验证JS*/
一期定下规则
二期实现功能
\ No newline at end of file
... ...
... ... @@ -2,15 +2,16 @@ var fs = require('fs');
var path=require('path');
var util = require('util');
var md5 = require('md5');
var Emitter=require('events');
/*重写控制器*/
var Emitter=require("./__Emitter");
var Viewer=function(app,tempEngine){
this.tempEngine=tempEngine;
this.cache={};
this.overrideExp(app);
this.engine=this.overrideEngine.bind(this);
Emitter.call(this);
};
util.inherits(Viewer,Emitter);
... ... @@ -21,23 +22,15 @@ Viewer.prototype.overrideExp=function(app){
callback=options;
options={};
}
return render.call(this, view, options, callback);
var views=view.split('.');
var _module=views.shift();
var filePath=path.resolve(global.apps,_module,"views/"+views.join('/'));
return render.call(this, filePath, options, callback);
};
// return render.call(this, view, options, callback);
})(app.render);
}
/*app.engine('md', function(str, options, fn){
try {
var html = md(str);
html = html.replace(/\{([^}]+)\}/g, function(_, name){
return options[name] || '';
});
fn(null, html);
} catch(err) {
fn(err);
}
});*/
var __parsefile = function(fileKey,filePath,dataModel,callback){
var me=this,cache=this.cache;
... ... @@ -51,6 +44,7 @@ var __parsefile = function(fileKey,filePath,dataModel,callback){
if(err){
return callback(err);
}
/*需要排除<!--{{}}-->*/
if(/\{\{>[^}]*\}\}/g.test(str)){
str=__parseLayout(filePath,str);
}
... ... @@ -69,7 +63,6 @@ var __parsefile = function(fileKey,filePath,dataModel,callback){
}
var __parseLayout=function(form,str){
console.log(form+":"+str);
var layouts=str.match(/\{\{>[^}]*\}\}/g);
return str.replace(/\{\{>[^}]*\}\}/g,function($0){
var name=path.resolve(path.dirname(form),$0.match(/\{\{>\s*([^}]*)\s*\}\}/m)[1].replace(/\s/g,'')+".html");
... ...
var isArray=Array.isArray||function(obj){
return {}.toString().call(obj)=="[object Array]"
}
var isObject=function(obj){
return typeof obj=="function"||typeof obj=="object";
}
var indexOf=function(array,key){
if(!array.length)return -1;
for (var i = 0; i < array.length; i++) {
if (array[i] == key) return i;
}
return -1;
}
var forEach=function(obj,fn){
if(isArray(obj)){
for(var i=0;i<obj.length;i++){
fn.call(obj,i,obj[i]);
}
return;
}
if(isObject(obj)){
for(var i in obj){
fn.call(obj,i,obj[i]);
}
return;
}
}
function on(keys,listener){
var that=this;
var registerEvent =this.registerEvent=this.registerEvent||{},
names=keys.split(/\s/);
forEach(names,function(i,name){
registerEvent[name]=registerEvent[name]||[];
if(!~indexOf(registerEvent[name],listener))
{
registerEvent[name].push(listener);
}
})
return that;
}
function one(keys,listener){
var that=this;
var fn=function(){
listener.call(this,[].slice.call(arguments));
that.off(keys,fn);
}
fn.fn=listener;
that.on(keys,fn);
return that;
}
function off(keys,listener){
var that=this;
var registerEvent =this.registerEvent=this.registerEvent||{},
names=keys.split(/\s/);
forEach(names,function(i,name){
if(registerEvent[name]&&!listener){
delete registerEvent[name];
}
if(registerEvent[name]&&listener){
var index=indexOf(registerEvent[name],listener);
if(~index){
[].splice.call(registerEvent[name],index,1)
}
}
});
return that;
}
function emit(keys){
var that=this;
var registerEvent =this.registerEvent=this.registerEvent||{},
names=keys.split(/\s/);
var args=[].slice.call(arguments,1);
forEach(names,function(i,name){
var listeners=registerEvent[name];
for(var i in listeners){
listeners[i].apply(that,args);
}
});
return that;
}
function all(keys,complete){
// var that=this;
// var registerEvent =this.registerEvent=this.registerEvent||{},
// names=keys.split(/\s/),count=0;
// forEach(names,function(i,name){
// count+=registerEvent[name].length;
// });
// forEach(names,function(i,name){
// var listeners=registerEvent[name];
// for(var i in listeners){
// count--;
// listeners[i].apply(that,args);
// }
// });
// return that;
}
function Emitter(event) {
this.registerEvent=event||{};
}
Emitter.prototype={
on:on,
off:off,
emit:emit,
one:one
};
module.exports = Emitter;