node——模塊化

以前寫的新聞部分幾乎全部操做都寫在了一塊兒,此次開始進行模塊化。html

爲何要模塊化:

1.提升開發效率,全部操做在一個文件內,不方便團隊操做,模塊化可多人同時操做json

2.當程序出錯,能夠分模塊尋找錯誤數組

3.可使程序不一次性所有展現出來,保留一些操做不可見ide

模塊化步驟:

1.思考,該模塊中要封裝什麼代碼?模塊化

2.思考,這些代碼有用到什麼外部數據?若是用到了該如何傳遞
3.當前模塊對外須要暴露的東西(moudule.eports的值)
函數

 

原代碼:post

var http=require('http');
var fs=require('fs');
var path=require('path');
var mime=require('mime');
var url=require('url');
var querystring=require('querystring');
var _=require('underscore');

http.createServer(function(req,res){

res.render=function(filename,tqData){
    fs.readFile(filename,function(err,data){
        if(err)
        {
            res.writeHead(404,'Not Found',{'Content-Type':'text/html;charset=utf-8'});
            res.end('44,not found');
            return;
        }
        if(tqData){
            var fn=_.template(data.toString('utf8'));
            data=fn(tqData);

        }
        res.end(data);
    })

}



req.url=req.url.toLowerCase();
req.method=req.method.toLowerCase();

var urlObj=url.parse(req.url,true);

if(req.url==='/'||req.url==='/index'&&req.method==='get')
{
    readNewsData(function(list){
        res.render(path.join(__dirname,'views','home.html'),{list:list});
    })

}else if(req.url==='/submit'&&req.method==='get'){

    res.render(path.join(__dirname,'views','submit.html'));
        
}else if(urlObj.pathname==='/item'&&req.method==='get'){

readNewsData(function(list){

        for(var i=0;i<list.length;i++)
        {

            if(list[i].id.toString()===urlObj.query.id)
            {
                model=list[i];
                break;

            }
        }
        if(model)
        {
            res.render(path.join(__dirname,'views','details.html'),{item:model});
        }
        else
        {
            res.end('no found')
        }
    })

}else if(req.url.startsWith('/add')&&req.method==='get'){

    fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){
        if(err&&err.code!=='ENOENT'){
            throw err;
        }
        var list_news=JSON.parse(data||'[]');
        
    });

    
    
        
}else if(req.url.startsWith('/add')&&req.method==='post'){
        
        readNewsData(function(list_news){
            
            postBodyData(req,function(postBody){
            
            postBody.id=list_news.length;
            list_news.push(postBody);
            
            writeNewsData(JSON.stringify(list_news),function(){
            res.statusCode=302;
            res.statusMessage='Found';
            res.setHeader('Location','/');
            res.end('over');

                });
        });
    });

    
}else if(req.url.startsWith('/resource')&&req.method==='get'){


    res.render(path.join(__dirname,req.url));

}        
else{
    res.writeHead(404,'NOT FOUND',{
        'Content-Type':'text/plain;charset=utf-8'
    });
    res.end('404,page not found');
}
}).listen(9090,function(){
    console.log('http://localhost:9090');
})


function readNewsData(callback){
    fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){
        if(err&&err.code!=='ENOENT'){
            throw err;
        }

        var list_news=JSON.parse(data||'[]');
        //經過回調函數callback()將讀取到的數據list,傳遞出去
        callback(list_news);
    });
}


function writeNewsData(data,callback){
    fs.writeFile(path.join(__dirname,'data','data1.json'),data,function(err){
        if(err){
            throw err;
        }
        console.log('ok');
    });

        callback();
}


function postBodyData(req,callback){
    
            var array=[];
        req.on('data',function(chunk){
            array.push(chunk);
    
        });

        req.on('end',function(){
            var postBody=Buffer.concat(array);
            postBody=postBody.toString('utf8');
            
            postBody=querystring.parse(postBody);
        
        callback(postBody);
        });
}
View Code

模塊化部分:

模塊一(服務模塊):負責啓動服務
模塊二(擴展模塊):負責擴展req和res對象,爲res和res對象,爲req和res增長如下更方便更好用的API
模塊三(路由模塊):負責路由判斷
模塊四(業務模塊):負責處理具體路由的業務的代碼

ui

模塊一(index.js)

代碼:url

 1 var http=require('http');
 2 var context=require('./context.js');
 3 var router=require('./router.js');
 4 var handler=require('./handler.js');
 5 
 6 http.createServer(function(req,res){
 7     //調用context.js模塊的返回值(函數),並將req和res對象傳遞給context.js模塊
 8     context(req,res);
 9     //調用路由模塊返回值
10     router(req,res);
11 
12 
13 }).listen(9090,function(){
14     console.log('http://localhost:9090');
15 })
View Code

 

模塊二(context.js)

負責擴展req和res對象,爲res和res對象,爲req和res增長如下更方便更好用的API
但願在該模塊作:
1.爲req增長一個query熟悉,該屬性中保存的就是用戶get請求提交過來的數據
-req.query
2.爲req增長一個pathname屬性
-req.pathname
3.爲res增長一個render函數spa

代碼:

var http=require('http');
var fs=require('fs');
var path=require('path');
var mime=require('mime');
var url=require('url');
var querystring=require('querystring');
var _=require('underscore');

