node架构与模块机制

回到node
  • node特性
    • 基于chrome V8特性
    • 基于事件驱动
    • 非阻塞io
  • node的web开发优势
    • 高并发服务
    • 高性能io node内部有一个进程池
    • 前后端代码统一
node内部架构

  • 通过绑定调用C++,js可以调用c++程序。js是单线程的,如何去调用底层呢 node有一个插件比如libuv用来读取文件。node底层c++有一个线程池,这个跟js无关。还有事件循环,有一个循环机制维护一个消息队列
node模块机制
  • 以模块(文件)来划分功能、组织代码和代码复用
  • 包规范来管理应用和可复用组件
  • 用npm工具和网站进行开源社区代码共享
Node模块模型
  • 核心模块(C++写的,可以直接拿来用的)
    • C/C++内建模块,最底层的模块。提供API给Javascript核心模块或其他Javascript文件模块调用(process.binding())
    • Javascript核心模块,存放在node安装目录的lib下,为C/C++内建模块提供封装和桥接
  • 文件模块
    • C++扩展模块,为了运行效率和特殊目的按照Node规范编译,扩展名为node,用process.dlopen()加载执行(动态连结库)
    • Javascript文件模块,由第三方或用户自行编写的模块
常用的Node核心模块
  • console:控制台输入输出
  • fs:与文件系统交互(在不同操作系统下是不一样的,node底层有个机制封装,可以使我们用的一样,实现跨平台)
  • fttp:提供HTTP服务器功能
  • net:有很多C++的库 提供TCP/IP网络功能
  • os:提供了一些操作系统相关的实用方法,比如取cpu、内存的信息
  • path:一般和os合起来用 提供了一些操作系统相关的实用方法
  • url:解析URL
  • querystring:解析URL的查询字符串
  • crypto:提供加密和解密功能,基本上是对OpenSSL的包装
模块对象
  • 模块对象(module)实际上也是一个文件,表示当前模块文件,是一个js对象。模块对象不是全局的,而是每个模块唯一的
  • 模块对象的属性
    • module.id,模块的标识符,通常是完全解析后的文件名
    • module.loaded 模块是否已经加载完成,或正在加载中 js运行时要先运行模块中的代码,加载完成后再执行其他的
    • filename 模块完全解析后的文件名
    • parent 调用该模块的模块
    • children 被该模块引用的模块对象
    • exports 模块的导出对象,默认为空对象
模块的导出
  • module.exports,模块的导出对象,默认为空对象 例子 exptest
    • exports变量是module.exports的快捷方式,module.exports.f=…可以被更简洁地写成 exports.f=…
    • exports变量直接赋值(exports=…)会使之不再是module.exports的快捷方式,导致不能被导出
    • 为避免出错,模块的导出都用module.exports,不用exports
模块引用
  • 使用require方法来指定加载模块,方法的参数是模块的标识符
  • 模块标识符包括
    • 核心模块,如http, fs, path等(核心模块不需要写路径,默认路径)
    • 文件模块,可以省略文件扩展名
      • 以.或..开始的相对路径
      • 绝对路径
    • 安装包模块,如express, colors
      • 在全局(npm list -global)或当前应用的node_modules中寻找目录
      • 在package.json文件中,寻找main属性所指明的模块入口文件
      • 没有package.json文件,以index.js为模块入口文件
  • require.resolve()可用来解析模块标识符的绝对路径。
模块缓存
  • 模块在第一次require后会被缓存,多次require不会导致模块的代码被执行多次
  • Node模块的缓存不同于浏览器的js缓存,浏览器只缓存文件,Node模块缓存的是编译和执行之后的对象
  • require.cache对象代表Node模块缓存区,缓存的模块以属性的方式加入该对象,可以用require.cache[‘模块标识符’]来访问具体的缓存模块,也可以delete该缓存
node包规范
  • Node采用包来对一组具有相互依赖关系的模块进行统一管理,封装为独立的复用组件或单个应用
  • Node的包通常为一个目录,包括如下内容
    • package.json,包的描述文件
    • bin目录,用于存放可执行文件和其他二进制文件
    • lib目录,用于存放待加载的js文件
    • doc目录,用于存放包使用说明的文档
    • test目录,用于存放单元测试用例代码文件
    • node_modules目录,本地安装的其他第三方包(全局安装的第三方包用npm list -g查询)
package.json
  • package.json文件是一个JSON对象
  • package.json的主要属性
    • name:包名,npm install依赖此名称
    • version:版本号,版本号为a,b,c的形式,其中a是大版本号,b是小版本号,c是补丁号
    • description:项目描述,npm search会用到
    • keywords:关键字,npm search会用到
    • main:包输出主入口模块的ID,当包被require时,返回的就是这个模块的导出
    • author,contributors:author是一个人,contributors是一组人
    • dependents:当前包所依赖的其他包和包的版本
    • scripts:指定了运行脚本命令的npm命令行缩写
基于包规范开发应用流程
  • 创建目录
  • 进入目录
  • 初始化(npm init生成package.json文件)
  • 配置依赖项(修改package.json的dependencies)
  • 安装依赖包(npm install)
  • 配置运行脚本命令(scripts的start子项,配置start是为统一包运行入口方式)
  • 编写代码
  • 运行代码(npm start)

非阻塞IO和事件驱动

非阻塞IO
  • 操作系统内核进行I/O操作时有两种方式
    • 阻塞,应用要读取磁盘某文件时,要等待系统内核完成硬盘寻道、读取数据、复刻数据到内存等操作后,调用才结束
    • 非阻塞,应用的I/O调用可以立即返回,但返回的是调用的状态,需要轮询的方式确定系统内核是否完成所有操作
    • Windows的IOCP及*nix的libev有不同的实现
  • Node的非阻塞I/O
    • 底层是基于libuv的线程池(但也把IOCP包括在内(为了跨平台))
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值