Appearance
npm 包管理基础
npm包管理是Node.js开发的核心技能。本章将详细介绍npm包的安装、卸载、更新等基础操作,以及如何有效管理项目依赖。
包的类型
按功能分类
- 工具包:如
webpack、babel等构建工具 - 库包:如
lodash、moment等工具库 - 框架包:如
express、react等框架 - 可执行包:如
nodemon、http-server等命令行工具
按作用域分类
- 普通包:如
lodash - 作用域包:如
@babel/core、@angular/core
安装包
基本安装命令
bash
# 安装包到dependencies(生产环境依赖)
npm install package-name
npm i package-name # 简写
# 安装特定版本
npm install package-name@1.2.3
npm i package-name@^1.2.3 # 安装兼容版本
npm i package-name@~1.2.3 # 安装补丁版本
# 安装最新版本
npm install package-name@latest
npm i package-name@next # 安装预发布版本
安装到不同依赖类型
bash
# 生产依赖(默认)
npm install package-name
npm install package-name --save
# 开发依赖
npm install package-name --save-dev
npm i package-name -D
# 可选依赖
npm install package-name --save-optional
npm i package-name -O
# 仅生产环境(移除开发依赖)
npm install --production
NODE_ENV=production npm install
本地包安装
bash
# 从本地路径安装
npm install ./path/to/local/package
npm install file:./path/to/local/package
# 从Git仓库安装
npm install git+https://github.com/user/repo.git
npm install git+ssh://git@github.com/user/repo.git
npm install user/repo#branch # 安装特定分支
# 从tarball安装
npm install https://example.com/package.tgz
卸载包
bash
# 卸载包
npm uninstall package-name
npm un package-name
npm remove package-name
npm rm package-name
# 卸载开发依赖
npm uninstall package-name --save-dev
npm un package-name -D
# 卸载多个包
npm uninstall package1 package2 package3
更新包
检查更新
bash
# 检查过时的包
npm outdated
# 检查特定包
npm outdated package-name
# 查看可用版本
npm view package-name versions --json
npm view package-name@latest version
执行更新
bash
# 更新单个包
npm update package-name
# 更新所有包
npm update
# 更新到特定版本
npm install package-name@latest
# 使用npm-check-updates工具(需要先安装)
npx npm-check-updates
npx npm-check-updates -u # 更新package.json
npm install # 安装更新后的版本
依赖关系管理
dependencies vs devDependencies
json
{
"dependencies": {
// 生产环境必需的包
"express": "^4.18.0",
"lodash": "^4.17.21"
},
"devDependencies": {
// 开发环境需要的包
"jest": "^28.0.0",
"webpack": "^5.72.0",
"eslint": "^8.0.0"
}
}
peerDependencies
json
{
"peerDependencies": {
// 宿主环境应提供的依赖
"react": "^17.0.0 || ^18.0.0",
"vue": "^3.0.0"
},
"peerDependenciesMeta": {
"vue": {
"optional": true
}
}
}
bundledDependencies
json
{
"bundledDependencies": [
// 发布时包含的依赖
"package-name"
]
}
版本控制
语义化版本控制
json
{
"dependencies": {
// 允许补丁和次要版本更新,不允许主版本更新
"package-a": "^1.2.3",
// 只允许补丁版本更新
"package-b": "~1.2.3",
// 固定版本
"package-c": "1.2.3",
// 版本范围
"package-d": ">=1.0.0 <2.0.0",
// 通配符
"package-e": "1.x",
"package-f": "*"
}
}
预发布版本
bash
# 安装alpha版本
npm install package-name@alpha
# 安装beta版本
npm install package-name@beta
# 安装特定预发布标签
npm install package-name@1.0.0-beta.1
node_modules结构
扁平化结构
npm使用扁平化策略来减少嵌套:
bash
# 安装后node_modules可能的结构
node_modules/
├── lodash/ # 直接依赖
├── express/ # 直接依赖
├── accepts/ # express的依赖
├── array-flatten/ # express的依赖
├── debug/ # 多个包的共同依赖
└── ms/ # debug的依赖
重复依赖处理
当不同版本的同一包被需要时:
bash
node_modules/
├── package-a/
│ └── node_modules/
│ └── lodash@4.17.20 # package-a需要的版本
├── package-b/
│ └── node_modules/
│ └── lodash@4.17.21 # package-b需要的版本
└── lodash@4.17.21 # 顶层版本
package-lock.json详解
package-lock.json确保依赖树的一致性:
{
"name": "my-project",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"express": "^4.18.0"
}
},
"node_modules/express": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
"integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL2g==",
"requires": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1"
}
}
}
}
锁定文件最佳实践
# 总是提交package-lock.json到版本控制
git add package-lock.json
# 使用npm ci进行干净安装
npm ci # 忽略node_modules,完全按照lockfile安装
# 验证lockfile完整性
npm audit
脚本包管理
安装并运行一次性工具
# 使用npx运行包而不安装
npx create-react-app my-app
npx serve .
npx http-server
# npx会临时安装包并运行,然后清理
本地安装的可执行文件
{
"scripts": {
"build": "webpack --mode production",
"dev": "webpack serve --mode development",
"lint": "eslint src/",
"test": "jest"
}
}
本地安装的包会自动添加到PATH,可以在scripts中直接使用。
工作区包管理
设置工作区
{
"name": "my-workspace-project",
"private": true,
"workspaces": [
"packages/*",
"frontend",
"backend"
]
}
工作区命令
# 在特定工作区安装包
npm install package-name --workspace=frontend
# 在所有工作区安装包
npm install package-name --workspaces
# 在特定工作区运行脚本
npm run build --workspace=frontend
# 在所有工作区运行脚本
npm run build --workspaces
# 递归运行脚本
npm run build --workspaces --if-present
包搜索和发现
搜索包
# 搜索包
npm search lodash
npm search --searchopts name,description "react component"
# 查看包信息
npm view package-name
npm view package-name --json
npm view package-name version
npm view package-name versions # 查看所有版本
检查包内容
# 查看包文件列表
npm view package-name files
# 检查包大小
npm pack package-name # 下载tarball而不安装
npm view package-name dist.tarball # 获取tarball URL
依赖安全
安全审计
# 检查安全漏洞
npm audit
# 检查详细信息
npm audit --audit-level high
# 自动修复
npm audit fix
# 修复所有可能的问题(可能改变依赖版本)
npm audit fix --force
# 生成审计报告
npm audit --json > audit-report.json
安全最佳实践
# 定期检查依赖
npm outdated
# 使用npm-check更新依赖
npx npm-check -u
# 验证包的完整性
npm audit
npm fund # 查看项目资助信息
性能优化
安装优化
# 使用生产模式安装(跳过devDependencies)
npm install --production
# 使用淘宝镜像加速
npm install --registry https://registry.npmmirror.com/
# 使用缓存
npm install --prefer-offline # 优先使用缓存
清理和维护
# 验证缓存
npm cache verify
# 清理缓存
npm cache clean --force
# 删除node_modules并重新安装
rm -rf node_modules package-lock.json
npm install
通过掌握这些包管理基础,您可以更有效地管理项目依赖,确保项目的稳定性和安全性。