位置: 编程技术 - 正文

node.js require() 源码解读

编辑:rootadmin

推荐整理分享node.js require() 源码解读,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

年,Node.js 项目诞生,所有模块一律为 CommonJS 格式。

时至今日,Node.js 的模块仓库 npmjs.com ,已经存放了万个模块,其中绝大部分都是 CommonJS 格式。

这种格式的核心就是 require 语句,模块通过它加载。学习 Node.js ,必学如何使用 require 语句。本文通过源码分析,详细介绍 require 语句的内部运行机制,帮你理解 Node.js 的模块机制。

一、require() 的基本用法

分析源码之前,先介绍 require 语句的内部逻辑。如果你只想了解 require 的用法,只看这一段就够了。

下面的内容翻译自《Node使用手册》。

请看一个例子。

当前脚本文件 /home/ry/projects/foo.js 执行了 require('bar') ,这属于上面的第三种情况。Node 内部运行过程如下。

首先,确定 x 的绝对路径可能是下面这些位置,依次搜索每一个目录。

搜索时,Node 先将 bar 当成文件名,依次尝试加载下面这些文件,只要有一个成功就返回。

如果都不成功,说明 bar 可能是目录名,于是依次尝试加载下面这些文件。

如果在所有目录中,都无法找到 bar 对应的文件或目录,就抛出一个错误。

二、Module 构造函数

了解内部逻辑以后,下面就来看源码。

require 的源码在 Node 的 lib/module.js 文件。为了便于理解,本文引用的源码是简化过的,并且删除了原作者的注释。

上面代码中,Node 定义了一个构造函数 Module,所有的模块都是 Module 的实例。可以看到,当前模块(module.js)也是 Module 的一个实例。

每个实例都有自己的属性。下面通过一个例子,看看这些属性的值是什么。新建一个脚本文件 a.js 。

运行这个脚本。

可以看到,如果没有父模块,直接调用当前模块,parent 属性就是 null,id 属性就是一个点。filename 属性是模块的绝对路径,path 属性是一个数组,包含了模块可能的位置。另外,输出这些内容时,模块还没有全部加载,所以 loaded 属性为 false 。

新建另一个脚本文件 b.js,让其调用 a.js 。

node.js require() 源码解读

运行 b.js 。

上面代码中,由于 a.js 被 b.js 调用,所以 parent 属性指向 b.js 模块,id 属性和 filename 属性一致,都是模块的绝对路径。

三、模块实例的 require 方法

每个模块实例都有一个 require 方法。

由此可知,require 并不是全局性命令,而是每个模块提供的一个内部方法,也就是说,只有在模块内部才能使用 require 命令(唯一的例外是 REPL 环境)。另外,require 其实内部调用 Module._load 方法。

下面来看 Module._load 的源码。

上面代码中,首先解析出模块的绝对路径(filename),以它作为模块的识别符。然后,如果模块已经在缓存中,就从缓存取出;如果不在缓存中,就加载模块。

因此,Module._load 的关键步骤是两个。

四、模块的绝对路径

下面是 Module._resolveFilename 方法的源码。

上面代码中,在 Module.resolveFilename 方法内部,又调用了两个方法 Module.resolveLookupPaths() 和 Module._findPath() ,前者用来列出可能的路径,后者用来确认哪一个路径为真。

为了简洁起见,这里只给出 Module._resolveLookupPaths() 的运行结果。

上面的数组,就是模块所有可能的路径。基本上是,从当前路径开始一级级向上寻找 node_modules 子目录。最后那三个路径,主要是为了历史原因保持兼容,实际上已经很少用了。

有了可能的路径以后,下面就是 Module._findPath() 的源码,用来确定到底哪一个是正确路径。

经过上面代码,就可以找到模块的绝对路径了。

有时在项目代码中,需要调用模块的绝对路径,那么除了 module.filename ,Node 还提供一个 require.resolve 方法,供外部调用,用于从模块名取到绝对路径。

五、加载模块

有了模块的绝对路径,就可以加载该模块了。下面是 module.load 方法的源码。

上面代码中,首先确定模块的后缀名,不同的后缀名对应不同的加载方法。下面是 .js 和 .json 后缀名对应的处理方法。

这里只讨论 js 文件的加载。首先,将模块文件读取成字符串,然后剥离 utf8 编码特有的BOM文件头,最后编译该模块。

