node模块详解

来源:互联网 发布:python程序设计答案 编辑:程序博客网 时间:2024/05/16 10:45

在上一篇文章里,我大概解释了node的代码组织方式,有三个关键词: module, exports, require,这里我根据朴灵的深入浅出nodejs详细解释一下这三个关键词。

在node引入模块并执行的过程中发生了什么事情的呢?

1. 路径分析

2. 文件定位

3. 编译执行

在node中,模块包括了两种,一种是核心模块,在node环境启动的时候,加载到内存中,大家都知道的,内存读取起来很快,另外一种是用户自己编辑的js文件模块,它是在执行的时候动态加载进去了,简单的说就是如果写了一个my_util.js模块,如果不通过require引入它,它就在那,不多不少,不会消失,也不能使用,require时,要进行路径分析,文件定位,编译执行后加载到内存里才能使用,也就是自己定义的文件,效率肯定没有核心模块效率高。

每个js文件在引入的时候都有个module对象,我们写两个文件:

util.js

function getSplitArray(originString, splitString){  return originString.split(splitString);}module.exports = {  getSplitArray: getSplitArray};console.log(module);

main.js

var util = require('./util.js');console.log(module);

一个exports一个方法,一个使用它,打印一下每个文件的module对象console.log(module),输出:

Module {  id: '/home/chenyafei/workspace/node/study/util.js',  exports: { getSplitArray: [Function: getSplitArray] },  parent:    Module {     id: '.',     exports: {},     parent: null,     filename: '/home/chenyafei/workspace/node/study/main.js',     loaded: false,     children: [ [Circular] ],     paths:       [ '/home/chenyafei/workspace/node/study/node_modules',        '/home/chenyafei/workspace/node/node_modules',        '/home/chenyafei/workspace/node_modules',        '/home/chenyafei/node_modules',        '/home/node_modules',        '/node_modules' ] },  filename: '/home/chenyafei/workspace/node/study/util.js',  loaded: false,  children: [],  paths:    [ '/home/chenyafei/workspace/node/study/node_modules',     '/home/chenyafei/workspace/node/node_modules',     '/home/chenyafei/workspace/node_modules',     '/home/chenyafei/node_modules',     '/home/node_modules',     '/node_modules' ] }
//////////////////////////////////////////////////////////////////////Module {  id: '.',  exports: {},  parent: null,  filename: '/home/chenyafei/workspace/node/study/main.js',  loaded: false,  children:    [ Module {       id: '/home/chenyafei/workspace/node/study/util.js',       exports: [Object],       parent: [Circular],       filename: '/home/chenyafei/workspace/node/study/util.js',       loaded: true,       children: [],       paths: [Object] } ],  paths:    [ '/home/chenyafei/workspace/node/study/node_modules',     '/home/chenyafei/workspace/node/node_modules',     '/home/chenyafei/workspace/node_modules',     '/home/chenyafei/node_modules',     '/home/node_modules',     '/node_modules' ] }

module有id, exports filename, loaded, children, paths属性,有经验的开发人员很快就明白了module执行的代码组织结构,id模块文件的唯一标示,实际上是文件的全路径,exports是对外开发的属性,filename是文件名,loaded没懂有什么用,children代表子模块,我的理解是可以通过children找到所需要的子模块,下面详细说下paths。

这个和require查找策略有关,比如我们的例子里require('./util.js'),如果我们改为require('util')会出现什么情况呢:

会查找到核心模块里的util模块,也就是说,require是先从核心模块查找,也就是从内存中找,如果查找到,就停止查找,查找不到从当前路径下找,顺序依次是:

<pre name="code" class="javascript">/home/chenyafei/workspace/node/study/node_modules',     '/home/chenyafei/workspace/node/node_modules',     '/home/chenyafei/workspace/node_modules',     '/home/chenyafei/node_modules',     '/home/node_modules',     '/node_modules'

所以说require是现从当前目录查找,然后从父目录,其次是父目录的父目录,直到查找到根目录中,可以看出来,文件层次越深,加载越慢,文件windows下的我没有尝试,有兴趣的可以试下。

那么路径查找到了,那文件扩展名定位呢?一般情况下,node会按照.js, .json, .node的次序依次查找,由于文件会调用同步阻塞式的判断文件是否存在,所以如果是json和node扩展名的文件,在require是将扩展名带上,这个可以更快的加载到文件。

那如果require('module_test')找到了一个module_test文件夹怎么办呢?node会在当前目录查找package.json通过parse这个文件,解析出要用的module,如果没有这个文件,就找index.js, index.json, index.node。

如果最后还没找到,那就会抛出个异常。

0 0
原创粉丝点击