新增了哪些概念
模块
Node.js 的模块一般分为2种类型
- 内置模块:即 Node.js 原生提供的功能,比如fs,http等
- 文件模块:即 node_modules 目录下的都是文件模块
模块加载系统
Node.js 有两个模块加载系统:CommonJS 模块和 ECMAScript 模块。
- 调用 require() 始终使用 CommonJS 模块加载器
- 调用 import() 始终使用 ECMAScript 模块加载器
CommonJS规范
一个遵循 CommonJS 规范的包必然包含一个包描述文件,并且处于包的根目录下,名为 package.json。
- 二进制文件在 bin 目录下
- JavaScript 源码在 lib 目录下
- 文档在 doc 目录下
- 单元测试文件在 test 目录下
最终在程序里导出的是 module.exports,exports 只是对 module.exports 的一个全局引用。
require加载机制
在 Node.js 中,第一次调用时会缓存模块,这意味着之后的每次调用都会得到相同的实例。
加载顺序
- 优先加载内置模块,即使有同名文件,也优先使用内置模块
- 不是内置模块,先查找缓存
- 如果找不到,则查找对应路径的文件或文件夹
- 如果找不到,则到 node_modules 目录下进行查找
- 如果找不到,报错
查找模块是文件夹
- 如果查找的模块是一个文件夹,则先查找文件是否有 package.json 文件,如果有,则定位里面的 main 字段,main 字段有值就加载对应的文件,比如 Jquery 的 main 字段是
"main":"dist/jquery.js"
- 如果没有 package.json 或 package.json 里面没有 main 字段,则查找 index 文件
- 如果找不到,报错
支持的文件类型
require 支持3种文件类型
- .js:最常用的文件,加载的时候先运行 js 文件代码,然后将 module.exports 作为 require 的返回值
- .json:文本文件,直接用 JSON.parse 转化成对象后返回
- .node:C++编译后的二进制文件,需要使用 node-gyp 进行编译
模块循环引用
循环引用是指两个或多个模块之间相互引用。
Node.js 对循环引用做了处理,例如 a 模块和 b 模块相互引用,a 模块在真正加载前会先缓存,a 模块在正式加载时加载了 b 模块,等到 b 模块加载 a 模块时,这时候缓存已经有 a 模块了,即使这时候 exports 是不完整的。
在开发过程中需要注意,通过将公共功能抽离出来,可以有效避免循环引用问题。
内置模块
以下是 Node.js 常用的内置模块,无需安装即可使用
内置模块 | 描述 |
---|---|
buffer | 处理二进制数据 |
cluster | 将单个 Node.js 进程拆分为多个进程 |
fs | 处理文件系统 |
http | 让 Node.js 充当 HTTP 服务器 |
https | 让 Node.js 充当 HTTPS 服务器 |
net | 创建服务器和客户端 |
buffer | 处理二进制数据 |
buffer | 处理二进制数据 |
os | 提供有关操作系统的信息 |
path | 处理文件路径 |
querystring | 处理 URL 查询字符串 |
stream | 处理流数据 |
timers | 在给定的毫秒数后执行函数 |
url | 解析 URL 字符串 |
util | 访问实用功能 |
Npm
Npm 是 Node.js Package Manager 的缩写,即 Node.js 包管理器。
Npm2 的依赖是嵌套式的,安装一个依赖时,其依赖不会被安装到node_modules 下。
但从 Npm3 开始(为了节省一点空间,同时解决 Windows 安装路径过长问题),将依赖扁平化,就会出现项目中依赖只有十几个,但在 node_modules 目录里可能出现成百上千个文件夹。