这是我参与「第四届青训营 」笔记创作活动的第8天
Node引入模块
在Node中引入模块,需要经历路径定位、文件定位、编译执行三个步骤
路径分析
1.模块标识符分析
前面提到,require()的标识符作为参数,Node实现了CommonJS模块规范,正是基于标识符
模块标识符可以分为以下几类:
核心模块,如http、fs、path等。
。或。。开始的相对路径文件模块。
以/开始的绝对文件路径。
非路径的文件模块,如自定义的connect模块
核心模块:
核心模块的优先级仅次于缓存加载,它在Node的源代码编译过程中就已经编译成二进制代码,其加载过程最快。
如果试图加载一个与核心模块标识符相同的自定义模块,是不会成功的一个http用户模块,想要加载成功,必须选择一个不同的标识符或者换用路径的方式。
路径形式的文件模块: 以.、..或/开始的标识符.被当做文件模块理,在分析路径模块时require()方法会将路径转为真实路径,并以真实路径作为索引,将编译执行后的结果存放到缓存中,以使二次加载时更快。
由于文件模块给Node指明了确切的文件位置,所以在查找过程中可以节约大量时间,其加载速度慢于核心模块。
●文件扩展名分析require()在分析标识符的过程中,会出现标识符中不包含文件扩展名的情况。CommonJS模块规范也允许在标识符中不包含文件扩展名,这种情况下,Node会按js、json、.node的次序补足扩展名,依次尝试。在尝试的过程中,需要调用fs模块同步阻塞式地判断文件是否存在。因为Node是单线程的,所以这里是一个会引起性能问题的地方。小诀窍是:如果是.node和json文件,在传递给require()的标识符中带上扩展名,会加快一点速度。另一个诀窍是:同步配合缓存以大幅度缓解Node单线程中阻塞式调用的缺陷。