2012-06-06 16 views
14

पर गतिशील रूप से आधारित नोड.जेएस मॉड्यूल लोड हो रहा है मैं एक्सप्रेस का उपयोग करके नोड.जेएस में एक प्रोजेक्ट कर रहा हूं। यहाँ मेरी निर्देशिका संरचना है:मार्ग

root 
|-start.js 
|-server.js 
|-lib/ 
| api/ 
|  user_getDetails.js 
|  user_register.js 

lib/api/ निर्देशिका एपीआई से संबंधित जे एस फ़ाइलों की एक संख्या है। मुझे ऐसा करने की ज़रूरत है कि एक तरह की हुकिंग सिस्टम बनाएं, कि जब भी एपीआई कार्यों में से एक को HTTP HTTP सर्वर से अनुरोध किया जाता है, तो यह एपीआई हैंडलर के अनुसार जो भी क्रिया निर्दिष्ट है, करता है। यह शायद भ्रमित है, लेकिन उम्मीद है कि आपको विचार मिल जाएगा।

  1. लैरी उपयोगकर्ता विवरण प्राप्त करने के लिए POST के माध्यम से अनुरोध भेजता है।
  2. सर्वर उस अनुरोध से जुड़े फ़ंक्शन को खोजने के लिए lib/api में दिखता है।
  3. सर्वर कार्रवाई करता है और लैरी को डेटा वापस भेजता है।

उम्मीद है कि आप मेरी मदद कर सकते हैं। मैं सोच रहा था कि यह प्रोटोटाइप का उपयोग करके किया जा सकता है, हालांकि यह सुनिश्चित नहीं है।

धन्यवाद!

+0

मुझे यकीन नहीं है कि मैं समझता हूं। आप बस 'var m = आवश्यकता (' ./ lib/api/user_getDetails.js ') करते हैं और उस प्रतिक्रिया का उपयोग अपनी प्रतिक्रिया में करते हैं। क्या मैं कुछ भूल रहा हूँ? – freakish

+0

मैं इसे गतिशील रूप से लोड करना चाहता हूं। यही है, अगर मैं एक नया एपीआई फ़ंक्शन जोड़ता हूं, तो मुझे मैन्युअल रूप से इसकी आवश्यकता नहीं होती है। लेकिन मुझे यकीन नहीं है कि इसे कैसे पूरा किया जाए। –

+0

तो, आप एक ऑटोलोडर चाहते हैं? –

उत्तर

23

यदि आप जानते हैं, जहां अपनी स्क्रिप्ट कर रहे हैं, यानी आप एक प्रारंभिक निर्देशिका है, उदाहरण के DIR के लिए है, तो आप fs साथ, काम कर सकते हैं, उदाहरण के लिए:

var fs = require('fs'); 
var path_module = require('path'); 
var module_holder = {}; 

function LoadModules(path) { 
    fs.lstat(path, function(err, stat) { 
     if (stat.isDirectory()) { 
      // we have a directory: do a tree walk 
      fs.readdir(path, function(err, files) { 
       var f, l = files.length; 
       for (var i = 0; i < l; i++) { 
        f = path_module.join(path, files[i]); 
        LoadModules(f); 
       } 
      }); 
     } else { 
      // we have a file: load it 
      require(path)(module_holder); 
     } 
    }); 
} 
var DIR = path_module.join(__dirname, 'lib', 'api'); 
LoadModules(DIR); 

exports.module_holder = module_holder; 
// the usual server stuff goes here 

अब

server.js आपकी स्क्रिप्ट को निम्नलिखित संरचना का पालन करने की आवश्यकता है (require(path)(module_holder) लाइन के कारण), उदाहरण के लिए:

user_getDetails.js

function handler(req, res) { 
    console.log('Entered my cool script!'); 
} 

module.exports = function(module_holder) { 
    // the key in this dictionary can be whatever you want 
    // just make sure it won't override other modules 
    module_holder['user_getDetails'] = handler; 
}; 

और अब, जब एक अनुरोध के प्रबंधन, है न:

// request is supposed to fire user_getDetails script 
module_holder['user_getDetails'](req, res); 

यह module_holder चर करने के लिए अपने सभी मॉड्यूल लोड करना चाहिए। मैंने इसका परीक्षण नहीं किया, लेकिन इसे काम करना चाहिए (त्रुटि प्रबंधन को छोड़कर !!!)। आप इस फ़ंक्शन को बदलना चाहते हैं (उदाहरण के लिए module_holder एक पेड़ बनाएं, एक स्तर का शब्दकोश नहीं) लेकिन मुझे लगता है कि आप इस विचार को समझ लेंगे।

यह फ़ंक्शन प्रति सर्वर शुरू होने के बाद लोड होना चाहिए (यदि आपको इसे अधिक बार आग लगाना है, तो आप शायद गतिशील सर्वर-साइड स्क्रिप्टिंग से निपट रहे हैं और यह एक बायाड विचार है, इमो)। अब आपको केवल एक चीज की आवश्यकता है module_holder ऑब्जेक्ट को निर्यात करना ताकि प्रत्येक व्यू हैंडलर इसका उपयोग कर सके।

+1

यदि आप स्टार्टअप पर फ़ंक्शन को एक बार कॉल कर रहे हैं, तो एसिंक संस्करणों का उपयोग करने का कोई कारण नहीं है; बस 'fs.lstatSync' और' fs.readdirSync' का उपयोग करें। यह आपको त्रुटियों को निगलने से भी रोकता है क्योंकि अपवादों को फेंक दिया जाएगा, कॉलबैक को पारित त्रुटियों के बजाय और फिर अनदेखा किया जाएगा। – Domenic