//讓當前模塊對外暴露一個函數,經過這個函數將res,req傳入模塊中
module.exports=function(req,res){

    //1.爲req增長query屬性
    var urlObj=url.parse(req.url.toLowerCase(),true);
    req.query=urlObj.query;
    //2.爲req增長pathname屬性
    req.pathname=urlObj.pathname;
    //3.爲req增長method屬性
    req.method=req.method.toLowerCase();

    //3.爲res增長函數
    res.render=function(filename,tqData){
        fs.readFile(filename,function(err,data){
            if(err)
            {
                res.writeHead(404,'Not Found',{'Content-Type':'text/html;charset=utf-8'});
                res.end('44,not found');
                return;
            }
            if(tqData){
                var fn=_.template(data.toString('utf8'));
                data=fn(tqData);

            }
            res.end(data);
        });
    };

};
View Code

模塊三(router.js)

該模塊負責封裝因此路由判斷代碼

代碼:

 1 //該模塊負責封裝因此路由判斷代碼
 2 
 3 var handler=require('./handler');
 4 
 5 
 6 module.exports = function(req,res){
 7     if(req.url==='/'||req.url==='/index'&&req.method==='get')
 8 {
 9     handler.index(req,res);
10 
11 }else if(req.pathname==='/submit'&&req.method==='get'){
12     handler.submit(req,res);
13         
14 }else if(req.pathname==='/item'&&req.method==='get'){
15     handler.item(req,res);
16 
17 }else if(req.url.startsWith('/add')&&req.method==='post'){
18     handler.add(req,res);
19     
20 }else if(req.url.startsWith('/resource')&&req.method==='get'){
21     handler.resource(req,res);
22 
23 }        
24 else{
25     handler.nofound(req,res);
26 }
27 }
View Code

模塊四(handler.js)

該模塊負責對具體的業務進行處理

代碼:

  1 //該模塊負責對具體的業務進行處理
  2 var path=require('path');
  3 var fs=require('fs'); 
  4 var querystring=require('querystring');
  5 
  6 module.exports.index=function(req,res){
  7     if(req.pathname==='/'||req.url==='/index'&&req.method==='get')
  8     {
  9     readNewsData(function(list){
 10         res.render(path.join(__dirname,'views','home.html'),{list:list});
 11     })
 12 }}
 13 
 14 module.exports.submit=function(req,res){
 15     res.render(path.join(__dirname,'views','submit.html'));
 16 }
 17 
 18 module.exports.item=function(req,res){
 19     readNewsData(function(list){
 20 
 21         for(var i=0;i<list.length;i++)
 22         {
 23 
 24             if(list[i].id.toString()===req.query.id)
 25             {
 26                 model=list[i];
 27                 break;
 28 
 29             }
 30         }
 31         if(model)
 32         {
 33             res.render(path.join(__dirname,'views','details.html'),{item:model});
 34         }
 35         else
 36         {
 37             res.end('no found')
 38         }
 39     })
 40 
 41 }
 42 
 43 
 44 module.exports.add=function(req,res){
 45     //1.讀取data1.json
 46         readNewsData(function(list_news){
 47             //2.讀取用戶post提交的數據
 48             postBodyData(req,function(postBody){
 49             //3.爲用戶提交的新聞增長一個id屬性,而且把新聞對象push到list中
 50             postBody.id=list_news.length;
 51             list_news.push(postBody);
 52             //將list數組寫入到data1.json中
 53             writeNewsData(JSON.stringify(list_news),function(){
 54             res.statusCode=302;
 55             res.statusMessage='Found';
 56             res.setHeader('Location','/');
 57             res.end('over');
 58 
 59                 });
 60         });
 61     });
 62 
 63 }
 64 
 65 
 66 module.exports.resource=function(req,res){
 67     res.render(path.join(__dirname,req.pathname));
 68 }
 69 
 70 
 71 module.exports.nofound=function(req,res){
 72     res.writeHead(404,'NOT FOUND',{
 73         'Content-Type':'text/plain;charset=utf-8'
 74     });
 75     res.end('404,page not found');
 76 }
 77 
 78 
 79 function readNewsData(callback){
 80     fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){
 81         if(err&&err.code!=='ENOENT'){
 82             throw err;
 83         }
 84 
 85         var list_news=JSON.parse(data||'[]');
 86         //經過回調函數callback()將讀取到的數據list,傳遞出去
 87         callback(list_news);
 88     });
 89 }
 90 
 91 function writeNewsData(data,callback){
 92     fs.writeFile(path.join(__dirname,'data','data1.json'),data,function(err){
 93         if(err){
 94             throw err;
 95         }
 96         console.log('ok');
 97     });
 98 
 99         //這裏寫當寫入數據完畢後的操做
100         callback();
101 }
102 
103 function postBodyData(req,callback){
104     
105         var array=[];
106         req.on('data',function(chunk){
107             array.push(chunk);
108             //
109         });
110 
111         req.on('end',function(){
112             var postBody=Buffer.concat(array);
113             postBody=postBody.toString('utf8');
114             
115             postBody=querystring.parse(postBody);
116         
117             callback(postBody);
118         });
119 }
View Code

 

執行順序

index.js文件從上往下執行,先加載context,在加載router,因爲router文件內要先加載handler,因此handler順序比router前面點,以後就開始監聽9090端口,當有了請求後就執行http內部的代碼了。

相關文章
相關標籤/搜索