Node.js 包管理
更新: 8/8/2025 字数: 0 字 时长: 0 分钟
包管理是 Node.js 生态系统的核心组成部分。npm(Node Package Manager)是 Node.js 的默认包管理器,还有其他优秀的包管理器如 Yarn 和 pnpm。
npm 基础
什么是 npm?
npm 是世界上最大的软件注册表,包含超过 100 万个包。它既是一个在线仓库,也是一个命令行工具。
npm 的作用
- 包安装:安装和管理项目依赖
- 版本管理:管理包的版本
- 脚本运行:运行项目脚本
- 包发布:发布自己的包到 npm 仓库
package.json 详解
package.json
是 Node.js 项目的核心配置文件。
创建 package.json
bash
# 交互式创建
npm init
# 使用默认值快速创建
npm init -y
# 使用自定义默认值
npm config set init-author-name "Your Name"
npm config set init-author-email "your.email@example.com"
npm config set init-license "MIT"
package.json 结构
json
{
"name": "my-awesome-project",
"version": "1.0.0",
"description": "一个很棒的 Node.js 项目",
"main": "index.js",
"type": "module",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest",
"test:watch": "jest --watch",
"build": "webpack --mode production",
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
"prepare": "husky install"
},
"keywords": [
"nodejs",
"javascript",
"web",
"api"
],
"author": {
"name": "Your Name",
"email": "your.email@example.com",
"url": "https://yourwebsite.com"
},
"license": "MIT",
"homepage": "https://github.com/username/my-awesome-project#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/username/my-awesome-project.git"
},
"bugs": {
"url": "https://github.com/username/my-awesome-project/issues"
},
"engines": {
"node": ">=14.0.0",
"npm": ">=6.0.0"
},
"dependencies": {
"express": "^4.18.2",
"lodash": "^4.17.21",
"mongoose": "^7.0.3"
},
"devDependencies": {
"nodemon": "^2.0.22",
"jest": "^29.5.0",
"eslint": "^8.39.0",
"prettier": "^2.8.8",
"husky": "^8.0.3"
},
"peerDependencies": {
"react": ">=16.8.0"
},
"optionalDependencies": {
"fsevents": "^2.3.2"
},
"bundledDependencies": [
"some-package"
],
"private": false,
"workspaces": [
"packages/*"
]
}
字段说明
json
{
"name": "项目名称(必须)",
"version": "版本号(必须,遵循 SemVer)",
"description": "项目描述",
"main": "入口文件",
"type": "module | commonjs",
"keywords": ["搜索关键词"],
"author": "作者信息",
"license": "许可证"
}
json
{
"scripts": {
"命令名": "要执行的命令"
},
"dependencies": {
"生产环境依赖": "版本号"
},
"devDependencies": {
"开发环境依赖": "版本号"
}
}
json
{
"engines": {
"node": "Node.js 版本要求",
"npm": "npm 版本要求"
},
"peerDependencies": {
"同伴依赖": "版本号"
},
"private": true,
"workspaces": ["工作区配置"]
}
依赖管理
安装依赖
bash
# 安装生产依赖
npm install express
npm install express mongoose lodash
npm i express # 简写
# 安装开发依赖
npm install --save-dev nodemon
npm install -D jest eslint prettier
# 安装全局包
npm install -g nodemon
npm install --global @vue/cli
# 安装特定版本
npm install express@4.18.2
npm install lodash@^4.17.0 # 兼容版本
npm install react@~16.8.0 # 近似版本
# 从 GitHub 安装
npm install user/repo
npm install https://github.com/user/repo.git
npm install git+ssh://git@github.com:user/repo.git
# 从本地路径安装
npm install ../my-package
npm install file:../my-package
版本号规则 (SemVer)
bash
# 版本号格式:主版本号.次版本号.修订号
# 例如:1.2.3
# 版本范围符号
^1.2.3 # 兼容版本:>=1.2.3 <2.0.0
~1.2.3 # 近似版本:>=1.2.3 <1.3.0
1.2.3 # 精确版本:=1.2.3
>=1.2.3 # 大于等于:>=1.2.3
<1.2.3 # 小于:<1.2.3
1.2.x # 通配符:>=1.2.0 <1.3.0
* # 任意版本
latest # 最新版本
查看和更新依赖
bash
# 查看已安装的包
npm list
npm ls
npm ls --depth=0 # 只显示顶级依赖
npm ls express # 查看特定包
# 查看全局包
npm list -g
npm ls -g --depth=0
# 查看包信息
npm info express
npm view express
npm show express versions --json # 查看所有版本
# 检查过时的包
npm outdated
npm outdated -g # 全局包
# 更新包
npm update
npm update express
npm update -g # 更新全局包
# 更新到最新版本
npm install express@latest
卸载依赖
bash
# 卸载包
npm uninstall express
npm remove express
npm rm express
# 卸载开发依赖
npm uninstall -D nodemon
# 卸载全局包
npm uninstall -g nodemon
npm 脚本
基本脚本
json
{
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "jest",
"build": "webpack --mode production",
"clean": "rm -rf dist/"
}
}
运行脚本
bash
# 运行脚本
npm run start
npm run dev
npm run test
npm run build
# 特殊脚本可以省略 run
npm start
npm test
# 传递参数
npm run test -- --watch
npm run build -- --env=production
高级脚本技巧
json
{
"scripts": {
"prebuild": "npm run clean",
"build": "webpack --mode production",
"postbuild": "npm run test",
"clean": "rimraf dist/",
"clean:cache": "npm cache clean --force",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
"format": "prettier --write src/",
"dev": "concurrently \"npm run dev:server\" \"npm run dev:client\"",
"dev:server": "nodemon server.js",
"dev:client": "webpack serve --mode development",
"deploy": "npm run build && npm run deploy:prod",
"deploy:prod": "rsync -avz dist/ user@server:/var/www/html/"
}
}
脚本中的环境变量
json
{
"scripts": {
"start:dev": "NODE_ENV=development node server.js",
"start:prod": "NODE_ENV=production node server.js",
"cross-platform": "cross-env NODE_ENV=production node server.js"
}
}
package-lock.json
作用和重要性
package-lock.json
锁定依赖的确切版本,确保团队成员和生产环境使用相同的依赖版本。
json
{
"name": "my-project",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"express": "^4.18.2"
}
},
"node_modules/express": {
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-...",
"dependencies": {
"accepts": "~1.3.8"
}
}
}
}
最佳实践
bash
# 提交 package-lock.json 到版本控制
git add package-lock.json
# 使用 npm ci 在生产环境安装
npm ci # 更快、更可靠的安装方式
# 更新 lock 文件
npm install # 会自动更新 lock 文件
npm update # 更新依赖并更新 lock 文件
npm 配置
查看和设置配置
bash
# 查看所有配置
npm config list
npm config ls -l # 显示所有配置项
# 查看特定配置
npm config get registry
npm config get cache
# 设置配置
npm config set registry https://registry.npm.taobao.org/
npm config set cache /path/to/cache
npm config set init-author-name "Your Name"
# 删除配置
npm config delete registry
# 编辑配置文件
npm config edit
常用配置项
bash
# 设置淘宝镜像
npm config set registry https://registry.npmmirror.com/
# 设置代理
npm config set proxy http://proxy.company.com:8080
npm config set https-proxy http://proxy.company.com:8080
# 设置缓存目录
npm config set cache /path/to/npm-cache
# 设置全局安装目录
npm config set prefix /path/to/global
# 设置日志级别
npm config set loglevel info
# 设置默认值
npm config set init-license MIT
npm config set init-version 0.1.0
.npmrc 文件
bash
# 项目级配置文件 .npmrc
registry=https://registry.npmmirror.com/
save-exact=true
engine-strict=true
# 用户级配置文件 ~/.npmrc
init-author-name=Your Name
init-author-email=your.email@example.com
init-license=MIT
npm 缓存管理
bash
# 查看缓存信息
npm cache verify
# 清理缓存
npm cache clean --force
# 查看缓存目录
npm config get cache
# 设置缓存目录
npm config set cache /new/cache/path
发布包到 npm
准备发布
bash
# 注册 npm 账户
npm adduser
# 或登录
npm login
# 查看当前用户
npm whoami
包的基本结构
my-package/
├── package.json
├── README.md
├── LICENSE
├── index.js
├── lib/
│ └── utils.js
├── test/
│ └── index.test.js
└── .npmignore
package.json 配置
json
{
"name": "my-awesome-package",
"version": "1.0.0",
"description": "一个很棒的 npm 包",
"main": "index.js",
"files": [
"lib",
"index.js",
"README.md"
],
"scripts": {
"test": "jest",
"prepublishOnly": "npm test"
},
"keywords": [
"utility",
"helper",
"javascript"
],
"author": "Your Name <your.email@example.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/username/my-awesome-package.git"
},
"bugs": {
"url": "https://github.com/username/my-awesome-package/issues"
},
"homepage": "https://github.com/username/my-awesome-package#readme"
}
.npmignore 文件
bash
# .npmignore
test/
*.test.js
.nyc_output/
coverage/
.env
.DS_Store
node_modules/
src/
.babelrc
webpack.config.js
发布流程
bash
# 检查包内容
npm pack
# 这会创建一个 .tgz 文件,可以检查包含的文件
# 测试发布(不会真正发布)
npm publish --dry-run
# 发布包
npm publish
# 发布 beta 版本
npm publish --tag beta
# 更新版本并发布
npm version patch # 修订版本 1.0.0 -> 1.0.1
npm version minor # 次版本 1.0.0 -> 1.1.0
npm version major # 主版本 1.0.0 -> 2.0.0
npm publish
管理已发布的包
bash
# 查看包信息
npm view my-package
# 撤销发布(72小时内)
npm unpublish my-package@1.0.0
npm unpublish my-package --force
# 废弃包版本
npm deprecate my-package@1.0.0 "This version has security issues"
# 查看下载统计
npm view my-package downloads
Yarn 包管理器
安装 Yarn
bash
# 使用 npm 安装
npm install -g yarn
# 使用 Homebrew (macOS)
brew install yarn
# 检查版本
yarn --version
Yarn 基本命令
bash
# 初始化项目
yarn init
yarn init -y
# 安装依赖
yarn install
yarn # 简写
# 添加依赖
yarn add express
yarn add -D nodemon # 开发依赖
yarn add -P lodash # 生产依赖
# 升级依赖
yarn upgrade
yarn upgrade express
# 移除依赖
yarn remove express
# 运行脚本
yarn start
yarn run build
# 全局安装
yarn global add nodemon
yarn global list
yarn global remove nodemon
Yarn vs npm
bash
npm install
npm install express
npm install -D nodemon
npm uninstall express
npm run start
npm update
npm list
bash
yarn
yarn add express
yarn add -D nodemon
yarn remove express
yarn start
yarn upgrade
yarn list
yarn.lock 文件
yaml
# yarn.lock
express@^4.18.2:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz"
integrity sha512-...
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
pnpm 包管理器
安装 pnpm
bash
# 使用 npm 安装
npm install -g pnpm
# 使用脚本安装
curl -fsSL https://get.pnpm.io/install.sh | sh -
# 检查版本
pnpm --version
pnpm 特点
- 节省磁盘空间:使用硬链接和符号链接
- 更快的安装速度:并行安装和缓存机制
- 严格的依赖管理:避免幽灵依赖
pnpm 基本命令
bash
# 安装依赖
pnpm install
pnpm i
# 添加依赖
pnpm add express
pnpm add -D nodemon
# 移除依赖
pnpm remove express
# 更新依赖
pnpm update
pnpm up
# 运行脚本
pnpm start
pnpm run build
# 全局安装
pnpm add -g nodemon
工作区 (Workspaces)
npm Workspaces
json
{
"name": "my-monorepo",
"private": true,
"workspaces": [
"packages/*",
"apps/*"
]
}
bash
# 安装所有工作区依赖
npm install
# 为特定工作区添加依赖
npm install express --workspace=packages/api
# 运行所有工作区的脚本
npm run test --workspaces
# 运行特定工作区的脚本
npm run build --workspace=packages/ui
Yarn Workspaces
json
{
"private": true,
"workspaces": {
"packages": [
"packages/*"
]
}
}
bash
# 安装依赖
yarn install
# 为工作区添加依赖
yarn workspace api add express
# 运行工作区脚本
yarn workspace ui run build
# 运行所有工作区脚本
yarn workspaces run test
安全性
审计依赖
bash
# npm 安全审计
npm audit
npm audit --audit-level moderate
npm audit fix
npm audit fix --force
# Yarn 安全审计
yarn audit
yarn audit --level moderate
# 使用 snyk
npm install -g snyk
snyk test
snyk fix
最佳安全实践
bash
# 使用 .nvmrc 锁定 Node.js 版本
echo "14.17.0" > .nvmrc
# 定期更新依赖
npm update
npm outdated
# 使用 npm ci 在生产环境
npm ci --only=production
# 检查许可证
npm install -g license-checker
license-checker
性能优化
加速安装
bash
# 使用淘宝镜像
npm config set registry https://registry.npmmirror.com/
# 使用 npm ci
npm ci # 比 npm install 更快
# 并行安装
npm install --prefer-offline
npm install --no-audit
npm install --no-fund
# 使用 pnpm
pnpm install # 通常比 npm 和 yarn 更快
减少包大小
bash
# 分析包大小
npm install -g bundlephobia
bundlephobia express
# 使用 webpack-bundle-analyzer
npm install -D webpack-bundle-analyzer
# 移除未使用的依赖
npm install -g depcheck
depcheck
故障排除
常见问题
bash
# 清理缓存
npm cache clean --force
yarn cache clean
pnpm store prune
# 删除 node_modules 重新安装
rm -rf node_modules package-lock.json
npm install
# 权限问题
sudo chown -R $(whoami) ~/.npm
# 网络问题
npm config set proxy http://proxy.company.com:8080
npm config set https-proxy http://proxy.company.com:8080
# 版本冲突
npm ls
npm dedupe
调试技巧
bash
# 详细日志
npm install --loglevel verbose
npm install --loglevel silly
# 查看安装过程
npm install --dry-run
# 检查配置
npm config list
npm doctor
最佳实践
- 版本管理:使用语义化版本控制
- 锁定文件:提交 lock 文件到版本控制
- 安全审计:定期运行安全审计
- 依赖更新:定期更新依赖包
- 脚本组织:合理组织 npm 脚本
- 环境隔离:区分开发和生产依赖
- 文档完善:编写清晰的 README 和文档
- 测试覆盖:确保包的质量
下一步
掌握包管理后,你可以继续学习: