美文网首页
Node.js动态读取模块

Node.js动态读取模块

作者: 忧郁的河蟹 | 来源:发表于2015-04-05 21:47 被阅读5495次

    动态读取模块解决了什么问题?

    以下是截取cnodejs社区源码的片段
    https://github.com/cnodejs/nodeclub/blob/master/web_router.js

    var sign = require('./controllers/sign');
    var site = require('./controllers/site');
    var user = require('./controllers/user');
    var message = require('./controllers/message');
    var topic = require('./controllers/topic');
    var reply = require('./controllers/reply');
    var rss = require('./controllers/rss');
    var staticController  = require('./controllers/static');
    var auth = require('./middlewares/auth');
    var limit = require('./middlewares/limit');
    var github = require('./controllers/github');
    var search = require('./controllers/search');
    

    topic,userreply 都是controller下的路由函数,当我们需要创建多一个路由函数的时候,开发者总是需要require多一个模块进来,当路由的规模越来越大的时候,文件里面,总会有十几行路由引用,在本人看来,这是非常糟糕的开发体验,那么有没有一种方法,可以按需加载,我们需要什么东西就引用什么,不用主动去require进来。好吧,不傲娇了,本文正是为了解决问题。

    先看看本文的最终解法

    load_dir.js

    var fs = require('fs');
    var path = require('path');
    
    var load = function(path, name) {
        if (name) {
            return require(path + name);
        }
        return require(path)
    };
    
    module.exports = function (dir) {
        patcher = {}
    
        fs.readdirSync(__dirname + '/' + dir).forEach(function (filename) {
            if (!/\.js$/.test(filename)) {
                return;
            }
            var name = path.basename(filename, '.js');
            var _load = load.bind(null, './' + dir + '/', name);
    
            patcher.__defineGetter__(name, _load);
        });
    
        return patcher;
    

    module/a.js

    module.exports = function () {
        console.log('module a');
    }
    

    module/b.js

    module.exports = function () {
        console.log('module a');
    }
    

    index.js

    module.exports = function () {
        console.log('module b');
    }
    
    var loadDir = require('./load_dir');
    
    var Module = loadDir('module');
    
    Module.a(); // print module a
    Module.b(); // print module b
    
    

    在上述代码当中,可以看到通过loadDir函数导出的Module,Module可以动态读取module文件夹下的js模块,只要通过Module.a() 或者 Module.b()就可以方便进行调用,因此loadDir函数是实现动态读取模块的关键。

    loadDir的实现细节

    读取指定目录下的js文件,并将js文件通过node.js的require方法进行导入,并存放在patcher变量下,利用__defineGetter__方法重新定义了了patcher的getter方法,当我们patcher.xx的时候,就会调用require的方法,动态读取对应目录下的模块。

    应用动态读取模块倒cnodejs社区源码

    var loadDir = require('./load_dir');
    var Router = loadDir('router');
    
    router.post('/signout', Router.sign.signout); 
    

    代码是不是已经变得 更加好维护了。

    最后,出了路由可以使用动态加载外,moogose的模型也可以,只要你想动态加载的模块,通通都可以这样处理,是不是觉得很方便,如果还是不是很了解的同学,可以参考我的示例项目。

    https://github.com/youyudehexie/nodejs-cookbook/tree/master/dynamic_module

    相关文章

      网友评论

          本文标题:Node.js动态读取模块

          本文链接:https://www.haomeiwen.com/subject/ylaaxttx.html