module._compile 方法用于模块的编译。

上面的代码基本等同于下面的形式。

也就是说,模块的加载实质上就是,注入exports、require、module三个全局变量,然后执行模块的源码,然后将模块的 exports 变量的值输出。

(完)

深入浅析Node.js 事件循环 Node.js是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。(来源于Javascript是单线程又是异步的,但是这种语言有个共同的特点

深入浅析NodeJs并发异步的回调处理 这里说并发异步,并不准确,应该说连续异步。NodeJs单线程异步的特性,直接导致多个异步同时进行时,无法确定最后的执行结果来回调。举个简单的

node.js入门实例helloworld详解 本文实例讲述了node.js入门实例helloworld。分享给大家供大家参考,具体如下:将下面的代码保存为:server.js存到E盘下面的node目录中。varhttp=require('http');f

标签: node.js require() 源码解读

本文链接地址:https://www.jiuchutong.com/biancheng/370646.html 转载请保留说明!

上一篇:win7下安装配置node.js+express开发环境(win7安装要求配置)

下一篇:深入浅析Node.js 事件循环(node.js gui)

  • 企业所得税季度申报表怎么填
  • 全国税务师官网报名
  • 企业建厂房购进材料可以抵扣吗
  • 增值税普票可以开给个人吗
  • 事假工资在税前扣除标准
  • 预算为负数实际为负数 怎么计算完成率
  • 生产型增值税转变为消费型增值税
  • 外借资质收取的税费会计处理
  • 行政相对人和行政管理相对人的区别
  • 支付的各项税费包括个人所得税吗
  • 退税显示未完成怎么处理
  • 采购合同清单的安装调试费如何开具发票?税率是多少
  • 现金返利怎么做账
  • 利息支出手续费
  • 资产处置损益和营业外收支的区别和联系
  • 企业改制后职工有几项补偿
  • 应纳税所得额怎么理解
  • 仓储费怎么账务处理
  • 公司购买投影仪的必要性?
  • 编制会计报表利润表
  • 劳务公司客户问题分析
  • 金蝶如何结转折旧费用的操作步骤
  • 社会保险费缴费凭据在哪查
  • 存货的入账价值怎么计算
  • 新版edge浏览器如何恢复设置
  • 微软发布Windows 10正式版 新浪
  • 银行利息为什么只算10个月
  • 从银行提取现金准备发放工资
  • ps工具栏失灵
  • php两种赋值方式
  • php生成图片 html转img
  • 应税消费品投资的筹划方法
  • 缴住房公积金会计分录怎么写
  • php email
  • 甲产品生产耗用a材料10000千克,单位成本
  • 会计怎么区别法定维修义务和合同义务
  • 【AIGC】1、爆火的 AIGC 到底是什么 | 全面介绍
  • 申请个人所得税
  • 前端好看的颜色
  • 微信小程序开发公司
  • br命令怎么用
  • 库存盘亏进项税怎么抵扣
  • 存货盘盈盘亏的会计处理
  • 预缴增值税所需成本
  • 装卸搬运的设备有哪些
  • 个税年度汇算清缴总结
  • 代购进口货物垫付方案
  • 注销公司流程超详细
  • sql server使用sql server身份登录
  • 小规模纳税人应交税费的二级科目
  • 汇算清缴要求
  • 不用交社保的几种情况
  • 购买软件使用费计入什么科目
  • 融资租赁业务利润怎么算
  • 固定资产如何入账处理
  • 财务收入支出明细表
  • 所得税汇算清缴需要调增的项目
  • 应收账款多收了退回怎么做账
  • 商业企业可将商品分为哪三类
  • win7系统怎么把桌面文件放到d盘
  • win7系统IE浏览器版本
  • ie8-ie11浏览器
  • scumpve服务器
  • shell 脚本 判断
  • dos命令行怎么打开
  • 基于像素的分类方法
  • js绑定onchange
  • c和unity3d
  • w10cmd命令高级命令
  • 本地安装策略在哪里
  • jQuery使用$.ajax提交表单完整实例
  • 在全盘搜索以win
  • 安卓端测试
  • javascript 自定义类
  • 经营所得个人所得税税率表
  • 高速公路发票在哪里开
  • 车船税的纳税期限是
  • 山东税务申报如何网上申报
  • 西安市经开区税务
  • 医务人员抗疫补助发放标准最新
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设