Node.js 中的模块

Node.js 遵循了 CommonJS 模块化规范,CommonJS 规定了模块的特性和各模块之间如何相互依赖

  • 每个模块内部,module 变量代表当前模块
  • module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口
  • 加载某个模块,其实是加载该模块的 module.exports 属性。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 中必须包含 nameversionmain这三个属性,分别代表包的名字、版本号、包的入口(.js文件)(require()加载的文件)

模块的加载机制

模块在第一次加载后会被缓存,多次调用 require() 模块的代码只会被执行一次。不论是内置模块、用户自定义模块、还是第三方模块,它们都会优先从缓存中加载,从而提高模块的加载效率。

  1. 内置模块的加载优先级最高(当第三方模块和内置模块同名时)
  2. 使用 require() 加载自定义模块时,必须指定以 ./…/ 开头的路径标识符。在加载自定义模块时,如果没有指定 ./…/ 这样的路径标识符,则 node 会把它当作内置模块或第三方模块进行加载。
  3. 在使用 require() 导入自定义模块时,如果省略了文件的扩展名,Node.js 会按顺序分别尝试加载以下的文件
    1. 按照确切的文件名进行加载
    2. 补全 .js 扩展名进行加载
    3. 补全 .json 扩展名进行加载
    4. 补全 .node 扩展名进行加载
    5. 加载失败,终端报错
  4. 如果传递给 require() 的模块标识符不是一个内置模块,也没有以 ./ 或 …/ 开头,则 Node.js 会从当前模块的父目录开始,尝试从 /node_modules 文件夹中加载第三方模块,如果没有找到对应的第三方模块,则移动到再上一层父目录中,进行加载,直到文件系统的根目录
  5. 假设在 ‘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.报错
  6. 当把目录作为模块使用require加载时,会按照下面的步骤尝试加载模块
    在被加载的目录下查找一个叫做 package.json 的文件,并寻找 main 属性值作为 require() 加载的入口-->(如果目录里没有 package.json 文件,或者 main 入口不存在或无法解析)试图加载目录下的 index.js 文件-->在终端打印错误消息,报告模块的缺失:Error: Cannot find module ‘xxx’
posted on 2024-08-21 10:28  XiSoil  阅读(9)  评论(0编辑  收藏  举报