nodejs的自定义全局模块

发布于 · 最后修改时间 · 标签: javascript cogitation

需求如下:
写了一个类:function A(){/*...*/},然后想给他暴露到全局中,作为一个可require的模块,无需再通过路径查找获取。
这里推荐三种方法:
1. 重写require函数,加一层请求拦截的包裹。
2. 根据process.mainModule.filename来获取对应的node_modules文件夹,在里面创建对应的临时文件来进行链接。
3. 将对象注册到底层模块列表中。
无论哪种方法,最重要的还是要避免跟系统模块名字冲突。其中第二种有点投机取巧,因为设计到文件的读写,进程意外中断导致文件残留等等不方便的因素导致我并不推荐。
而第一种和第三种都要涉及到一个对象:process.binding("natives");这里返回的将是原生模块的代码。
第三种无疑效率最高,实现方法如下:

var natives_modules = process.binding("natives");
function defineAs(module_name, obj){
    if (natives_modules.hasOwnProperty(module_name)) {
        throw Error("Module Name has be defined");
    }
    var __module_uuid = +new Date + Math.random().toString(32);
    global[__module_uuid] = obj;
    var scriptContent = 'module.exports = global["'+__module_uuid+'"]';
    natives_modules[module_name] = scriptContent;
};
//PS:如果你用iojs,__module_uuid可以换成Symbol对象会更好。

不过话说回来,不用require函数名,为这些模块的加载方法另外取名字无疑是最简单粗暴的选择,只是说,使用统一的API,即便是后来你把代码封装发布到npm上,也能使原本的代码好好工作,不是很好么。