深入理解Commonjs规范及Node模块实现-创新互联
前面的话
我们提供的服务有:成都网站建设、成都网站设计、微信公众号开发、网站优化、网站认证、中牟ssl等。为数千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的中牟网站制作公司Node在实现中并非完全按照CommonJS规范实现,而是对模块规范进行了一定的取舍,同时也增加了少许自身需要的特性。本文将详细介绍NodeJS的模块实现
引入
nodejs是区别于javascript的,在javascript中的顶层对象是window,而在node中的顶层对象是global
[注意]实际上,javascript也存在global对象,只是其并不对外访问,而使用window对象指向global对象而已
在javascript中,通过var a = 100;是可以通过window.a来得到100的
但在nodejs中,是不能通过global.a来访问,得到的是undefined
这是因为var a = 100;这个语句中的变量a,只是模块范围内的变量a,而不是global对象下的a
在nodejs中,一个文件就是一个模块,每个模块都有自己的作用域。使用var来声明的一个变量,它并不是全局的,而是属于当前模块下
如果要在全局作用域下声明变量,则如下所示
概述
Node中模块分为两类:一类是Node提供的模块,称为核心模块;另一类是用户编写的模块,称为文件模块
核心模块部分在Node源代码的编译过程中,编译进了二进制执行文件。在Node进程启动时,部分核心模块就被直接加载进内存中,所以这部分核心模块引入时,文件定位和编译执行这两个步骤可以省略掉,并且在路径分析中优先判断,所以它的加载速度是最快的
文件模块则是在运行时动态加载,需要完整的路径分析、文件定位、编译执行过程,速度比核心模块慢
接下来,我们展开详细的模块加载过程
模块加载
在javascript中,加载模块使用script标签即可,而在nodejs中,如何在一个模块中,加载另一个模块呢?
使用require()方法来引入
【缓存加载】
再展开介绍require()方法的标识符分析之前,需要知道,与前端浏览器会缓存静态脚本文件以提高性能一样,Node对引入过的模块都会进行缓存,以减少二次引入时的开销。不同的地方在于,浏览器仅仅缓存文件,而Node缓存的是编译和执行之后的对象
不论是核心模块还是文件模块,require()方法对相同模块的二次加载都一律采用缓存优先的方式,这是第一优先级的。不同之处在于核心模块的缓存检查先于文件模块的缓存检查
【标识符分析】
require()方法接受一个标识符作为参数。在Node实现中,正是基于这样一个标识符进行模块查找的。模块标识符在Node中主要分为以下几类:[1]核心模块,如http、fs、path等;[2].或..开始的相对路径文件模块;[3]以/开始的绝对路径文件模块;[4]非路径形式的文件模块,如自定义的connect模块
根据参数的不同格式,require命令去不同路径寻找模块文件
1、如果参数字符串以“/”开头,则表示加载的是一个位于绝对路径的模块文件。比如,require('/home/marco/foo.js')将加载/home/marco/foo.js
2、如果参数字符串以“./”开头,则表示加载的是一个位于相对路径(跟当前执行脚本的位置相比)的模块文件。比如,require('./circle')将加载当前脚本同一目录的circle.js
3、如果参数字符串不以“./“或”/“开头,则表示加载的是一个默认提供的核心模块(位于Node的系统安装目录中),或者一个位于各级node_modules目录的已安装模块(全局安装或局部安装)
[注意]如果是当前路径下的文件模块,一定要以./开头,否则nodejs会试图去加载核心模块,或node_modules内的模块
//a.js console.log('aaa'); //b.js require('./a');//'aaa' require('a');//报错
另外有需要云服务器可以了解下创新互联建站www.cdcxhl.com,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
文章名称:深入理解Commonjs规范及Node模块实现-创新互联
文章URL:http://scjbc.cn/article/dicgdh.html