iT邦幫忙

DAY 9
6

node.js伺服器實戰系列 第 9

node.js伺服器實戰(9) - 模組化

從昨天的程式中發現,把程式hard code在一起會造成測試上的不便,所以還是把他做成模組。
模組化的需求

之前在撰寫程式時,把所有的程式碼都放在同一支程式裡面,在撰寫目錄預設index檔的功能時,就發現會有一些測試的困難度。例如設定多個預設index檔時,需要測試先後順序是否影響功能。但是這樣需要每次都改寫evolve.js才能進行測試,非常的不方便。把伺服器程式模組化,就可以解決這樣的問題。

之前已經做的準備

其實之前已經默默地做了一些準備,包括:

  1. 把evolve.js放在lib目錄
  2. http.server用一個constructor封裝

把程式碼封裝成一個物件,並用constructor初始化,這樣就可以透過module.exports輸出給其他程式使用。

模組化

至於實做,倒是很簡單,只要把evolve這個constructor指派給module.ports就可以了,像這樣:

 var http = require('http'),
     fs = require('fs'),
     url = require('url'),
     mime = require('../deps/mime'),
     path = require('path'),
     evolve = function(conf) {
         var server = http.createServer(function(request, response) {
             var urlObj = url.parse(request.url);
             var respath = path.join(conf.basedir, urlObj.pathname);
             console.log('request: ' + respath);
             fs.stat(respath, function(err, stats) {
                 if(err) {
                     console.log(respath + ' not exists.');
                     response.writeHead(404, '');
                     response.end();
                 } else {
                     if(stats.isDirectory()) {
                         var ic=0;
                         fs.readFile(path.join(respath, conf.dirindex[ic]), function dih(err, data) {
                             ic++;
                             if(err) {
                                 if(ic<conf.dirindex.length) {
                                     fs.readFile(path.join(respath, conf.dirindex[ic]), dih);
                                 } else {
                                     console.log(path.join(respath, conf.dirindex[ic-1]) + ' not exists.');
                                     response.writeHead(404, '');
                                     response.end();
                                 }
                             } else {
                                 console.log(path.join(respath, conf.dirindex[ic-1]) + ' exists.');
                                 response.writeHead(200, {
                                     "Content-Type": mime.lookup(path.join(respath, conf.dirindex[ic-1])),
                                     "Content-Length": data.length
                                 });
                                 response.end(data);
                             }
                         });
                     } else {
                         fs.readFile(respath, function(err, data) {
                             if(err) {
                                 console.log(respath + ' not exists.');
                                 response.writeHead(404, '');
                                 response.end();
                             } else {
                                 console.log(respath + ' exists.');
                                 response.writeHead(200, {
                                     "Content-Type": mime.lookup(respath), 
                                     "Content-Length": data.length
                                 });
                                 response.end(data);
                             }
                         });
                     }
                 }
             });
         });
         this.listen = function(port, addr) {
             server.listen(port, addr);
             return this;
         };
     };
 module.exports = evolve;

要使用伺服器時,就利用模組來呼叫他(tests/testserver001.js):

 var evolve = require('../lib/evolve'),
 instance = new evolve({
     basedir: path.join(__dirname, '/../www'),
     dirindex: ['index.htm','index.html','default.htm']
 });
 instance.listen(8443, '127.0.0.1');
 console.log('server started.');

跟之前的程式其實只差兩行,拆成兩個檔案。現在目錄結構變成:

evolve
|-- README
|-- deps
|   `-- mime
|       |-- LICENSE
|       |-- README.md
|       |-- index.js
|       |-- mime.js
|       |-- mime.types
|       |-- node.types
|       |-- package.json
|       `-- test.js
|-- index.js
|-- lib
|   `-- evolve.js
|-- tests
|   |-- testserver001.js
|   |-- testserver002.js
|   `-- testserver003.js
`-- www
    |-- bg.gif
    `-- default.htm

多個測試

透過模組化,把伺服器程式與實例分離,要做測試就容易了。例如想要測試目錄index檔,之前要改動伺服器程式的檔案,現在只要寫三個測試用不同的設定啟動伺服器就可以:

testserver002.js:

 var evolve = require('../lib/evolve'),
 instance = new evolve({
     basedir: path.join(__dirname, '/../www'),
     dirindex: ['index.htm','default.htm','index.html']
 });
 instance.listen(8443, '127.0.0.1');
 console.log('server started.');

testserver003.js:

 var evolve = require('../lib/evolve'),
 instance = new evolve({
     basedir: path.join(__dirname, '/../www'),
     dirindex: ['default.htm','index.htm','index.html']
 });
 instance.listen(8443, '127.0.0.1');
 console.log('server started.');

另外,在evolve根目錄加上index.js,內容很簡單:

module.exports = require('lib/evolve');

這樣只要把evolve放到NODE_PATH環境變數所指的目錄,或是node.js應用程式的node_modules子目錄中,之後就可以透過require('evolve')來使用這個模組。

相關文章


上一篇
node.js伺服器實戰(8) - 目錄的預設index檔
下一篇
node.js伺服器實戰(10) - 加入cache機制
系列文
node.js伺服器實戰33

尚未有邦友留言

立即登入留言