+0

@Domeic True। किसी भी तरह से मैं एसिंक प्रोग्रामिंग में उपयोग किया गया और अब सिंक्रनाइज़ नहीं सोचता, हे। :) वैसे, आपने अपना 'प्रयास {} पकड़ {} 'ब्लॉक हटा दिया। दरअसल, इसकी आवश्यकता नहीं है, क्योंकि स्क्रिप्ट जारी रहेगी, भले ही मॉड्यूल अपवाद फेंकता हो। लेकिन यह अब तुल्यकालिक संस्करणों के लिए सच नहीं है! – freakish

+0

ग्रेट उत्तर, लेकिन मैं अभी भी उलझन में हूं कि सर्वर मॉड्यूल का उपयोग कैसे करें ... किसी भी तरह का प्रोटोटाइप-आधारित सिस्टम का उपयोग करने के लिए एक आदर्श समाधान होगा (यदि यह समझ में आता है)। जो भी स्क्रिप्ट लोड में कुछ होना चाहिए 'Hook.add ("user_getDetails"); Hook.user_getDetails.action = function() {console.log ("user_get विवरण विधि लागू!")}; ऐसा कुछ, हालांकि मुझे नहीं पता कि यह कैसे काम करेगा: पी –

3

app.js

var c_file = 'html.js'; 

var controller = require(c_file); 
var method = 'index'; 

if(typeof(controller[method])==='function') 
    controller[method](); 

एचटीएमएल।डी

+1

मुझे लगता है कि यह होना चाहिए (टाइपफ (नियंत्रक [विधि]) == 'फ़ंक्शन') – zephyr

+0

आप सही हैं @zephyr – ZiTAL

1

यहाँ एक REST API वेब सेवा गतिशील सर्वर के लिए भेजा यूआरएल के आधार पर हैंडलर js फाइल लोड का एक उदाहरण है: js

module.exports = 
{ 
    index: function() 
    { 
     console.log('index method'); 
    }, 
    close: function() 
    { 
     console.log('close method');  
    } 
}; 

इस कोड को एक छोटा सा आप जादू कर सकते हैं dynamizing :

server.js

var http = require("http"); 
var url = require("url"); 

function start(port, route) { 
    function onRequest(request, response) { 
     var pathname = url.parse(request.url).pathname; 
     console.log("Server:OnRequest() Request for " + pathname + " received."); 
     route(pathname, request, response); 
    } 

    http.createServer(onRequest).listen(port); 
    console.log("Server:Start() Server has started."); 
} 

exports.start = start; 

router.js

function route(pathname, req, res) { 
    console.log("router:route() About to route a request for " + pathname); 

    try { 
     //dynamically load the js file base on the url path 
     var handler = require("." + pathname); 

     console.log("router:route() selected handler: " + handler); 

     //make sure we got a correct instantiation of the module 
     if (typeof handler["post"] === 'function') { 
      //route to the right method in the module based on the HTTP action 
      if(req.method.toLowerCase() == 'get') { 
       handler["get"](req, res); 
      } else if (req.method.toLowerCase() == 'post') { 
       handler["post"](req, res); 
      } else if (req.method.toLowerCase() == 'put') { 
       handler["put"](req, res); 
      } else if (req.method.toLowerCase() == 'delete') { 
       handler["delete"](req, res); 
      } 

      console.log("router:route() routed successfully"); 
      return; 
     } 
    } catch(err) { 
     console.log("router:route() exception instantiating handler: " + err); 
    } 

    console.log("router:route() No request handler found for " + pathname); 
    res.writeHead(404, {"Content-Type": "text/plain"}); 
    res.write("404 Not found"); 
    res.end(); 

} 

exports.route = route; 

index.js

var server = require("./server"); 
var router = require("./router"); 

server.start(8080, router.route); 

मेरे मामले में संचालकों एक सबफ़ोल्डर/TrainerCentral में हैं, इसलिए मानचित्रण इस तरह काम करता है:

स्थानीय होस्ट: 8080/TrainerCentral/पकाने की विधि js फ़ाइल को मैप होगा/TrainerCentral /Recipe.js स्थानीय होस्ट: 8080/TrainerCentral/कसरत js फ़ाइल /TrainerCentral/Workout.js करने के लिए नक्शे होगा

यहाँ एक उदाहरण हैंडलर कि, पुन: प्राप्त करने डालने, अद्यतन करने के लिए 4 मुख्य HTTP कार्यों में से प्रत्येक को संभाल सकता है, और डेटा हटाना

/TrainerCentral/Workout.js

function respond(res, code, text) { 
    res.writeHead(code, { "Content-Type": "text/plain" }); 
    res.write(text); 
    res.end(); 
} 

module.exports = { 
    get: function(req, res) { 
     console.log("Workout:get() starting"); 

     respond(res, 200, "{ 'id': '123945', 'name': 'Upright Rows', 'weight':'125lbs' }"); 
    }, 
    post: function(request, res) { 
     console.log("Workout:post() starting"); 

     respond(res, 200, "inserted ok"); 
    }, 
    put: function(request, res) { 
     console.log("Workout:put() starting"); 

     respond(res, 200, "updated ok"); 
    }, 
    delete: function(request, res) { 
     console.log("Workout:delete() starting"); 

     respond(res, 200, "deleted ok"); 
    } 
}; 
"नोड index.js"

मज़े के साथ कमांड लाइन से सर्वर प्रारंभ

!

संबंधित मुद्दे