• nodejs模块实现(二)


    一 Nodejs模块实现:Nodejs模块加载机制

    1 在Node中引入模块,需要经历如下三个步骤:

    • 路径分析
    • 文件定位
    • 编译执行

    2 在Node中,模块分为两类:

    第一类是Node自身提供的模块,称为核心模块:fs、http等,就像java中的jdk提供的核心类一样。

    第二类是用户编写的模块,称为文件模块。

    • 核心模块部分在Node源代码的编译过程中,编译进了二进制执行文件。在Node进程启动时,核心模块就被直接加载进内存,所以这部分的模块引入时,文件定位和编译执行这两个步骤可以省略掉,并且在路径分析中优先判断,所以它的加载速度是最快的。
    • 文件模块在运行时动态加载,需要完整的路径分析,文件定位,编译执行过程,加载速度比核心模块慢。

     3 模块加载的优先级是:缓存模块 > 核心模块 > 用户自定义模块。


    二nodejs模块加载内部理解: Commonjs规范及nodejs实现

    在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内的模块 

    【文件扩展名分析】

      require()在分析标识符的过程中,会出现标识符中不包含文件扩展名的情况。CommonJS模块规范也允许在标识符中不包含文件扩展名,这种情况下,Node会先查找是否存在没有后缀的该文件,如果没有,再按.js、.json、.node的次序补足扩展名,依次尝试

      在尝试的过程中,需要调用fs模块同步阻塞式地判断文件是否存在。因为Node是单线程的,所以这里是一个会引起性能问题的地方。小诀窍是:如果是.node和.json文件,在传递给require()的标识符中带上扩展名,会加快一点速度。另一个诀窍是:同步配合缓存,可以大幅度缓解Node单线程中阻塞式调用的缺陷

    【目录分析和包】

      在分析标识符的过程中,require()通过分析文件扩展名之后,可能没有查找到对应文件,但却得到一个目录,这在引入自定义模块和逐个模块路径进行查找时经常会出现,此时Node会将目录当做一个包来处理

      在这个过程中,Node对CommonJS包规范进行了一定程度的支持。首先,Node在当前目录下查找package.json(CommonJS包规范定义的包描述文件),通过JSON.parse()解析出包描述对象,从中取出main属性指定的文件名进行定位。如果文件名缺少扩展名,将会进入扩展名分析的步骤

      而如果main属性指定的文件名错误,或者压根没有package.json文件,Node会将index当做默认文件名,然后依次查找index.js、index.json、index.node

      如果在目录分析的过程中没有定位成功任何文件,则自定义模块进入下一个模块路径进行查找。如果模块路径数组都被遍历完毕,依然没有查找到目标文件,则会抛出查找失败的异常

  • 相关阅读:
    Android签名详解(debug和release)
    Java反射机制的学习
    Android应用开发中如何使用隐藏API(转)
    asp.net购物车,订单以及模拟支付宝支付(二)---订单表
    asp.net购物车,订单以及模拟支付宝支付(一)---购物车表及添加购物车流程
    asp.net权限控制的方式
    .Net使用程序发送邮件时的问题
    Word2016“此功能看似已中断 并需要修复”问题解决办法
    C#字符串来袭——因为爱,所以爱
    C#时间的味道——任时光匆匆我只在乎你
  • 原文地址:https://www.cnblogs.com/terrymin/p/15822732.html
Copyright © 2020-2023  润新知