Module

module是node.js最常用的模块,是node.js的根基,主要作用是导入模块,组织模块。

简单原理

module里面核心的方法是require,以下我将会用简单的伪代码来描述require的过程


var cache = {}; //模块缓存
function require(path) {

    var filename = _resolveFilename(path); // 读取模块的文件名字
    if (cache[filename]) {  //判断该模块是否已经加载到内存,如果已经在内存,则直接读取
        return cache[filename];
    }

    if (Native.module[filename]) { //判断模块是否原生 native的模块,如果是native模块,读取模块内容
        return Native.module[filename];
    }


    var content = fs.readFileSync(filename); // 用同步阻塞的方法读取文件内容

    var extension = getFileextension(filename); //根据文件extension的类型,根据不同的类型对不同文件进行相应的处理。

    if (extension == '.json') {
        return JSON.parse(content);
    }

    if (extension == '.node') {
        return process.dlopen; 
    }

    if (extension == '.js') {

        if (Module._contextLoad) { //根据_contextLoad 这个全局参数来区分,模块是需要所有文件都加载统一的上下文里面,还是分开不同上下文加载,通过exports的方法来跟其他模块通讯。node.js默认使用后者来处理。
            var sandbox = {};
            for (var k in global) {
                sandbox[k] = global[k];
            }
            sandbox.require = require;
            sandbox.exports = self.exports;
            sandbox.__filename = filename;
            sandbox.__dirname = dirname;
            sandbox.module = self;
            sandbox.global = sandbox;
            sandbox.root = root;
            return runInNewContext(content, sandbox, { filename: filename });

        } else {
            global.require = require;
            global.exports = self.exports;
            global.__filename = filename;
            global.__dirname = dirname;
            global.module = self;
            return runInThisContext(content, { filename: filename });

        }
    }
}

后记

总的来说,module模块还是比较简单,不过在浏览器里面就不是那么好实现了,根源还是在加载文件的时候,是否异步方法相关,尝试想想如果我们在加载模块的时候,使用fs.readFile 而不是readFileSync ,而执行一个文件当中,我们需要判断模块是否已经加载完毕,复杂度就变得大很多。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容