当前位置: 首页 > 编程笔记 >

Nodejs模块载入运行原理

文德曜
2023-03-14
本文向大家介绍Nodejs模块载入运行原理,包括了Nodejs模块载入运行原理的使用技巧和注意事项,需要的朋友参考一下

前言

使用Nodejs,就不可避免地引用第三方模块,它们有些是Nodejs自带的(例:http,net...),有些是发布在npm上的(例:mssql,elasticsearch...)

本篇章聚焦3个问题:

  1. Nodejs模块的加载过程。
  2. 应用启动的过程。
  3. 应用如何加载依赖模块。

1.模块的加载过程

Nodejs 模块大概可分为4种:

a) builtin module Nodejs中以C++形式提供的模块。

b) constant module Nodejs中定义常量的模块。

c) native module Nodejs中以javascript形式提供的模块。

d) 第三方module 由第三方提供的模块。

我们先看builtin module 和 native module的生成过程。

native JS module的生成相对复杂一些,编译后,会在/out/release/obj/gen目录下生成一个node_natives.h。

该文件是由js2c.py生成,它会把Nodejs源码中的lib目录下,所有js文件转成ASCII码,并存放在相应的数组里。

builtin C++ module 生成过程相对简单,每个builtin C++的模块入口,都会通过宏NODE_MODULE_CONTEXT_AWARE_BUILTIN扩展成一个func,例如对tcp_wrap模块而言,会扩展成static void register_tcp_wrap() attribute(constructor) 函数。

熟悉GCC的朋友都知道,attribute(constructor)修饰的函数会在Nodejs的main()函数之前被执行,也就是说,builtin C++ module 会在main()函数之前被载入到modlist_builtin列表,而modlist_builtin是一个struct node_module类型的指针,get_builtin_module()会遍历查找我们所需的模块。

其实无论是naive JS module 还是 builtin C++ module,最终都是要被编译成可执行文件。对于两者的提取方式,却大不相同,js module 使用process.binding('natives'),而C++ module 则直接使用get_builtin_module()。

在node.cc里面提供了一个binding()函数,当我们应用require()来引用另外一个模块时,binding()函数便会被引入。下面我们分析一下这个函数:

可以目测到,函数主要为三个模块服务:builtin,constants和native。

builtin优先级最高,会到modlist_builtin中查找,过程非常简单,遍历整个列表,查找相同名字的模块即可。找到后,模块的注册函数会被先执行,然后将数据exports返回。

constants模块优先级次之,Nodejs中的常量定义通过constants导出。

native 优先级最低。

2.应用启动的过程

上图为一个流程图,它描述了test.js做为参数启动开始,最终被执行。整个过程可以分为4步:

1.可执行文件 node : node入口,在启动过程中主要扮演环境准备工作

2.src/node.js:启动脚本

3.Native Module:为module.js 的执行做准备工作

4.module.js:native module,用来加载,编译,执行应用程序

应用如何加载依赖模块

前面提到NativeModule.require()只负责帮助引用natives module,这对于lib/module.js而言已经足够了。

但是很明显,一般应用不但需要引用matives module,还要引用第三方模块,让我们看一下module.js中的Module.prototype._require()函数中。

 类似资料:
  • 本文向大家介绍深入理解Nodejs Global 模块,包括了深入理解Nodejs Global 模块的使用技巧和注意事项,需要的朋友参考一下 浏览器上有自己的全局对象 window,同理, nodejs 下也有自己的全局对象 global,并且在各个模块下 都可以直接访问 global 对象。 在 nodejs 中,除了可以直接使用 V8 JavaScript 引擎中所支持的原生 JavaScr

  • 我想调用我的函数main()使用html onload事件和console.log文本导入从另一个(生成Object.js)文件,但当我导入函数,onload事件停止工作和函数main()不再使用。 HTML: 生成对象。js: main.js: 当我尝试控制台时。main()中的log(“text”)可以正常工作,但当我尝试使用导入的函数时却不行。我该怎么做才能解决这个问题? Chrome控制台

  • 例如,我希望将我的套接字路由和拆分为不同的文件,但仍然可以使用回调参数,如下所示: 到目前为止,它们都在一个文件中,我不喜欢这样。

  • 我是这个巴别塔的新成员,有一些在nodejs方面的经验。我的包裹。json文件有一个巴别塔 “@babel/preset-react”:“^7.10.4”、“@nuxtjs/eslint-config”:“^0.0.1”、“babel-cli”:“^6.26.0”, 这些依赖关系与巴别塔有关。从一些无法工作的开发人员那里得到了这个项目。安装依赖关系和其他东西后。当我试图通过nuxtjs运行项目给我

  • 本文向大家介绍深入浅析Nodejs的Http模块,包括了深入浅析Nodejs的Http模块的使用技巧和注意事项,需要的朋友参考一下 一、http服务器     我们知道传统的HTTP服务器是由Aphche、Nginx、IIS之类的软件来搭建的,但是Nodejs并不需要,Nodejs提供了http模块,自身就可以用来构建服务器,例如: http模块中封装了一个HTTP服务器和一个简易的HTTP客户端

  • 问题内容: 只是想知道我们如何在node.js 8中导入模块-我们仍在使用吗? 还是我们仍然需要babel来使用? 我一直在挖掘,但似乎没有答案。如果我们仍然必须使用require,为什么节点还不能实现? 问题答案: UPDATE-2018.11.15↓ 简短答案 我们仍在使用 长答案 ESM加载已部分降落在2017年9月发布的node 上。正因为如此,它已经成为规范的一部分,并且已经作为实验功能