NodeJs浅讲

106 阅读6分钟

2019年写的ppt,准备用于团队分享,因为写的还不完整 就没分享。今日从ppt里撸出来放到这个平台,也算重温了一下知识点。。。

跨平台

起初,Node只可以在Linux平台上运行。如果想在Windows平台上学习和使用,则必须通过Cygwin或者MinGW。随着Node的发展,微软注意到了它的存在,并投入了一个团队帮助Node实现Windows平台的兼容,在v0.6.0版本发布时,Node已经能够直接在Windows平台上运行了。

兼容Windows和*nix平台主要得益于Node在架构层面的改动,它在操作系统与Node 上层模块系统 之间构建了一层平台层架构,即libuv。目前,libuv已经成为许多系统实现跨平台的基础组件。

image.png

CommonJS 的模块规范

前言

在Javascript的发展历程中,它主要在浏览器端发光发热。由于官方规范(ECMAScript)规范化的时间较早,规范涵盖的范畴非常小。这些规范中包含词法、类型、上下文、表达式、声明、方法、对象等语言的基本要素。在实际应用中,JavaScript的表现能力取决于宿主环境中的API支持程序。在Web1.0时代,只有对DOM、BOM等基本的支持。随着Web2.0的推进,HTML5崭露头角,它将Web网页带进Web应用时代,在浏览器中出现了更多、更强大的API供JavaScript调用,这得感谢W3C组织对HTML5规范的推进以及各大浏览器厂商对规范的大力支持。但是,Web在发展,浏览器中出现了更多的标准API,这些过程发生在前端,后端JavaScript的规范却远远落后。对于JavaScript自身而言,它的规范依然是薄弱的,还有以下缺陷。

1. 没有模块系统

2. 标准库较少

3. 没有标准接口

4. 缺乏包管理系统

加删除线是因为:现如今的node已经解决这些缺陷了

JavaScript 与 ECMAScript的关系

image.png

回到CommonJS的模块规范

CommonJS规范为JavaScript制定了一个美好的愿景-----希望JavaScript能够在任何地方运行。

CommonJS对模块的定义十分简单,主要分为模块引用模块定义模块标识3个部分

模块引用:require(’qs’);

模块定义:module.export.add = function(){}

模块标识:模块标识其实就是传递给require()方法的参数

Node的模块实现

Node在实现中并非完全按照规范实现,而是对模块规范进行了一定的取舍,同时也增加了少许自身需要的特性。尽管规范中exports、require和module听起来十分简单、但是Node在实现它们的过程中究竟经历了什么,这个过程需要知晓。

Node中引入模块,需要经历如下3个步骤

(1)路径分析

(2)文件定位

(3)编译执行

在Node中,模块分为三类:

一类是Node提供的模块,称为核心模块

一类是用户编写的模块,称为文件模块

一类是由npm/yarn等包管理器安装的模块;称为自定义模块/第三方模块;

优先从缓存加载

不论是核心模块还是文件模块,require()方法对相同模块的二次加载都一律采用缓存优先的方式,这是第一优先级的。不同之处在于核心模块的缓存检查先于文件模块的缓存检查

require.cache :所有已加载的模块都在这里缓存着。

路径分析和文件定位

因为标识符有几种形式,对于不同的标识符,模块的查找和定位有不同程度上的差异。

模块标识符主要分为以下几类。

1、核心模块,如http、fs、path

2、...开始的相对路径文件模块

3、以/开始的绝对路径文件模块。

4、非路径形式的文件模块

核心模块

核心模块的优先级仅次于缓存加载、它在Node的源代码编译过程中已经编译为二进制代码,其加载过程最快。

如果试图加载一个与核心模块标识符相同的自定义模块,那是不会成功的。如果自己编写了一个http模块,想要加载成功,必须选择一个不同的标识符或者换用路径的方式。

路径形式的文件模块

.../开始的标识符,这里都被当做文件模块来处理。在分析文件模块,require()方法会将路径转换为真实路径,并以真实路径作为索引,将编译执行后的结果存放到缓存中,以使二次加载更快。

由于文件模块给Node指明了确切的文件位置,所以在查找过程中可以节约大量时间,其加载速度慢于核心模块

自定义模块/第三方模块

自定义模块指的是非核心模块,也不是路径形式的标识符。它是一种特殊的文件模块,可能是一个文件或者包的形式。这类模块的查找是最费时的,也是所有方式中最慢的一种。 在介绍自定义模块的查找方式之前,需要先介绍一下模块路径这个概念 随意创建一个js文件其内容console.log(module.paths);。

image.png 你的输出跟我这里不会一样,但逻辑是一样的,显示一个数组,这个数组,就是查找三方模块时的查找路径队列,先从当前执行文件路径下查找node_modules,如果找不到再向父级目录查找node_modules,如果还找不到,继续向上找,直到找到根路径下的node_modules还找不到的话就会抛出一个错误

Node 的依赖

1、V8

由谷歌开源的一个高性能JavaScript引擎,该引擎采用c++编写,chrome浏览器用的就是这个引擎。V8可以单独运行,也可以嵌入c++应用中。

2、libuv

libuv是一个专注于异步I/O的跨平台类库。实际上它主要为Node.js而开发,不过也被其它的一些程序使用,如Luvit、Julia、pyuv等。

Node.js的一个重要概念就是事件循环。而Node.js的事件循环就是由这个libuv进行驱动的。有了libuv对Node.js的事件循环支持,读者才能在Node.js的异步世界中自由翱翔。

3、其它依赖

(1)http-parser 这是一个c实现的http消息解析器,其能解析http协议的请求数据和返回数据。

(2)OpenSSL 这是一套大名鼎鼎的安全套接字层协议库

(3)zlib 这是一个老牌的年代久远的提供数据压缩的功能的库。

……..

未完待续-敬请期待