基于路由dynamic加载Node.js模块

我正在使用快递在Node.js中做一个项目。 这是我的目录结构:

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

lib/api/目录有一些与API相关的JS文件。 我需要做的是制作一种钩子系统,只要有一个API函数被快速HTTP服务器请求,它就会执行相应API处理程序中指定的任何操作。 这可能是令人困惑的,但希望你明白了。

  1. Larry通过POST发送请求以获取用户详细信息。
  2. 服务器在lib/api中查找以查找与该请求关联的函数。
  3. 服务器执行操作并将数据发送回Larry。

希望你能帮助我。 我想这可以使用原型,不知道。

谢谢!

如果您知道脚本的位置,即您有一个初始目录,例如DIR ,那么您可以使用fs ,例如:

server.js

 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 

现在您的脚本需要遵循以下结构(因为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_holdervariables。 我没有testing它,但它应该工作( 除了error handling!!! )。 你可能想要改变这个function(例如,使module_holder是一棵树,而不是一个级别的字典),但我想你会理解这个想法。

这个函数应该在每个服务器启动时加载一次(如果你需要更频繁地启动它,那么你可能正在处理dynamic的服务器端脚本,这是一个baaaaaad的想法,恕我直言)。 现在唯一需要的是导出module_holder对象,以便每个视图处理程序都可以使用它。

app.js

 var c_file = 'html.js'; var controller = require(c_file); var method = 'index'; if(typeof(controller[method])==='function') controller[method](); 

html.js

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

dynamic化这个代码,你可以做一些神奇的事情:D

下面是一个REST API Web服务的例子,该服务根据发送给服务器的URLdynamic加载处理程序js文件:

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,所以映射的工作是这样的:

localhost:8080 / TrainerCentral / Recipe将映射到js文件/TrainerCentral/Recipe.js localhost:8080 / TrainerCentral / Workout将映射到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"); } }; 

使用“node index.js”从命令行启动服务器

玩的开心!