NPM
npm 是 Node.js 附带的包管理器。它可用于安装和发布 CommonJS 和 ECMAScript 模块、jQuery 插件、可重用 JavaScript 代码(库)、基于 JavaScript 的 CLI 程序等。

查看更多相关内容
什么是 npm,它作为 JavaScript 项目的包管理器是如何工作的?npm (Node Package Manager) 是 Node.js 的默认包管理器,用于安装、管理和发布 JavaScript 包。
## 核心功能
npm 主要提供以下功能:
1. **包管理**:从 npm registry 下载和安装第三方包
2. **依赖管理**:自动处理包之间的依赖关系
3. **版本控制**:使用语义化版本管理包版本
4. **脚本执行**:通过 package.json 定义和运行项目脚本
5. **包发布**:将自定义包发布到 npm registry 供他人使用
## 工作原理
npm 的工作流程如下:
1. **初始化项目**:运行 `npm init` 创建 package.json 文件
2. **安装依赖**:运行 `npm install` 安装 package.json 中定义的依赖
3. **依赖解析**:npm 解析依赖树,确定需要安装的所有包及其版本
4. **下载安装**:从 npm registry 下载包到 node_modules 目录
5. **锁定版本**:生成 package-lock.json 记录精确的依赖版本
## package.json 结构
```json
{
"name": "my-project",
"version": "1.0.0",
"description": "项目描述",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "jest"
},
"dependencies": {
"express": "^4.18.0"
},
"devDependencies": {
"jest": "^29.0.0"
}
}
```
## 常用命令
- `npm install <package>`:安装包
- `npm install -g <package>`:全局安装包
- `npm install --save-dev <package>`:安装为开发依赖
- `npm update`:更新依赖包
- `npm uninstall <package>`:卸载包
- `npm run <script>`:运行 package.json 中定义的脚本
## 依赖类型
1. **dependencies**:生产环境依赖,应用运行时必需
2. **devDependencies**:开发环境依赖,仅在开发时需要
3. **peerDependencies**:同伴依赖,需要宿主项目提供
4. **optionalDependencies**:可选依赖,安装失败不会中断
npm 通过 package.json 和 package-lock.json 文件确保项目依赖的一致性和可重现性,是现代 JavaScript 开发生态系统的核心工具。
服务端 · 2月17日 23:29
npm 7+ 有哪些新功能?它们如何提升包管理?npm 7+ 引入了重大改进,包括并行安装、工作区支持和更好的依赖解析。了解这些新特性对于现代 JavaScript 开发至关重要。
## npm 7 主要新特性
### 1. 并行安装
npm 7 改进了依赖安装算法,支持并行下载和安装包。
**性能提升**:
- 安装速度比 npm 6 快 2-3 倍
- 更好的网络资源利用
- 减少总体安装时间
**配置并行度**:
```bash
# 设置最大并行连接数
npm config set maxsockets 50
# 设置最大网络请求并发数
npm config set network-concurrency 16
```
### 2. 工作区(Workspaces)
npm 7 原生支持 monorepo 工作区,无需额外配置。
**配置工作区**:
```json
{
"name": "my-monorepo",
"version": "1.0.0",
"private": true,
"workspaces": [
"packages/*"
],
"scripts": {
"install": "npm install -ws",
"build": "npm run build -ws",
"test": "npm test -ws"
}
}
```
**目录结构**:
```
my-monorepo/
├── package.json
├── packages/
│ ├── shared/
│ │ ├── package.json
│ │ └── index.js
│ ├── app/
│ │ ├── package.json
│ │ └── index.js
│ └── utils/
│ ├── package.json
│ └── index.js
```
**工作区命令**:
```bash
# 在所有工作区中运行命令
npm run build -ws
# 在特定工作区中运行命令
npm run build --workspace=packages/app
# 安装依赖到特定工作区
npm install lodash --workspace=packages/app
# 添加工作区依赖
npm install ../shared --workspace=packages/app
```
### 3. 改进的依赖解析
npm 7 使用更智能的依赖解析算法,减少重复安装。
**依赖提升**:
```
node_modules/
├── lodash/ # 提升到顶层
├── package-a/
├── package-b/
└── package-c/
```
**配置解析策略**:
```bash
# 禁用依赖提升
npm config set legacy-bundling true
# 使用严格的 peer 依赖解析
npm config set strict-peer-deps true
```
### 4. package-lock.json v2
npm 7 引入了新的锁文件格式,提供更好的可读性和更详细的元数据。
**新特性**:
- 更清晰的 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.0"
}
},
"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"
},
"engines": {
"node": ">= 0.10.0"
}
}
}
}
```
### 5. npm exec 和 npx 改进
npm 7 改进了 `npx` 的实现,并引入了 `npm exec` 命令。
**npm exec**:
```bash
# 执行包中的二进制文件
npm exec create-react-app my-app
# 等同于 npx
npx create-react-app my-app
# 传递参数
npm exec --package=eslint -- eslint src/
```
**改进的 npx**:
- 更快的包解析
- 更好的缓存机制
- 支持多个包
### 6. 自动安装 peer 依赖
npm 7 默认自动安装 peer 依赖,简化依赖管理。
**行为变化**:
```bash
# npm 6: 需要手动安装 peer 依赖
npm install <package>
npm install <peer-dependency>
# npm 7: 自动安装 peer 依赖
npm install <package>
```
**配置**:
```bash
# 禁用自动安装 peer 依赖
npm config set auto-install-peers false
# 使用严格的 peer 依赖解析
npm config set strict-peer-deps true
```
### 7. 改进的输出格式
npm 7 提供更清晰、更简洁的输出格式。
**示例**:
```
added 1423 packages, and audited 1424 packages in 32s
238 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
```
### 8. npm fund 命令
npm 7 引入了 `npm fund` 命令,显示项目的资金来源信息。
**使用**:
```bash
npm fund
```
**输出示例**:
```
my-project@1.0.0
├── express@4.18.2
│ └── https://opencollective.com/express
├── lodash@4.17.21
│ └── https://opencollective.com/lodash
└── webpack@5.0.0
└── https://github.com/sponsors/webpack
```
### 9. 支持 overrides
npm 8+ 支持 `overrides` 字段,强制使用特定版本的依赖。
**配置 overrides**:
```json
{
"overrides": {
"vulnerable-package": "1.2.3",
"package-a": {
"package-b": "2.0.0"
}
}
}
```
**使用场景**:
- 修复安全漏洞
- 解决版本冲突
- 强制使用特定版本
### 10. 改进的错误处理
npm 7 提供更详细的错误信息和更好的错误恢复机制。
**错误信息示例**:
```
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: my-project@1.0.0
npm ERR! Found: react@18.0.0
npm ERR! node_modules/react
npm ERR! react@"^18.0.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.0.0" from some-package@1.0.0
npm ERR! node_modules/some-package
```
## npm 8 新特性
### 1. 改进的 workspaces
npm 8 改进了工作区功能,支持更复杂的 monorepo 结构。
### 2. npm diff 命令
npm 8 引入了 `npm diff` 命令,比较依赖版本差异。
```bash
# 比较当前安装与 package.json
npm diff
# 比较特定包
npm diff <package-name>
# 比较两个版本
npm diff <package-name>@1.0.0 <package-name>@2.0.0
```
### 3. 改进的 npm query
npm 8 改进了 `npm query` 命令,支持更强大的依赖查询。
```bash
# 查找所有过期的包
npm query ":outdated"
# 查找所有开发依赖
npm query ":dev"
# 查找特定包的依赖
npm query "lodash > *"
```
### 4. 支持 .npmrc 的继承
npm 8 支持从父目录继承 `.npmrc` 配置。
## npm 9 新特性
### 1. 改进的性能
npm 9 进一步优化了性能,安装速度更快。
### 2. 改进的安全性
npm 9 增强了安全功能,包括更好的完整性验证。
### 3. 改进的错误报告
npm 9 提供更清晰的错误信息和更好的故障排除指导。
## 迁移到 npm 7+
### 1. 升级 npm
```bash
# 使用 npm 自身升级
npm install -g npm@latest
# 使用 nvm
nvm install node --latest-npm
# 使用 n
n latest
```
### 2. 检查兼容性
```bash
# 检查项目依赖
npm ls
# 检查 peer 依赖
npm ls --depth=0
```
### 3. 处理 peer 依赖
```bash
# 自动安装 peer 依赖
npm install
# 手动解决冲突
npm install --force
```
### 4. 更新 package-lock.json
```bash
# 删除旧的锁文件
rm package-lock.json
# 重新安装生成新锁文件
npm install
```
## 最佳实践
### 1. 使用工作区管理 monorepo
```json
{
"workspaces": [
"packages/*"
],
"scripts": {
"install": "npm install -ws",
"build": "npm run build -ws",
"test": "npm test -ws",
"clean": "npm run clean -ws"
}
}
```
### 2. 使用 overrides 管理版本
```json
{
"overrides": {
"vulnerable-package": "1.2.3"
}
}
```
### 3. 使用 npm ci 替代 npm install
```bash
# CI 环境使用 npm ci
npm ci
```
### 4. 配置合理的并行度
```bash
# 根据网络环境调整
npm config set maxsockets 50
npm config set network-concurrency 16
```
### 5. 使用 npm fund 支持开源项目
```bash
# 查看项目资金来源
npm fund
# 支持开源项目
npm fund <package-name>
```
## 常见问题
### 1. peer 依赖冲突
```bash
# 使用严格的 peer 依赖解析
npm config set strict-peer-deps true
# 手动解决冲突
npm install --force
```
### 2. 工作区依赖问题
```bash
# 清理工作区缓存
npm cache clean --force
# 重新安装
npm install -ws
```
### 3. 性能问题
```bash
# 检查配置
npm config list
# 调整并行度
npm config set maxsockets 50
# 使用缓存
npm install --prefer-offline
```
npm 7+ 带来了显著的性能提升和功能改进,是现代 JavaScript 开发的理想选择。
服务端 · 2月17日 23:29
NPM Link 是如何工作的?什么时候应该用它进行本地包开发?npm link 是一个强大的工具,用于在本地开发和测试 npm 包。它允许开发者在不发布包的情况下,将本地包链接到其他项目中。
## npm link 基本概念
npm link 创建两个链接:
1. **全局链接**:将本地包链接到全局 node_modules
2. **项目链接**:将全局链接链接到项目的 node_modules
## 基本用法
### 1. 链接本地包
**步骤 1**:在要链接的包目录中创建全局链接
```bash
cd /path/to/my-package
npm link
```
这会在全局 node_modules 中创建一个符号链接指向本地包。
**步骤 2**:在要使用该包的项目中链接
```bash
cd /path/to/my-project
npm link my-package
```
这会在项目的 node_modules 中创建一个符号链接指向全局链接。
### 2. 验证链接
```bash
# 查看全局链接
npm list -g --depth=0
# 查看项目中的链接
npm list my-package
# 查看链接的详细信息
ls -la node_modules/my-package
```
## 实际应用场景
### 场景 1:开发本地库
假设你正在开发一个工具库 `my-utils`:
```bash
# 1. 进入工具库目录
cd ~/projects/my-utils
# 2. 创建全局链接
npm link
# 3. 进入使用该库的项目
cd ~/projects/my-app
# 4. 链接工具库
npm link my-utils
# 5. 在代码中使用
import { formatDate } from 'my-utils';
```
### 场景 2:开发 CLI 工具
开发命令行工具时,npm link 特别有用:
```bash
# 1. 在 CLI 工具目录
cd ~/projects/my-cli
# 2. 确保 package.json 中有 bin 字段
{
"name": "my-cli",
"bin": {
"my-cli": "./bin/cli.js"
}
}
# 3. 创建全局链接
npm link
# 4. 现在可以在任何地方使用
my-cli --help
```
### 场景 3:开发 React 组件库
```bash
# 1. 在组件库目录
cd ~/projects/my-components
# 2. 创建全局链接
npm link
# 3. 在 React 应用中链接
cd ~/projects/my-react-app
npm link my-components
# 4. 使用组件
import { Button } from 'my-components';
```
## 高级用法
### 1. 链接 scoped 包
```bash
# 链接 scoped 包
cd ~/projects/@mycompany/my-package
npm link
# 在项目中链接
cd ~/projects/my-project
npm link @mycompany/my-package
```
### 2. 链接多个包
```bash
# 链接多个本地包
cd ~/projects/package-a
npm link
cd ~/projects/package-b
npm link
# 在项目中链接所有包
cd ~/projects/my-project
npm link package-a package-b
```
### 3. 解除链接
```bash
# 解除项目中的链接
cd ~/projects/my-project
npm unlink my-package
# 解除全局链接
cd ~/projects/my-package
npm unlink -g
# 或者使用 unlink 命令
npm unlink -g my-package
```
## 常见问题
### 1. 链接不生效
**问题**:链接后仍然使用旧版本
**解决方案**:
```bash
# 清除缓存
npm cache clean --force
# 重新链接
npm link
# 重启开发服务器
npm run dev
```
### 2. TypeScript 类型错误
**问题**:链接的包缺少类型定义
**解决方案**:
```bash
# 确保包中包含类型定义
cd ~/projects/my-package
npm run build
# 在项目中重新链接
cd ~/projects/my-project
npm unlink my-package
npm link my-package
```
### 3. 依赖冲突
**问题**:链接的包与项目依赖冲突
**解决方案**:
```bash
# 检查依赖
npm ls my-package
# 使用 npm link --force
npm link my-package --force
```
### 4. Windows 符号链接问题
**问题**:Windows 上符号链接需要管理员权限
**解决方案**:
```bash
# 以管理员身份运行终端
# 或启用开发者模式
# 设置 -> 更新和安全 -> 开发者模式
```
## 最佳实践
### 1. 使用 package.json 脚本
```json
{
"scripts": {
"link": "npm link",
"link:app": "npm link my-package",
"unlink": "npm unlink -g my-package"
}
}
```
### 2. 文档化链接流程
在 README 中说明如何链接本地包:
```markdown
## Local Development
To use this package locally without publishing:
```bash
# In this package directory
npm link
# In your project directory
npm link my-package
```
```
### 3. 使用 watch 模式
```bash
# 在包目录中使用 watch 模式
cd ~/projects/my-package
npm run watch
# 修改代码会自动重新编译
```
### 4. 测试链接的包
```bash
# 在项目中测试
cd ~/projects/my-project
npm test
# 手动测试功能
node -e "require('my-package').test()"
```
## 与其他工具的集成
### 1. 与 Yarn 集成
```bash
# Yarn 也支持 link
cd ~/projects/my-package
yarn link
cd ~/projects/my-project
yarn link my-package
```
### 2. 与 pnpm 集成
```bash
# pnpm 使用不同的链接机制
cd ~/projects/my-package
pnpm link --global
cd ~/projects/my-project
pnpm link --global my-package
```
### 3. 与 monorepo 集成
```bash
# 使用 workspaces 替代 npm link
cd ~/projects/my-monorepo
npm install
# workspaces 自动处理内部依赖
```
## 实际示例
### 开发一个工具函数库
**my-utils/package.json**:
```json
{
"name": "my-utils",
"version": "1.0.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"watch": "tsc --watch"
}
}
```
**my-utils/src/index.ts**:
```typescript
export function formatDate(date: Date): string {
return date.toISOString();
}
export function capitalize(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1);
}
```
**链接和使用**:
```bash
# 1. 构建包
cd ~/projects/my-utils
npm run build
npm link
# 2. 在项目中使用
cd ~/projects/my-app
npm link my-utils
# 3. 在代码中使用
import { formatDate, capitalize } from 'my-utils';
console.log(formatDate(new Date()));
console.log(capitalize('hello'));
```
## 性能考虑
### 1. 链接 vs 安装
| 特性 | npm link | npm install |
|------|----------|--------------|
| 速度 | 快(符号链接) | 慢(复制文件) |
| 磁盘空间 | 少(共享文件) | 多(独立副本) |
| 实时更新 | 是 | 否 |
| 生产环境 | 不推荐 | 推荐 |
### 2. 何时使用 npm link
- **开发阶段**:快速迭代和测试
- **本地调试**:不需要发布即可测试
- **多项目共享**:多个项目使用同一本地包
### 3. 何时避免使用 npm link
- **生产环境**:使用正式发布的版本
- **CI/CD**:使用 npm install 或 npm ci
- **性能敏感**:链接可能影响性能
## 故障排除
### 1. 检查链接状态
```bash
# 查看全局链接
npm list -g --depth=0 --link=true
# 查看项目链接
npm list --depth=0 --link=true
```
### 2. 清理损坏的链接
```bash
# 删除 node_modules
rm -rf node_modules
# 重新安装
npm install
# 重新链接
npm link my-package
```
### 3. 查看链接路径
```bash
# 查看链接的实际路径
readlink node_modules/my-package
# macOS/Linux
ls -la node_modules/my-package
# Windows
dir node_modules\my-package
```
## 替代方案
### 1. 使用 npm pack
```bash
# 打包本地包
cd ~/projects/my-package
npm pack
# 在项目中安装
cd ~/projects/my-project
npm install ../my-package/my-package-1.0.0.tgz
```
### 2. 使用私有 registry
```bash
# 发布到私有 registry
cd ~/projects/my-package
npm publish --registry=https://registry.yourcompany.com
# 在项目中安装
cd ~/projects/my-project
npm install my-package --registry=https://registry.yourcompany.com
```
### 3. 使用 workspaces
```json
{
"workspaces": [
"packages/*"
]
}
```
npm link 是本地开发和测试 npm 包的强大工具,可以显著提高开发效率。理解其工作原理和最佳实践对于高效的包开发至关重要。
服务端 · 2月17日 23:28
什么是 npm 脚本,npm 的生命周期脚本是如何工作的?npm scripts 是在 package.json 的 `scripts` 字段中定义的命令,用于自动化项目的常见任务。
## 基本语法
```json
{
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"build": "webpack --mode production",
"test": "jest",
"lint": "eslint src/"
}
}
```
## 运行脚本
使用 `npm run <script-name>` 或 `npm <script-name>`(对于 start、stop、test 等特殊命令):
```bash
npm run dev
npm start
npm test
```
## 生命周期脚本
npm 提供了特殊的生命周期脚本,在特定事件时自动执行:
### 安装相关生命周期
```json
{
"scripts": {
"preinstall": "echo 'Installing dependencies...'",
"install": "node setup.js",
"postinstall": "echo 'Dependencies installed!'",
"preuninstall": "echo 'Uninstalling...'",
"postuninstall": "echo 'Uninstalled!'"
}
}
```
执行顺序:
1. `preinstall`
2. `install`
3. `postinstall`
### 发布相关生命周期
```json
{
"scripts": {
"prepublishOnly": "npm run build && npm run test",
"prepack": "npm run build",
"postpack": "echo 'Package packed!'",
"publish": "node publish.js",
"postpublish": "echo 'Published!'"
}
}
```
执行顺序:
1. `prepublishOnly`
2. `prepack`
3. `prepare`
4. `postpack`
5. `publish`
6. `postpublish`
### 其他生命周期
```json
{
"scripts": {
"prestart": "npm run build",
"start": "node index.js",
"poststart": "echo 'Server started!'",
"pretest": "npm run lint",
"test": "jest",
"posttest": "npm run coverage"
}
}
```
## 脚本参数传递
可以向脚本传递参数:
```json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
}
}
```
运行时传递额外参数:
```bash
npm run test -- --verbose
```
`--` 后面的参数会传递给脚本命令。
## 环境变量
npm scripts 可以访问 npm 提供的环境变量:
```json
{
"scripts": {
"build": "webpack --env.NODE_ENV=$npm_package_config_env",
"start": "node $npm_package_main"
}
}
```
常用环境变量:
- `npm_package_name`:包名
- `npm_package_version`:包版本
- `npm_package_main`:主入口文件
- `npm_package_scripts_*`:其他脚本
- `npm_config_*`:npm 配置
- `npm_lifecycle_event`:当前生命周期事件名
## 跨平台兼容性
npm scripts 在不同操作系统上的兼容性处理:
### 使用 cross-env
```json
{
"scripts": {
"build": "cross-env NODE_ENV=production webpack"
}
}
```
### 使用 rimraf(跨平台删除)
```json
{
"scripts": {
"clean": "rimraf dist"
}
}
```
## 常见脚本模式
### 开发环境脚本
```json
{
"scripts": {
"dev": "nodemon index.js",
"dev:debug": "nodemon --inspect index.js",
"dev:hot": "webpack serve --hot"
}
}
```
### 构建脚本
```json
{
"scripts": {
"build": "webpack --mode production",
"build:dev": "webpack --mode development",
"build:analyze": "webpack --mode production --analyze"
}
}
```
### 测试脚本
```json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:ci": "jest --ci --coverage --maxWorkers=2"
}
}
```
### 代码质量脚本
```json
{
"scripts": {
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
"format": "prettier --write \"src/**/*.js\"",
"typecheck": "tsc --noEmit"
}
}
```
### Git 钩子脚本(使用 husky)
```json
{
"scripts": {
"prepare": "husky install",
"precommit": "lint-staged"
}
}
```
## 并行和顺序执行
使用 `&` 并行执行,使用 `&&` 顺序执行:
```json
{
"scripts": {
"parallel": "npm run lint & npm run test",
"sequential": "npm run lint && npm run test",
"all": "npm run lint && npm run test && npm run build"
}
}
```
使用 npm-run-all 工具更灵活:
```json
{
"scripts": {
"dev": "npm-run-all --parallel dev:*",
"dev:server": "nodemon index.js",
"dev:client": "webpack serve"
}
}
```
## 最佳实践
1. **命名规范**:使用冒号分隔相关脚本(如 `test:watch`)
2. **文档化**:在 README 中说明自定义脚本的作用
3. **错误处理**:确保脚本在失败时返回非零退出码
4. **性能优化**:避免不必要的重复操作
5. **环境隔离**:使用环境变量管理不同环境配置
6. **依赖管理**:将开发工具作为 devDependencies
## 调试技巧
### 查看脚本执行详情
```bash
npm run <script> -- --verbose
```
### 查看实际执行的命令
```bash
npm run <script> -n
```
### 使用 npm link 调试本地包
```bash
npm link ../my-local-package
```
npm scripts 是项目自动化的核心,合理使用可以显著提高开发效率和项目可维护性。
服务端 · 2月17日 23:28
NPM是如何处理版本管理的?不同的版本范围符号有哪些?npm 使用语义化版本控制(Semantic Versioning,简称 SemVer)来管理包的版本,格式为 `MAJOR.MINOR.PATCH`。
## 版本号格式
- **MAJOR(主版本号)**:当做了不兼容的 API 修改时递增
- **MINOR(次版本号)**:当做了向下兼容的功能性新增时递增
- **PATCH(修订号)**:当做了向下兼容的问题修正时递增
示例:`1.2.3`
- 1 = 主版本号
- 2 = 次版本号
- 3 = 修订号
## 版本范围符号
npm 支持多种版本范围符号来指定依赖版本:
### 1. 精确版本
```
"express": "4.18.0"
```
只安装精确的 4.18.0 版本
### 2. 波浪号(~)
```
"express": "~4.18.0"
```
等价于 `>=4.18.0 <4.19.0`
允许修订号更新,但主版本和次版本不变
### 3. 插入符(^)
```
"express": "^4.18.0"
```
等价于 `>=4.18.0 <5.0.0`
允许次版本和修订号更新,但主版本不变(默认行为)
### 4. 大于/小于
```
"express": ">4.0.0"
"express": "<5.0.0"
"express": ">=4.18.0 <5.0.0"
```
### 5. 连字符范围
```
"express": "4.16.0 - 4.18.0"
```
包含 4.16.0 到 4.18.0 之间的所有版本
### 6. 或符号(||)
```
"express": "^4.0.0 || ^5.0.0"
```
匹配任意一个满足条件的版本
### 7. 通配符(*)
```
"express": "4.*"
"express": "*"
```
匹配任意版本
### 8. 最新版本
```
"express": "latest"
"express": "next"
```
安装最新发布版本或下一个预发布版本
## 预发布版本
预发布版本使用连字符和标识符:
```
"express": "5.0.0-beta.1"
"express": "5.0.0-rc.1"
"express": "5.0.0-alpha.3"
```
常见预发布标识符:
- `alpha`:内部测试版本
- `beta`:公开测试版本
- `rc`(Release Candidate):候选发布版本
## package-lock.json 的作用
package-lock.json 文件记录了每个依赖包的确切版本和依赖树结构:
```json
{
"name": "my-project",
"version": "1.0.0",
"lockfileVersion": 2,
"packages": {
"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"
}
}
}
}
```
**作用**:
1. 确保团队成员安装相同版本的依赖
2. 提高安装速度(直接使用锁定版本)
3. 防止依赖漂移导致的意外问题
4. 记录依赖的完整性校验信息
## 版本管理最佳实践
1. **生产环境使用精确版本**:确保稳定性
2. **开发环境使用范围版本**:便于获取更新
3. **提交 package-lock.json**:确保团队一致性
4. **定期更新依赖**:`npm outdated` 查看过期包
5. **使用 npm audit**:检查安全漏洞
6. **理解破坏性更新**:主版本升级前查看变更日志
## 常用版本管理命令
```bash
# 查看当前安装的版本
npm list
# 查看包的最新版本
npm view <package> version
# 查看包的所有版本
npm view <package> versions
# 检查过期的包
npm outdated
# 更新包(遵循 package.json 中的范围)
npm update
# 更新到最新主版本
npm install <package>@latest
# 检查安全漏洞
npm audit
# 自动修复安全漏洞
npm audit fix
```
理解 npm 版本管理对于维护项目稳定性和安全性至关重要,特别是在团队协作和长期维护的项目中。
服务端 · 2月17日 23:27
如何发布 npm 包并配置私有注册库?npm 允许开发者将自定义包发布到 npm registry,供他人使用。同时,企业可以使用私有 registry 管理内部包。
## 发布 npm 包
### 1. 准备工作
**注册 npm 账号**:
```bash
npm adduser
# 或
npm login
```
**验证登录**:
```bash
npm whoami
```
### 2. package.json 配置
确保 package.json 包含必要字段:
```json
{
"name": "my-awesome-package",
"version": "1.0.0",
"description": "An awesome npm package",
"main": "index.js",
"keywords": ["awesome", "package"],
"author": "Your Name <email@example.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/username/my-awesome-package.git"
},
"homepage": "https://github.com/username/my-awesome-package#readme",
"bugs": {
"url": "https://github.com/username/my-awesome-package/issues"
},
"files": [
"dist",
"README.md",
"LICENSE"
],
"scripts": {
"prepublishOnly": "npm run build && npm run test",
"build": "tsc",
"test": "jest"
}
}
```
**重要字段说明**:
- `name`:包名,必须唯一(在公开 registry)
- `version`:遵循语义化版本
- `private`:设置为 `false` 或删除该字段才能发布
- `files`:指定要包含在发布包中的文件
### 3. 发布流程
**构建和测试**:
```bash
npm run build
npm test
```
**预发布检查**:
```bash
npm pack
```
这会生成 `.tgz` 文件,可以检查将要发布的内容。
**发布到公开 registry**:
```bash
npm publish
```
**发布特定标签**:
```bash
npm publish --tag beta
```
**发布到私有 scope**:
```bash
npm publish --access public
```
### 4. 版本管理
**更新版本**:
```bash
# 补丁版本 (1.0.0 -> 1.0.1)
npm version patch
# 次版本 (1.0.0 -> 1.1.0)
npm version minor
# 主版本 (1.0.0 -> 2.0.0)
npm version major
# 预发布版本
npm version prerelease --preid beta
```
**发布新版本**:
```bash
git push --follow-tags
npm publish
```
## 私有 Registry
### 1. 配置私有 Registry
**设置全局 registry**:
```bash
npm config set registry https://registry.yourcompany.com
```
**设置项目级 registry**:
在项目根目录创建 `.npmrc`:
```
registry=https://registry.yourcompany.com
```
### 2. 使用 Scoped Packages
**创建 scoped 包**:
```json
{
"name": "@yourcompany/package-name"
}
```
**配置 scope registry**:
```bash
npm config set @yourcompany:registry https://registry.yourcompany.com
```
**在 .npmrc 中配置**:
```
@yourcompany:registry=https://registry.yourcompany.com
```
### 3. 认证配置
**使用 token 认证**:
```bash
npm config set //registry.yourcompany.com/:_authToken YOUR_TOKEN
```
**在 .npmrc 中配置**:
```
//registry.yourcompany.com/:_authToken=${NPM_TOKEN}
```
**使用环境变量**:
```bash
export NPM_TOKEN=your_token_here
```
### 4. 发布到私有 registry
**发布 scoped 包**:
```bash
npm publish
```
**发布为公开包(在私有 registry)**:
```bash
npm publish --access public
```
## 常用发布命令
```bash
# 检查包名是否可用
npm view <package-name>
# 查看包信息
npm info <package-name>
# 查看包的所有版本
npm view <package-name> versions
# 查看包的依赖
npm view <package-name> dependencies
# 取消发布(谨慎使用)
npm unpublish <package-name>@<version>
# 废弃包版本
npm deprecate <package-name>@<version> "This version is deprecated"
# 搜索包
npm search <keyword>
# 查看当前 registry
npm config get registry
# 查看 npm 配置
npm config list
```
## .npmignore 文件
`.npmignore` 文件用于指定发布时要忽略的文件:
```
# 源代码
src/
test/
*.ts
*.spec.js
# 开发配置
.eslintrc
.prettierrc
jest.config.js
tsconfig.json
# 文档
docs/
*.md
!README.md
# CI/CD
.github/
.gitlab-ci.yml
# IDE
.vscode/
.idea/
```
**注意**:`.npmignore` 会覆盖 `files` 字段。
## 最佳实践
### 1. 版本管理
- 遵循语义化版本规范
- 在发布前运行完整测试
- 使用 `prepublishOnly` 脚本确保质量
- 维护 CHANGELOG.md 记录变更
### 2. 包结构
```
my-package/
├── package.json
├── README.md
├── LICENSE
├── .npmignore
├── src/
│ └── index.ts
├── dist/
│ ├── index.js
│ └── index.d.ts
└── test/
└── index.test.js
```
### 3. 文档
- 提供清晰的 README.md
- 包含安装和使用示例
- 说明 API 和配置选项
- 提供贡献指南
### 4. 安全性
- 不要在包中包含敏感信息
- 使用 `npm audit` 检查安全漏洞
- 定期更新依赖
- 使用 `.npmignore` 排除敏感文件
### 5. 持续集成
```yaml
# .github/workflows/publish.yml
name: Publish Package
on:
push:
tags:
- 'v*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm test
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
```
## 常见问题
### 1. 包名冲突
如果包名已被占用,考虑:
- 使用 scoped 包:`@username/package-name`
- 选择不同的名称
- 联系包的所有者
### 2. 发布失败
常见原因:
- 包名已被占用
- 缺少必要字段
- 版本号未更新
- 认证失败
### 3. 取消发布限制
npm 限制取消发布:
- 只能取消发布 72 小时内的版本
- 不能取消发布超过 24 小时的主要版本
- 使用 `deprecate` 替代 `unpublish`
## 企业级解决方案
### 1. Verdaccio
轻量级私有 npm registry:
```bash
npm install -g verdaccio
verdaccio
```
### 2. Artifactory
企业级制品仓库,支持多种包管理器。
### 3. Nexus Repository
另一个流行的企业级制品仓库解决方案。
### 4. GitHub Packages
使用 GitHub 作为私有 registry:
```bash
npm config set registry https://npm.pkg.github.com
npm login --scope=@your-username --registry=https://npm.pkg.github.com
```
掌握 npm 发布和私有 registry 配置对于团队协作和企业级项目管理至关重要。
服务端 · 2月17日 23:27
npm 和 Yarn 的区别,以及如何选择npm 和 Yarn 是两个最流行的 JavaScript 包管理器,各有优缺点。了解它们的区别和选择合适的工具对于项目开发很重要。
## 基本介绍
### npm
- **发布时间**:2010 年
- **开发者**:Isaac Z. Schlueter
- **维护者**:npm, Inc.(现属 GitHub)
- **默认安装**:随 Node.js 一起安装
### Yarn
- **发布时间**:2016 年
- **开发者**:Facebook、Google、Exponent 和 Tilde
- **维护者**:Open Collective 社区
- **安装方式**:需要单独安装
## 核心区别
### 1. 安装速度
**npm**:
- 早期版本串行安装依赖
- npm 7+ 引入并行安装,速度显著提升
- 使用缓存机制加速重复安装
**Yarn**:
- 从一开始就支持并行安装
- 通常比 npm 6 及更早版本快
- 与 npm 7+ 速度相当
```bash
# npm 安装
npm install
# Yarn 安装
yarn install
```
### 2. 锁文件
**npm**:
- 使用 `package-lock.json`
- npm 5+ 自动生成
- 记录精确的依赖版本和树结构
**Yarn**:
- 使用 `yarn.lock`
- 自动生成
- 更详细的锁文件格式
**示例**:
```json
// package-lock.json
{
"name": "my-project",
"lockfileVersion": 2,
"packages": {
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-..."
}
}
}
```
```yaml
# yarn.lock
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#..."
integrity sha512-...
```
### 3. 命令差异
| 功能 | npm | Yarn |
|------|-----|------|
| 安装依赖 | `npm install` | `yarn install` |
| 添加依赖 | `npm install <pkg>` | `yarn add <pkg>` |
| 添加开发依赖 | `npm install <pkg> -D` | `yarn add <pkg> -D` |
| 全局安装 | `npm install -g <pkg>` | `yarn global add <pkg>` |
| 更新依赖 | `npm update` | `yarn upgrade` |
| 删除依赖 | `npm uninstall <pkg>` | `yarn remove <pkg>` |
| 运行脚本 | `npm run <script>` | `yarn run <script>` 或 `yarn <script>` |
| 查看信息 | `npm info <pkg>` | `yarn info <pkg>` |
### 4. 工作区(Workspaces)
**npm**:
- npm 7+ 原生支持工作区
- 配置简单,与 package.json 集成
```json
{
"name": "my-monorepo",
"workspaces": [
"packages/*"
]
}
```
**Yarn**:
- Yarn 1+ 支持工作区
- 更成熟的工作区功能
- 支持 Yarn Plug'n'Play(PnP)
```json
{
"name": "my-monorepo",
"private": true,
"workspaces": {
"packages": [
"packages/*"
]
}
}
```
### 5. 离线模式
**npm**:
```bash
npm install --offline
npm install --prefer-offline
```
**Yarn**:
```bash
yarn install --offline
yarn install --prefer-offline
```
Yarn 的离线模式更成熟,缓存管理更好。
### 6. 输出格式
**npm**:
- 输出较详细
- 显示安装进度和警告
**Yarn**:
- 输出更简洁
- 使用 emoji 和颜色
- 更好的用户体验
### 7. 安全性
**npm**:
- `npm audit` 内置安全审计
- npm 8+ 支持 `overrides` 强制版本
- 与 npm registry 集成良好
**Yarn**:
- `yarn audit` 安全审计
- 支持 `resolutions` 强制版本
- 更严格的依赖解析
### 8. 插件和扩展
**npm**:
- 插件系统相对简单
- 通过 npm scripts 扩展功能
**Yarn**:
- 丰富的插件生态系统
- 支持 Yarn 2+ 的插件系统
- 更灵活的自定义选项
## 性能对比
### 安装速度测试
```
大型项目(1000+ 依赖):
- npm 6: ~120s
- npm 7+: ~60s
- Yarn 1: ~45s
- Yarn 2+: ~40s
中型项目(100-500 依赖):
- npm 6: ~30s
- npm 7+: ~15s
- Yarn 1: ~12s
- Yarn 2+: ~10s
```
### 磁盘空间
```
node_modules 大小:
- npm: 标准嵌套结构
- Yarn 1: 标准嵌套结构
- Yarn 2+ (PnP): 无 node_modules,显著减少空间
```
## 选择建议
### 选择 npm 的场景
1. **新项目**:npm 7+ 性能已足够好
2. **简单项目**:不需要复杂的工作区功能
3. **团队熟悉**:团队已经熟悉 npm
4. **CI/CD**:大多数 CI 环境默认支持 npm
5. **发布包**:npm 发布流程更简单
### 选择 Yarn 的场景
1. **大型 monorepo**:Yarn 工作区更成熟
2. **需要离线支持**:Yarn 离线模式更好
3. **性能敏感**:Yarn 通常更快
4. **需要 PnP**:Yarn 2+ 的 Plug'n'Play 功能
5. **团队偏好**:团队更喜欢 Yarn 的用户体验
## 迁移指南
### 从 npm 迁移到 Yarn
```bash
# 安装 Yarn
npm install -g yarn
# 在项目目录运行
yarn install
# Yarn 会自动读取 package.json 并生成 yarn.lock
```
### 从 Yarn 迁移到 npm
```bash
# 删除 yarn.lock
rm yarn.lock
# 运行 npm install
npm install
# npm 会生成 package-lock.json
```
## 高级功能对比
### 1. 依赖解析策略
**npm**:
- 嵌套依赖结构
- npm 7+ 使用更智能的解析算法
- 支持依赖提升
**Yarn**:
- 更严格的依赖解析
- Yarn 2+ 支持零安装(PnP)
- 更好的依赖去重
### 2. 缓存机制
**npm**:
```bash
npm cache verify
npm cache clean --force
```
**Yarn**:
```bash
yarn cache list
yarn cache clean
```
Yarn 的缓存管理更精细。
### 3. 版本管理
**npm**:
```bash
npm version major
npm version minor
npm version patch
```
**Yarn**:
```bash
yarn version --major
yarn version --minor
yarn version --patch
```
### 4. 全局包管理
**npm**:
```bash
npm list -g --depth=0
npm uninstall -g <pkg>
```
**Yarn**:
```bash
yarn global list
yarn global remove <pkg>
```
## 配置文件
### .npmrc
```ini
# npm 配置
registry=https://registry.npmjs.org
cache=/path/to/cache
strict-ssl=true
```
### .yarnrc.yml
```yaml
# Yarn 2+ 配置
nodeLinker: node-modules
enableGlobalCache: true
npmRegistryServer: "https://registry.npmjs.org"
```
## 最佳实践
### 1. 锁文件管理
- 始终提交锁文件到版本控制
- 不要手动编辑锁文件
- 定期更新依赖
### 2. 版本范围
```json
{
"dependencies": {
// 生产环境使用精确版本
"critical-package": "1.2.3",
// 开发环境可以使用范围版本
"dev-package": "^1.2.3"
}
}
```
### 3. 安全审计
```bash
# npm
npm audit
npm audit fix
# Yarn
yarn audit
yarn audit --json
```
### 4. CI/CD 优化
```yaml
# GitHub Actions - npm
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
# GitHub Actions - Yarn
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'yarn'
```
## 未来趋势
- **npm**:持续改进性能和安全性
- **Yarn**:推动 PnP 和零安装概念
- **pnpm**:新兴的包管理器,使用硬链接节省空间
- **Bun**:新一代 JavaScript 运行时,内置包管理器
选择 npm 还是 Yarn 主要取决于项目需求、团队偏好和具体场景。两者都是优秀的包管理器,各有优势。
服务端 · 2月17日 23:26
npm audit 是如何工作的?npm 安全的最佳实践有哪些? - npm 提供了内置的安全审计功能来检测和修复项目依赖中的安全漏洞。了解 npm 安全机制对于维护应用程序安全至关重要。
## npm audit 命令
### 基本用法
```bash
# 扫描项目依赖中的安全漏洞
npm audit
# 显示审计结果的 JSON 格式
npm audit --json
# 只显示生产依赖的漏洞
npm audit --production
```
### 审计报告示例
```
found 3 vulnerabilities (2 moderate, 1 high)
┌───────────────┬──────────────────────────────────────┐
│ Low │ Prototype Pollution │
├───────────────┼──────────────────────────────────────┤
│ Moderate │ Regular Expression Denial of Service │
├───────────────┼──────────────────────────────────────┤
│ High │ Command Injection │
└───────────────┴──────────────────────────────────────┘
```
## 漏洞严重级别
npm 将漏洞分为以下严重级别:
1. **Low(低)**:影响有限,需要特定条件
2. **Moderate(中)**:有一定影响,需要用户交互
3. **High(高)**:严重影响,可能导致数据泄露
4. **Critical(严重)**:极高影响,可能导致系统完全被控制
## 自动修复漏洞
### npm audit fix
```bash
# 自动修复可修复的漏洞
npm audit fix
# 只修复生产依赖的漏洞
npm audit fix --production
# 强制修复(可能引入破坏性更改)
npm audit fix --force
```
### 修复策略
`npm audit fix` 会:
1. 识别可以安全更新的依赖
2. 更新到修复了漏洞的版本
3. 更新 package-lock.json
4. 报告无法自动修复的漏洞
## 手动修复漏洞
### 1. 更新特定包
```bash
# 更新到最新版本
npm update <package-name>
# 安装特定版本
npm install <package-name>@<version>
```
### 2. 使用 overrides(npm 8+)
在 package.json 中使用 overrides 强制使用特定版本:
```json
{
"overrides": {
"vulnerable-package": "1.2.3"
}
}
```
### 3. 使用 resolutions(Yarn)
如果使用 Yarn,可以使用 resolutions:
```json
{
"resolutions": {
"vulnerable-package": "1.2.3"
}
}
```
## npm audit 配置
### 配置审计级别
```bash
# 设置审计级别(默认为 low)
npm config set audit-level moderate
# 可选值:low, moderate, high, critical
```
### 禁用审计
```bash
# 全局禁用审计
npm config set audit false
# 安装时跳过审计
npm install --no-audit
```
## 安全最佳实践
### 1. 定期审计
```bash
# 在 CI/CD 流程中添加审计
npm audit
```
### 2. 锁定依赖版本
```json
{
"dependencies": {
"package": "1.2.3"
}
}
```
使用精确版本而不是范围版本。
### 3. 提交 package-lock.json
确保团队使用相同的依赖版本。
### 4. 使用 .npmrc 配置
```ini
# .npmrc
audit=true
audit-level=moderate
```
### 5. 监控依赖更新
```bash
# 查看过期的包
npm outdated
# 查看包的安全公告
npm view <package> security-advisories
```
## CI/CD 集成
### GitHub Actions 示例
```yaml
name: Security Audit
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 0' # 每周运行
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Run security audit
run: npm audit
- name: Attempt to fix vulnerabilities
run: npm audit fix
continue-on-error: true
- name: Check for remaining vulnerabilities
run: |
if [ $(npm audit --json | jq '.metadata.vulnerabilities.high + .metadata.vulnerabilities.critical') -gt 0 ]; then
echo "High or critical vulnerabilities found!"
exit 1
fi
```
### 使用第三方工具
```bash
# 使用 Snyk
npm install -g snyk
snyk test
# 使用 npm-check-updates
npm install -g npm-check-updates
ncu -u
```
## 供应链安全
### 1. 验证包完整性
npm 使用 SHA-512 校验和验证包完整性:
```json
{
"integrity": "sha512-..."
}
```
### 2. 使用 npm provenance
npm provenance 提供包的来源验证:
```bash
npm publish --provenance
```
### 3. 检查包维护者
```bash
# 查看包的维护者
npm view <package> maintainers
# 查看包的发布历史
npm view <package> time
```
## 常见安全问题
### 1. 依赖混淆攻击
攻击者发布与内部包同名的恶意包。
**预防措施**:
- 使用 scoped 包:`@company/package`
- 配置私有 registry
- 审查新安装的包
### 2. Typosquatting 攻击
攻击者发布拼写错误的包名。
**预防措施**:
- 仔细检查包名
- 使用官方 registry
- 审查包的下载量和维护者
### 3. 恶意代码注入
攻击者在包中注入恶意代码。
**预防措施**:
- 审查包的源代码
- 使用 `npm audit` 定期检查
- 限制包的权限
## 安全工具
### 1. npm audit
内置的安全审计工具。
### 2. Snyk
提供更全面的安全扫描:
```bash
npm install -g snyk
snyk auth
snyk test
```
### 3. Dependabot
GitHub 的依赖更新和安全警报工具。
### 4. WhiteSource
企业级开源安全管理平台。
### 5. OWASP Dependency-Check
扫描项目依赖中的已知漏洞。
## .npmignore 和安全性
确保不将敏感信息发布到 npm:
```
# .npmignore
.env
*.key
*.pem
secrets/
config/production.json
```
## 许可证合规
检查依赖的许可证:
```bash
# 使用 license-checker
npm install -g license-checker
license-checker
# 使用 npm-license-crawler
npm install -g npm-license-crawler
npm-license-crawler
```
## 安全配置示例
### package.json
```json
{
"name": "my-secure-app",
"version": "1.0.0",
"engines": {
"node": ">=16.0.0",
"npm": ">=8.0.0"
},
"scripts": {
"audit": "npm audit",
"audit:fix": "npm audit fix",
"check-licenses": "license-checker"
},
"dependencies": {
"express": "^4.18.0"
},
"overrides": {
"vulnerable-package": "1.2.3"
}
}
```
### .npmrc
```ini
# 安全配置
audit=true
audit-level=moderate
fetch-retries=3
fetch-retry-mintimeout=20000
fetch-retry-maxtimeout=120000
strict-ssl=true
```
## 常见问题解决
### 1. 无法自动修复的漏洞
```bash
# 手动查找替代包
npm search <package-name>
# 联系包维护者
npm view <package> author
```
### 2. 依赖冲突
```bash
# 使用 overrides 解决冲突
npm install --force
```
### 3. 误报
```bash
# 查看漏洞详情
npm audit --json
# 查看包的安全公告
npm view <package> security-advisories
```
npm 安全审计是保护应用程序免受已知漏洞攻击的重要工具。定期审计和及时更新依赖是维护安全性的关键。
服务端 · 2月17日 23:25
最重要的 npm 命令及其高效使用方法有哪些?npm 提供了多种命令来管理包和项目,掌握这些命令对于高效的 JavaScript 开发至关重要。
## 包管理命令
### 安装包
```bash
# 安装最新版本
npm install <package>
# 安装特定版本
npm install <package>@<version>
# 安装多个包
npm install <package1> <package2> <package3>
# 安装为生产依赖
npm install <package> --save-prod
npm install <package> -P
# 安装为开发依赖
npm install <package> --save-dev
npm install <package> -D
# 安装为可选依赖
npm install <package> --save-optional
npm install <package> -O
# 安装为同伴依赖
npm install <package> --save-peer
# 全局安装
npm install <package> --global
npm install <package> -g
# 精确安装版本
npm install <package> --save-exact
npm install <package> -E
# 强制重新安装
npm install <package> --force
```
### 更新包
```bash
# 更新所有包(遵循 package.json 中的范围)
npm update
# 更新特定包
npm update <package>
# 更新到最新主版本
npm update <package> --latest
# 检查过期的包
npm outdated
# 检查特定包是否过期
npm outdated <package>
```
### 卸载包
```bash
# 卸载包
npm uninstall <package>
# 卸载多个包
npm uninstall <package1> <package2>
# 卸载全局包
npm uninstall <package> --global
npm uninstall <package> -g
# 卸载并从 package.json 中移除
npm uninstall <package> --save
# 卸载开发依赖
npm uninstall <package> --save-dev
```
## 信息查询命令
### 查看包信息
```bash
# 查看包的基本信息
npm info <package>
# 查看包的特定字段
npm info <package> version
npm info <package> description
npm info <package> author
npm info <package> homepage
# 查看包的所有版本
npm info <package> versions
# 查看包的依赖
npm info <package> dependencies
# 查看包的开发依赖
npm info <package> devDependencies
# 查看包的同伴依赖
npm info <package> peerDependencies
# 查看包的发布时间
npm info <package> time
# 查看包的下载量
npm info <package> downloads
# 查看包的维护者
npm info <package> maintainers
# 查看包的关键词
npm info <package> keywords
```
### 查看已安装的包
```bash
# 查看所有已安装的包
npm list
# 查看顶级依赖
npm list --depth=0
# 查看特定包
npm list <package>
# 查看全局安装的包
npm list --global
# 查看全局顶级依赖
npm list --global --depth=0
# 以 JSON 格式输出
npm list --json
# 只显示生产依赖
npm list --production
# 只显示开发依赖
npm list --dev
# 显示包的大小
npm list --long
```
### 搜索包
```bash
# 搜索包
npm search <keyword>
# 搜索并限制结果数量
npm search <keyword> --long
# 以 JSON 格式搜索
npm search <keyword> --json
# 搜索特定维护者的包
npm search <keyword> --author <author>
# 搜索特定关键词的包
npm search <keyword> --keywords <keywords>
```
## 项目管理命令
### 初始化项目
```bash
# 初始化新项目(交互式)
npm init
# 使用默认值初始化
npm init -y
npm init --yes
# 使用特定配置初始化
npm init --scope=@mycompany
# 创建特定类型的包
npm init react-app my-app
npm init vue-app my-app
```
### 运行脚本
```bash
# 运行脚本
npm run <script>
# 运行 start 脚本(简写)
npm start
# 运行 stop 脚本(简写)
npm stop
# 运行 test 脚本(简写)
npm test
# 运行 restart 脚本(简写)
npm restart
# 列出所有脚本
npm run
# 传递参数给脚本
npm run <script> -- --arg1 --arg2
# 以静默模式运行
npm run <script> --silent
npm run <script> -s
```
### 版本管理
```bash
# 更新补丁版本(1.0.0 -> 1.0.1)
npm version patch
# 更新次版本(1.0.0 -> 1.1.0)
npm version minor
# 更新主版本(1.0.0 -> 2.0.0)
npm version major
# 更新预发布版本
npm version prerelease
npm version prerelease --preid beta
npm version prerelease --preid alpha
# 更新到特定版本
npm version 1.2.3
# 创建 Git 标签
npm version patch -m "Bump to version %s"
# 不创建 Git 标签
npm version patch --no-git-tag-version
```
## 发布命令
### 发布包
```bash
# 发布包
npm publish
# 发布特定标签
npm publish --tag beta
npm publish --tag next
# 发布为公开包(scoped 包)
npm publish --access public
# 发布为受限包(scoped 包)
npm publish --access restricted
# 发布特定目录
npm publish <directory>
# 发布前运行测试
npm publish --dry-run
# 发布并附带 provenance
npm publish --provenance
```
### 取消发布
```bash
# 取消发布特定版本
npm unpublish <package>@<version>
# 取消发布整个包(谨慎使用)
npm unpublish <package>
# 强制取消发布
npm unpublish <package>@<version> --force
```
### 废弃版本
```bash
# 废弃特定版本
npm deprecate <package>@<version> "This version is deprecated"
# 废弃所有版本
npm deprecate <package> "This package is deprecated"
```
## 配置命令
### 查看配置
```bash
# 查看所有配置
npm config list
# 查看特定配置
npm config get <key>
# 查看用户配置
npm config list --user
# 查看全局配置
npm config list --global
# 查看项目配置
npm config list --project
# 编辑配置文件
npm config edit
# 查看配置文件位置
npm config get userconfig
npm config get globalconfig
```
### 设置配置
```bash
# 设置配置
npm config set <key> <value>
# 设置全局配置
npm config set <key> <value> --global
# 删除配置
npm config delete <key>
# 删除全局配置
npm config delete <key> --global
```
### 常用配置
```bash
# 设置 registry
npm config set registry https://registry.npmmirror.com
# 设置缓存目录
npm config set cache /path/to/cache
# 设置前缀
npm config set prefix /usr/local
# 设置日志级别
npm config set loglevel info
# 设置代理
npm config set https-proxy http://proxy.example.com:8080
# 设置严格 SSL
npm config set strict-ssl true
# 设置保存前缀
npm config set save-prefix ^
# 设置精确保存
npm config set save-exact true
```
## 缓存命令
### 管理缓存
```bash
# 验证缓存
npm cache verify
# 清理缓存
npm cache clean
# 强制清理缓存
npm cache clean --force
# 添加到缓存
npm cache add <package>@<version>
# 查看缓存目录
npm config get cache
```
## 安全命令
### 安全审计
```bash
# 运行安全审计
npm audit
# 显示审计结果的 JSON 格式
npm audit --json
# 只审计生产依赖
npm audit --production
# 只审计开发依赖
npm audit --dev
# 自动修复漏洞
npm audit fix
# 强制修复漏洞
npm audit fix --force
# 只修复生产依赖的漏洞
npm audit fix --production
# 显示漏洞详情
npm audit --audit-level=low
npm audit --audit-level=moderate
npm audit --audit-level=high
npm audit --audit-level=critical
```
## 高级命令
### 工作区命令
```bash
# 在所有工作区中运行命令
npm run <script> -ws
npm run <script> --workspaces
# 在特定工作区中运行命令
npm run <script> --workspace=<workspace>
# 安装到所有工作区
npm install -ws
# 添加到特定工作区
npm add <package> --workspace=<workspace>
```
### 执行命令
```bash
# 执行包中的二进制文件
npm exec <package>
# 执行特定包
npm exec --package=<package> <command>
# 等同于 npx
npx <package>
# 执行并传递参数
npx <package> --arg1 --arg2
# 使用特定版本
npx <package>@<version>
# 忽略本地安装
npx --ignore-existing <package>
# 使用缓存
npx --yes <package>
npx -y <package>
```
### 查询命令
```bash
# 查询依赖
npm query ":root"
# 查询所有过期的包
npm query ":outdated"
# 查询所有开发依赖
npm query ":dev"
# 查询特定包的依赖
npm query "lodash > *"
# 查询特定路径的包
npm query "#./packages/*"
```
### 差异命令
```bash
# 比较当前安装与 package.json
npm diff
# 比较特定包
npm diff <package>
# 比较两个版本
npm diff <package>@1.0.0 <package>@2.0.0
# 比较与 git 的差异
npm diff --git
```
## 其他有用命令
### 资金命令
```bash
# 查看项目的资金来源
npm fund
# 查看特定包的资金来源
npm fund <package>
# 打开资金链接
npm fund --which=<package>
```
### 组织命令
```bash
# 创建组织
npm org create <organization>
# 添加成员
npm org add <user> <organization>
# 移除成员
npm org rm <user> <organization>
# 列出成员
npm org ls <organization>
# 设置角色
npm org set <user> <role> <organization>
```
### 访问命令
```bash
# 设置包访问权限
npm access public <package>
# 设置包为受限访问
npm access restricted <package>
# 添加包的协作者
npm access add <user> <package>
# 移除包的协作者
npm access rm <user> <package>
# 列出包的协作者
npm access ls <package>
# 查看包的访问权限
npm access status <package>
```
### 登录和注销
```bash
# 登录
npm login
npm adduser
# 注销
npm logout
# 查看当前用户
npm whoami
# 查看用户信息
npm profile get
# 更新用户信息
npm profile set <key> <value>
# 更改密码
npm profile set password
```
### 团队命令
```bash
# 创建团队
npm team create <team> <organization>
# 添加成员到团队
npm team add <user> <team>
# 从团队移除成员
npm team rm <user> <team>
# 列出团队成员
npm team ls <team>
# 删除团队
npm team destroy <team>
```
## 最佳实践
### 1. 使用 npm ci 替代 npm install
```bash
# CI 环境使用 npm ci
npm ci
```
### 2. 使用精确版本
```bash
# 生产环境使用精确版本
npm install <package> --save-exact
```
### 3. 定期更新依赖
```bash
# 检查过期包
npm outdated
# 更新包
npm update
```
### 4. 定期运行安全审计
```bash
# 运行安全审计
npm audit
# 修复漏洞
npm audit fix
```
### 5. 使用 .npmrc 配置
```bash
# 项目级配置
echo "registry=https://registry.npmmirror.com" > .npmrc
```
掌握这些 npm 命令可以显著提高开发效率和项目管理能力。
服务端 · 2月17日 23:24
npm 缓存机制是怎样的?如何优化依赖安装速度?npm 提供了多种缓存机制来加速包的安装和减少网络请求。理解缓存机制对于优化构建性能和解决安装问题非常重要。
## npm 缓存位置
### 默认缓存位置
npm 缓存默认存储在以下位置:
- **macOS/Linux**: `~/.npm`
- **Windows**: `%AppData%/npm-cache`
**查看缓存位置**:
```bash
npm config get cache
```
### 缓存目录结构
```
~/.npm/
├── _cacache/
│ ├── content-v2/
│ │ └── sha512/
│ │ └── ...
│ └── index-v5/
│ └── ...
└── _logs/
```
## 缓存管理命令
### 查看缓存信息
```bash
# 查看缓存大小
npm cache verify
# 查看缓存目录
npm config get cache
```
### 清理缓存
```bash
# 清理缓存(npm 5+)
npm cache clean --force
# 清理特定包的缓存
npm cache clean <package-name>
```
### 验证缓存
```bash
# 验证缓存完整性
npm cache verify
```
## 缓存工作原理
### 1. 包下载缓存
当安装包时,npm 会:
1. 检查本地缓存是否存在该包
2. 如果存在且未过期,直接使用缓存
3. 如果不存在或已过期,从 registry 下载
4. 将下载的包存储到缓存
### 2. 缓存键
缓存使用内容的 SHA-512 哈希作为键:
```
~/.npm/_cacache/content-v2/sha512/<hash>
```
### 3. 缓存索引
索引文件存储包元数据和位置信息:
```
~/.npm/_cacache/index-v5/
```
## 缓存配置
### 配置缓存大小
```bash
# 设置缓存大小限制(默认为 10GB)
npm config set cache-max 10737418240
# 设置缓存最小保留时间(秒)
npm config set cache-min 3600
```
### 配置缓存策略
```bash
# 禁用缓存(不推荐)
npm config set cache false
# 设置缓存目录
npm config set cache /path/to/cache
```
## 离线安装
使用缓存进行离线安装:
```bash
# 使用缓存安装(不检查网络)
npm install --offline
# 使用缓存但允许网络回退
npm install --prefer-offline
# 优先使用网络,缓存作为后备
npm install --prefer-online
```
## CI/CD 中的缓存优化
### GitHub Actions 示例
```yaml
name: Build and Test
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
```
### Docker 优化
```dockerfile
FROM node:18-alpine
# 复制 package 文件
COPY package*.json ./
# 安装依赖(利用缓存)
RUN npm ci --only=production
# 复制应用代码
COPY . .
CMD ["npm", "start"]
```
### 自定义缓存目录
```bash
# 设置自定义缓存目录
export npm_config_cache=/custom/cache/path
npm install
```
## 缓存相关问题和解决方案
### 1. 缓存损坏
**症状**:安装失败或出现奇怪的错误
**解决方案**:
```bash
npm cache clean --force
npm install
```
### 2. 缓存占用过多空间
**解决方案**:
```bash
# 查看缓存大小
npm cache verify
# 清理缓存
npm cache clean --force
# 定期清理(添加到 crontab)
0 0 * * 0 npm cache clean --force
```
### 3. 缓存导致版本不一致
**解决方案**:
```bash
# 强制重新下载
npm install --force
# 删除 node_modules 和 package-lock.json
rm -rf node_modules package-lock.json
npm install
```
## 性能优化技巧
### 1. 使用 npm ci
`npm ci` 专门用于 CI 环境,比 `npm install` 更快:
```bash
npm ci
```
**优势**:
- 直接使用 package-lock.json
- 跳过某些用户级配置
- 删除 node_modules 后重新安装
- 更快的安装速度
### 2. 并行安装
npm 7+ 支持并行安装:
```bash
# 设置并行安装数量
npm config set maxsockets 50
```
### 3. 使用镜像
使用国内镜像加速下载:
```bash
# 使用淘宝镜像
npm config set registry https://registry.npmmirror.com
# 使用 cnpm
npm install -g cnpm --registry=https://registry.npmmirror.com
```
### 4. 预安装常用包
```bash
# 全局安装常用包
npm install -g nodemon typescript
# 使用 npm link 共享本地包
npm link ../local-package
```
## 缓存监控
### 查看缓存统计
```bash
# 查看缓存大小
du -sh ~/.npm
# 查看缓存目录结构
tree ~/.npm/_cacache -L 2
```
### 缓存分析工具
```bash
# 使用 npm-cache-stats
npm install -g npm-cache-stats
npm-cache-stats
```
## 最佳实践
### 1. 开发环境
- 保持默认缓存配置
- 定期清理缓存(每月一次)
- 使用 `npm cache verify` 检查缓存完整性
### 2. CI/CD 环境
- 使用 `npm ci` 替代 `npm install`
- 配置缓存层(GitHub Actions cache、Docker volume)
- 设置合理的缓存保留策略
### 3. 生产环境
- 使用 `npm ci --production` 只安装生产依赖
- 考虑使用 `.npmrc` 锁定配置
- 定期清理缓存以释放空间
### 4. 离线环境
- 预先下载所有依赖到缓存
- 使用 `npm install --offline` 进行离线安装
- 考虑使用私有 registry
## .npmrc 配置示例
```ini
# 项目级 .npmrc
cache=/path/to/project/.npm-cache
registry=https://registry.npmmirror.com
prefer-offline=true
fetch-retries=3
fetch-retry-mintimeout=20000
fetch-retry-maxtimeout=120000
```
## 常见问题排查
### 安装速度慢
```bash
# 检查网络连接
ping registry.npmjs.org
# 使用镜像
npm config set registry https://registry.npmmirror.com
# 清理缓存
npm cache clean --force
```
### 缓存问题导致安装失败
```bash
# 清理缓存
npm cache clean --force
# 删除 node_modules 和 lock 文件
rm -rf node_modules package-lock.json
# 重新安装
npm install
```
### 磁盘空间不足
```bash
# 查看缓存大小
du -sh ~/.npm
# 清理缓存
npm cache clean --force
# 设置缓存大小限制
npm config set cache-max 5368709120
```
理解 npm 缓存机制可以帮助开发者优化构建性能、解决安装问题,并在 CI/CD 环境中提高效率。
服务端 · 2月17日 23:23