Node.js 中的模块
Node.js
遵循了 CommonJS
模块化规范,CommonJS
规定了模块的特性和各模块之间如何相互依赖
- 每个模块内部,
module
变量代表当前模块 module
变量是一个对象,它的exports
属性(即module.exports
)是对外的接口- 加载某个模块,其实是加载该模块的
module.export
s 属性。require() 方法用于加载模块
包
Node.js
中的第三方模块又叫做包
不同于 Node.js
中的内置模块与自定义模块,包是由第三方个人或团队开发出来的,免费供所有人使用。Node.js
中的包都是免费且开源的
- 由于
Node.js
的内置模块仅提供了一些底层的 API,导致在基于内置模块进行项目开发的时,效率很低 - 包是基于内置模块封装出来的,提供了更高级、更方便的 API,极大的提高了开发效率
- 包和内置模块之间的关系,类似于
jQuery
和 浏览器内置API
之间的关系
我们可以使用这些命令在项目中添加包
npm install 包的完整名称
#或者
npm i 包的完整名称
npm i 包的完整名称 包的完整名称(加空格可以安装多个包)
npm add 包的完整名称
使用 npm uninstall
来卸载指定的包
使用镜像源可以解决一些npm
下载缓慢的问题
设置镜像
npm 官方原始镜像网址是:https://registry.npmjs.org/
淘宝 NPM 镜像:http://registry.npmmirror.com
阿里云 NPM 镜像:https://npm.aliyun.com
腾讯云 NPM 镜像:https://mirrors.cloud.tencent.com/npm/
华为云 NPM 镜像:https://mirrors.huaweicloud.com/repository/npm/
网易 NPM 镜像:https://mirrors.163.com/npm/
中国科学技术大学开源镜像站:http://mirrors.ustc.edu.cn/
清华大学开源镜像站:https://mirrors.tuna.tsinghua.edu.cn/
使用淘宝镜像源加速 NPM
# new
npm config set registry https://registry.npmmirror.com
# old
npm config set registry https://registry.npm.taobao.org
使用阿里云 镜像源加速 NPM
npm config set registry https://npm.aliyun.com
使用腾讯云镜像源加速 NPM
npm config set registry http://mirrors.cloud.tencent.com/npm/
使用华为云 镜像源加速 NPM
npm config set registry https://mirrors.huaweicloud.com/repository/npm/
返回npm 官方原始镜像
npm config set registry https://registry.npmjs.org/
使用那个镜像,只需要 npm config set registry + 对应的镜像网址就好了
npm config set registry + URL
查看当前的镜像源:
npm config get registry
包的分类
项目包
那些被安装到项目的 node_modules
目录中的包,都是项目包。项目包又分为两类
- 开发依赖包(被记录到
devDependencies
节点中的包,只在开发期间会用到)npm i 包名 -D
- 核心依赖包(被记录到
dependencies
节点中的包,在开发期间和项目上线之后都会用到)npm i 包名
全局包
在执行 npm install
命令时,如果提供了 -g
参数,则会把包安装为全局包
全局包会被安装到 C:\Users\用户目录\AppData\Roaming\npm\node_modules
目录下
npm install 包名 -g # 全局安装指定的包
npm uninstall 包名 -g # 卸载全局指定的包
注意
- 只有工具性质的包,才有全局安装的必要性。因为它们提供了好用的终端命令
- 判断某个包是否需要全局安装后才能使用,可以参考官方提供的使用说明即可
规范的包结构
一个规范的包,它的组成结构,必须符合以下 3 点要求
- 包必须以单独的目录而存在
- 包的顶级目录(点进去的目录)下要必须包含 package.json 这个包管理配置文件
package.json
中必须包含name
,version
,main
这三个属性,分别代表包的名字、版本号、包的入口(.js
文件)(require()
加载的文件)
模块的加载机制
模块在第一次加载后会被缓存,多次调用 require()
模块的代码只会被执行一次。不论是内置模块、用户自定义模块、还是第三方模块,它们都会优先从缓存中加载,从而提高模块的加载效率。
- 内置模块的加载优先级最高(当第三方模块和内置模块同名时)
- 使用 require() 加载自定义模块时,必须指定以
./
或…/
开头的路径标识符。在加载自定义模块时,如果没有指定./
或…/
这样的路径标识符,则 node 会把它当作内置模块或第三方模块进行加载。 - 在使用 require() 导入自定义模块时,如果省略了文件的扩展名,Node.js 会按顺序分别尝试加载以下的文件
- 按照确切的文件名进行加载
- 补全
.js
扩展名进行加载 - 补全
.json
扩展名进行加载 - 补全
.node
扩展名进行加载 - 加载失败,终端报错
- 如果传递给 require() 的模块标识符不是一个内置模块,也没有以 ./ 或 …/ 开头,则 Node.js 会从当前模块的父目录开始,尝试从 /node_modules 文件夹中加载第三方模块,如果没有找到对应的第三方模块,则移动到再上一层父目录中,进行加载,直到文件系统的根目录
- 假设在 ‘C:\Users\Public\Desktop\demo\node_modules\a.js’ 里调用 require(‘tools’),Node.js 会按以下顺序查找
1.C:\Users\Public\Desktop\demo\node_modules\tools
2.C:\Users\Public\Desktop\node_modules\tools
3.C:\Users\Public\Desktop\tools
....
4.C:\tools
5.报错 - 当把目录作为模块使用require加载时,会按照下面的步骤尝试加载模块
在被加载的目录下查找一个叫做package.json
的文件,并寻找 main 属性值作为 require() 加载的入口-->(如果目录里没有package.json
文件,或者 main 入口不存在或无法解析)试图加载目录下的index.js
文件-->在终端打印错误消息,报告模块的缺失:Error: Cannot find module ‘xxx’