Node.js动态读取模块

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

以下是截取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动态读取模块)