包管理工具
前置概念
模块(Module)
文件即模块,人口文件称为 「入口模块或主模块」
库(Library,简称「lib」)
一个或多个模块组成的一个功能块
包(Package)
有元数据的库,元数据有:名称、描述、git 仓库、作者、依赖等,为库提供信息的
关系

包管理(NPM)
NPM 全称 Node Package Manager,是 Node 的包管理器,运行在 Node 环境,为包提供文件系统的能力。npm 是前端包管理工具的基础设施,在 npm 的基础上可以去自定义包管理模型
NPM 不能运行在浏览器的环境,因为浏览器提供的能力是有限的,再加上浏览器还有种种限制,所以 NPM 运行在 Node 端更合适,可以充分利用 Node 的能力。
NPM 的出现解决了,包管理的一些痛点:
- 可 以直接下载指定版本的包,而不需要去 github 手动下载某个版本,以及拷贝到本地工作目录等一些列繁琐的操作
- 自动下载依赖的包,不需要人为的下载
- 更新库通过版本控制,省去了自己去服务器管理的成本
- 如何复用
NPM 的出现解决了 Node 包管理的缺陷,后被纳入到 Node 安装环境中,使得 NPM 安装更方便
组成
由三部分组成:
- 官网:提供包的查询能力,以及包的用户信息管理能力
- Register:包的仓库,类似 Docker Hub,存储所有开发的第三方包,开发者可直接从仓库读取下载需要的包
- CLI:Command Line Interface 命令行接口,可以使用命令行来使用 NPM 的能力
包的安装
NPM 安装的包,在 Node 环境被称为「第三方包」,安装也很简单,可以直接使用 NPM CLI 安装
- 本地安装
- 命令:
npm i [包名@版本号] [option],option 不是全局就行 - 本地安装会将包安装在当前目录的
node_modules下。 - 若第三方包也存在 CLI,NPM 会创建该包的软链接到
node_modules/.bin目录下,这时可以使用npx [命令名]来执行包提供的 CLI 能力
- 命令:
- 全局安装
- 命令:
npm i [包名@版本号] [option],option 是-g/--global - 全局的包一般都有 CLI 脚本,版本稳定,大部分包都会用到,比如:nodemon、http-server、typescript 等
- 命令:
包配置
NPM 包管理需要在包的「根目录」创建一个 package.json 配置文件,用来描述包的配置信息。
package.json 包含的主要配置项:
- name:包的名称,该名称必须是英文单词字符,支持连接符
- version:版本
- 版本规范:主版本号.次版本号.补丁版本号
- 主版本号:仅当程序发生了重大变化时才会增长,如新增了重要功能、新增了大量的API、技术架构发生了重大变化
- 次版本号:仅当程序发生了一些小变化时才会增长,如新增了一些小功能、新增了一些辅助型的API
- 补丁版本号:仅当解决了一些 bug 或 进行了一些局部优化时更新,如修复了某个函数的 bug、提升了某个函数的运行效率
- description:包的描述
- homepage:官网地址
- author:包的作者,必须是有效的 npm 账户名,书写规范是
account <mail>,例如:zhangsan <zhangsan@gmail.com>,不正确的账号和邮箱可能导致发布包时失败 - repository:包的仓储地址,通常指 git 或 svn 的地址,它是一个对象
- type:仓储类型,git 或 svn
- url:地址
- main:包的入口文件,使用包的人默认从该入口文件导入包的内容
- keywords: 搜索关键字,发布包后,可以通过该数组中的关键字搜索到包
使用npm init --yes或npm init -y可以在生成配置文件时自动填充默认配置
package.json 另一个重要作用就是,记录当前 NPM 工程包的依赖
- dependencies:生产环境的依赖包
- devDependencies:仅开发环境的依赖包
可以使用以下命令来安装依赖包到该工程中
## 本地安装所有依赖 dependencies + devDependencies
npm install
npm i
## 仅安装生产环境的依赖 dependencies
npm install --production
## 安装依赖到生产环境
npm i 包名
npm i --save 包名
npm i -S 包名
## 安装依赖到开发环境
npm i --save-dev 包名
npm i -D 包名
包的使用
在 Node 环境下,可以通过 require 函数加载模块,如果 require 参数不是一个相对路径,Node 就认为该模块是一个「第三方模块」,会到项目的 node_modules 目录下查找模块的入口文件。
查找有以下规则:
- 先对
require 参数加「文件后缀」,去匹配「文件」,匹配到了,就去执行文件,并返回module.exports内容 - 上一步匹配失败,就去匹配「目录」
- 匹配到目录,读取该目录下
package.json文件的main属性- 存在
main值对应的文件,就执行文件,并返回module.exports内容。若 main 对应的文件不存在,Node 会给一个 DeprecationWarning 提示信息,返回一个空对象 - 不存在
main,默认查找目录下的index.js文件:存在index.js文件,就执行文件,并返回module.exports内容;不存在index.js文件,就报错Error: Cannot find module 'xxxx'
- 存在
- 没有匹配到目录,就在当前项目的「上级目录」下,查找是否存在
node_modules目录:存在就重复上述步骤;否则就往上级目录依次继续查找node_modules目录,若最终在顶级目录依然没找到模块,Node 就会报错
- 匹配到目录,读取该目录下
在 Node 中,引入一个 json 文件,会被转为 js 对象
依赖包的版本
版本规范:主版本号.次版本号.补丁版本号
- 主版本号:仅当程序发生了重大变化时才会增长,如新增了重要功能、新增了大量的API、技术架构发生了重大变化
- 次版本号:仅当程序发生了一些小变化时才会增长,如新增了一些小功能、新增了一些辅助型的API
- 补丁版本号:仅当解决了一些 bug 或 进行了一些局部优化时更新,如修复了某个函数的 bug、提升了某个函数的运行效率
package.json 记录依赖版本号的意义:
| 符号 | 描述 | 示例 | 示例描述 |
|---|---|---|---|
| > | 大于某个版本 | >1.2.1 | 大于1.2.1版本 |
| >= | 大于等于某个版本 | >=1.2.1 | 大于等于1.2.1版本 |
< | 小于某个版本 | <1.2.1 | 小于1.2.1版本 |
<= | 小于等于某个版本 | <=1.2.1 | 小于等于1.2.1版本 |
| - | 介于两个版本之 间 | 1.2.1 - 1.4.5 | 介于1.2.1和1.4.5之间 |
| x | 不固定的版本号 | 1.3.x | 只要保证主版本号是1,次版本号是3即可 |
| ~ | 补丁版本号可增 | ~1.3.4 | 保证主版本号是1,次版本号是3,补丁版本号大于等于4 |
| ^ | 此版本和补丁版本可增 | ^1.3.4 | 保证主版本号是1,次版本号可以大于等于3,补丁版本号可以大于等于4 |
| * | 最新版本 | * | 始终安装最新版本 |
NPM 脚本
位置:paekage.json -> scripts 对象
特点:scripts 对象 的 key 是脚本的名称,value 是具体要在命令行执行的脚本
执行:使用 npm run 脚本名称 来执行脚本。脚本省略了 npx 关键字,所以要运行本地环境的 CLI(node_modules/.bin),可不写 npx
小细节:
- 若脚本名称是
start、stop、test,可以省略run - NPM 默认内置了一个
start的脚本,值为node server.js