跳到主要内容

npm

npm(Node Package Manager)是 Node.js 的默认包管理器,也是世界上最大的软件注册表之一。截至 2024 年,npm 仓库已托管超过 200 万个包,每周下载量超过 300 亿次。

安装与配置

安装 Node.js 和 npm

npm 随 Node.js 一起安装,无需单独安装。推荐使用以下方式安装 Node.js:

使用官方安装包

Node.js 官网 下载对应系统的安装包。LTS 版本更稳定,适合生产环境;Current 版本包含最新特性。

使用 nvm(Node Version Manager)

nvm 允许在同一台机器上安装和管理多个 Node.js 版本:

# 安装 nvm(macOS/Linux)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

# 安装 Node.js LTS 版本
nvm install --lts

# 安装指定版本
nvm install 20.10.0

# 切换版本
nvm use 20

# 设置默认版本
nvm alias default 20

# 查看已安装版本
nvm ls

使用 nvm-windows(Windows)

# 下载并安装 nvm-windows
# https://github.com/coreybutler/nvm-windows/releases

# 安装 Node.js
nvm install 20.10.0

# 切换版本
nvm use 20.10.0

验证安装

# 检查 Node.js 版本
node -v
# 输出示例: v20.10.0

# 检查 npm 版本
npm -v
# 输出示例: 10.2.3

# 查看 npm 安装路径
npm root -g
# 输出示例: /usr/local/lib/node_modules

# 查看 npm 配置
npm config list

升级 npm

# 升级到最新版本
npm install -g npm@latest

# 升级到指定版本
npm install -g [email protected]

# 使用 Node.js 自带的 Corepack(Node.js 16.13+)
corepack enable
corepack prepare npm@latest --activate

初始化项目

创建 package.json

# 交互式创建 package.json
npm init

# 使用默认值创建 package.json
npm init -y

# 使用指定模板创建
npm init react-app my-app # 使用 create-react-app
npm init vite my-app --template react # 使用 create-vite
npm init @nestjs/new my-api # 使用 NestJS CLI

交互式创建时,npm 会依次询问以下信息:

  • name:包名,默认为当前目录名
  • version:版本号,默认为 1.0.0
  • description:描述信息
  • entry point:入口文件,默认为 index.js
  • test command:测试命令
  • git repository:Git 仓库地址
  • keywords:关键词
  • author:作者
  • license:许可证,默认为 ISC

package.json 结构详解

{
"name": "my-project",
"version": "1.0.0",
"description": "项目描述",
"main": "index.js",
"module": "index.mjs",
"types": "index.d.ts",
"bin": {
"my-cli": "./bin/cli.js"
},
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest",
"build": "webpack --mode production",
"lint": "eslint src/",
"format": "prettier --write ."
},
"keywords": ["node", "javascript"],
"author": "Your Name <[email protected]>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/user/repo.git"
},
"bugs": {
"url": "https://github.com/user/repo/issues"
},
"homepage": "https://github.com/user/repo#readme",
"dependencies": {
"express": "^4.18.2",
"lodash": "^4.17.21"
},
"devDependencies": {
"jest": "^29.5.0",
"typescript": "^5.0.0"
},
"peerDependencies": {
"react": ">=16.8.0"
},
"optionalDependencies": {
"fsevents": "^2.3.0"
},
"bundledDependencies": [
"my-dependency"
],
"engines": {
"node": ">=18.0.0",
"npm": ">=9.0.0"
},
"os": ["darwin", "linux"],
"cpu": ["x64", "arm64"],
"private": false,
"publishConfig": {
"registry": "https://registry.npmjs.org",
"access": "public"
},
"files": [
"dist",
"lib",
"README.md"
],
"sideEffects": false
}

关键字段说明

name 和 version

这两个字段是必需的,它们共同构成包的唯一标识。name 必须是小写的,可以包含字母、数字、连字符和下划线。

{
"name": "@myorg/my-package",
"version": "1.0.0"
}

main、module 和 types

  • main:CommonJS 入口文件,Node.js 默认使用
  • module:ES Module 入口文件,打包工具优先使用
  • types:TypeScript 类型定义文件

scripts

定义可通过 npm run 执行的脚本命令。npm 提供了一些生命周期钩子:

{
"scripts": {
"prebuild": "echo 'Building...'",
"build": "webpack",
"postbuild": "echo 'Build complete!'"
}
}

执行 npm run build 时,会依次执行 prebuildbuildpostbuild

files

指定发布时要包含的文件。默认包含所有文件,但以下文件始终被排除:

  • .git
  • node_modules
  • .npmignore 中列出的文件

依赖管理

依赖类型详解

npm 支持多种依赖类型,每种类型有不同的用途:

dependencies(生产依赖)

运行时必需的依赖,会被打包到生产环境中:

npm install express
npm install [email protected]
{
"dependencies": {
"express": "^4.18.2",
"lodash": "^4.17.21"
}
}

devDependencies(开发依赖)

仅在开发和测试时需要的依赖,不会被打包到生产环境:

npm install -D jest
npm install --save-dev typescript
{
"devDependencies": {
"jest": "^29.5.0",
"typescript": "^5.0.0"
}
}

常见的开发依赖包括:

  • 测试框架:jest, mocha, vitest
  • 构建工具:webpack, vite, rollup
  • 代码检查:eslint, prettier
  • 类型定义:@types/node

peerDependencies(同伴依赖)

表示当前包需要宿主项目提供指定的依赖。常用于插件开发:

{
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
}
}

例如,一个 React 组件库不应该将 React 打包进去,而是声明为 peerDependencies,由使用方提供。

optionalDependencies(可选依赖)

即使安装失败也不会影响项目运行:

{
"optionalDependencies": {
"fsevents": "^2.3.0"
}
}

典型场景是平台特定的依赖,如 macOS 上的 fsevents。

bundledDependencies(打包依赖)

发布时会将这些依赖打包在一起:

{
"bundledDependencies": [
"my-private-package"
]
}

安装依赖

# 安装 package.json 中所有依赖
npm install

# 仅安装生产依赖(跳过 devDependencies)
npm install --production

# 忽略可选依赖
npm install --omit=optional

# 安装生产依赖
npm install lodash

# 安装指定版本
npm install [email protected]

# 安装版本范围
npm install lodash@">=4.17.0 <5.0.0"

# 安装最新版本
npm install lodash@latest

# 安装下一个版本(next tag)
npm install lodash@next

# 安装开发依赖
npm install -D jest
npm install --save-dev jest

# 安装可选依赖
npm install -O typescript
npm install --save-optional typescript

# 全局安装
npm install -g typescript
npm install --global typescript

# 安装精确版本(不使用 ^ 前缀)
npm install --save-exact lodash

# 安装到 bundleDependencies
npm install --save-bundle my-package

# 从 Git 仓库安装
npm install git+https://github.com/user/repo.git
npm install github:user/repo
npm install git+ssh://[email protected]:user/repo.git

# 从本地路径安装
npm install ./local-package
npm install file:../local-package

# 从压缩包安装
npm install ./package.tgz
npm install https://example.com/package.tgz

删除依赖

# 删除依赖
npm uninstall lodash

# 删除开发依赖
npm uninstall -D jest
npm uninstall --save-dev jest

# 删除可选依赖
npm uninstall -O typescript

# 删除全局依赖
npm uninstall -g typescript

# 删除多个依赖
npm uninstall lodash express

更新依赖

# 检查可更新的依赖
npm outdated

# 输出示例:
# Package Current Wanted Latest Location Depended by
# express 4.17.1 4.18.2 4.18.2 node_modules/express my-project
# lodash 4.17.20 4.17.21 4.17.21 node_modules/lodash my-project

# 更新依赖到 package.json 允许的范围内
npm update

# 更新特定包
npm update lodash

# 更新到最新版本(需要修改 package.json)
npm install lodash@latest

# 更新所有依赖到最新版本(需要额外工具)
npx npm-check-updates -u
npm install

# 全局更新
npm update -g

查看依赖

# 查看已安装的依赖
npm list

# 查看顶层依赖(不显示嵌套)
npm list --depth=0

# 查看全局依赖
npm list -g --depth=0

# 查看特定包的依赖树
npm list lodash

# 查看包的安装路径
npm root

# 查看全局安装路径
npm root -g

# 查看包信息
npm view lodash

# 查看特定版本信息
npm view [email protected]

# 查看特定字段
npm view lodash version
npm view lodash dependencies
npm view lodash repository.url

# 查看包的所有版本
npm view lodash versions

# 搜索包
npm search express
npm search express --long # 显示详细信息

版本号规则

npm 使用语义化版本(SemVer),版本号格式为 主版本号.次版本号.修订号

版本范围符号

符号含义示例匹配范围
^兼容版本^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.3<=1.2.3
=精确版本=1.2.31.2.3
-范围1.2.3 - 1.3.0>=1.2.3 <=1.3.0
``
*任意版本*所有版本
x通配符1.x>=1.0.0 <2.0.0
无符号精确版本1.2.31.2.3

^ 和 ~ 的区别

这是最容易混淆的两个符号:

^(脱字符)

允许不改变最左边非零数字的更新:

  • ^1.2.3>=1.2.3 <2.0.0(允许次版本和修订号更新)
  • ^0.2.3>=0.2.3 <0.3.0(只允许修订号更新)
  • ^0.0.3>=0.0.3 <0.0.4(精确版本)
  • ^1.2.x>=1.2.0 <2.0.0
  • ^0.0.x>=0.0.0 <0.1.0
  • ^1.0.0>=1.0.0 <2.0.0

~(波浪号)

只允许修订号更新:

  • ~1.2.3>=1.2.3 <1.3.0
  • ~1.2>=1.2.0 <1.3.0
  • ~1>=1.0.0 <2.0.0
  • ~0.2.3>=0.2.3 <0.3.0

版本管理命令

# 查看当前版本
npm version

# 更新版本号
npm version patch # 1.0.0 -> 1.0.1(修订号 +1)
npm version minor # 1.0.0 -> 1.1.0(次版本号 +1)
npm version major # 1.0.0 -> 2.0.0(主版本号 +1)

# 预发布版本
npm version prerelease # 1.0.0 -> 1.0.1-0
npm version prerelease --preid=beta # 1.0.0 -> 1.0.1-beta.0

# 从 Git 仓库更新版本
npm version minor -m "Upgrade to %s"

# 强制更新(即使有未提交的更改)
npm version patch --force

脚本命令

定义脚本

{
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"build": "webpack --mode production",
"build:dev": "webpack --mode development",
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
"format": "prettier --write .",
"clean": "rm -rf dist node_modules",
"reinstall": "npm run clean && npm install"
}
}

运行脚本

# 运行脚本
npm run start
npm start # start 可省略 run

# 运行 test 和 restart 也可以省略 run
npm test
npm restart

# 传递参数
npm run test -- --coverage --watchAll=false

# 运行并行脚本
npm run lint & npm run test

# 使用 npm-run-all 并行运行
npx npm-run-all --parallel lint test

# 使用 npm-run-all 串行运行
npx npm-run-all --serial clean build

生命周期脚本

npm 在特定时机自动执行的脚本:

钩子触发时机用途
preinstall安装依赖前检查环境
postinstall安装依赖后构建原生模块
preuninstall卸载依赖前清理资源
postuninstall卸载依赖后清理配置
preversion版本变更前运行测试
version版本变更后更新文件
postversion版本变更后推送 Git
pretest测试前准备测试数据
test测试时运行测试
posttest测试后清理测试数据
prestart启动前检查配置
start启动时启动应用
poststart启动后记录日志
prerestart重启前停止服务
restart重启时重启应用
postrestart重启后记录日志
prestop停止前保存状态
stop停止时停止应用
poststop停止后清理资源
prepare发布前/安装后构建 TypeScript
prepublishOnly发布前最终检查
prepack打包前准备文件
postpack打包后清理临时文件

生命周期示例

{
"scripts": {
"prebuild": "npm run clean",
"build": "webpack --mode production",
"postbuild": "npm run copy-assets",
"pretest": "npm run build",
"test": "jest",
"posttest": "npm run coverage-report",
"preversion": "npm test",
"version": "npm run build && git add dist",
"postversion": "git push && git push --tags"
}
}

配置管理

.npmrc 文件

npm 使用 .npmrc 文件进行配置,可以放在多个位置:

  • 项目级/path/to/project/.npmrc(优先级最高)
  • 用户级~/.npmrc
  • 全局级$PREFIX/etc/npmrc
  • 内置级/path/to/npm/npmrc
# 设置镜像源
registry=https://registry.npmmirror.com

# 私有包配置
@mycompany:registry=https://npm.mycompany.com

# 认证信息
//npm.mycompany.com/:_authToken=${NPM_TOKEN}
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

# 代理设置
proxy=http://proxy.example.com:8080
https-proxy=http://proxy.example.com:8080
noproxy=localhost,127.0.0.1

# 缓存设置
cache=${APPDATA}/npm-cache

# 安全设置
strict-ssl=true
cafile=/path/to/certificate.pem

# 其他设置
save-exact=true
save-prefix=~
package-lock=true

# 脚本设置
ignore-scripts=false
script-shell=/bin/bash

# 日志级别
loglevel=warn

# 进度条
progress=true

常用配置命令

# 查看所有配置
npm config list

# 查看详细配置(包括默认值)
npm config list -l

# 查看特定配置
npm config get registry
npm config get cache

# 设置配置
npm config set registry https://registry.npmmirror.com
npm config set save-exact true
npm config set init.author.name "Your Name"

# 设置用户级配置
npm config set registry https://registry.npmmirror.com --location=user

# 设置项目级配置
npm config set registry https://registry.npmmirror.com --location=project

# 删除配置
npm config delete registry

# 设置代理
npm config set proxy http://proxy.example.com:8080
npm config set https-proxy http://proxy.example.com:8080

# 删除代理
npm config delete proxy
npm config delete https-proxy

# 编辑配置文件
npm config edit
npm config edit --global

环境变量

npm 支持通过环境变量配置:

# 设置镜像源
NPM_CONFIG_REGISTRY=https://registry.npmmirror.com npm install

# 设置缓存目录
NPM_CONFIG_CACHE=/tmp/npm-cache npm install

# 设置认证令牌
NPM_TOKEN=xxx npm publish

# 设置代理
HTTP_PROXY=http://proxy.example.com:8080 npm install
HTTPS_PROXY=http://proxy.example.com:8080 npm install

常用镜像源

切换镜像源

# 淘宝镜像
npm config set registry https://registry.npmmirror.com

# 官方镜像
npm config set registry https://registry.npmjs.org

# 腾讯镜像
npm config set registry https://mirrors.cloud.tencent.com/npm/

# 华为镜像
npm config set registry https://repo.huaweicloud.com/repository/npm/

使用 nrm 管理镜像源

nrm 是一个镜像源管理工具,可以方便地在不同镜像源之间切换:

# 安装 nrm
npm install -g nrm

# 列出所有镜像源
nrm ls

# 切换镜像源
nrm use taobao
nrm use npm

# 测试镜像源速度
nrm test

# 添加自定义镜像源
nrm add company http://npm.company.com/

# 删除镜像源
nrm del company

针对特定 scope 使用不同镜像源

# 为 @mycompany scope 设置私有仓库
npm config set @mycompany:registry https://npm.mycompany.com

# 或在 .npmrc 中配置
# @mycompany:registry=https://npm.mycompany.com

发布包

注册账号

# 注册 npm 账号
npm adduser

# 登录
npm login

# 登录到私有仓库
npm login --registry=https://npm.mycompany.com

# 查看当前用户
npm whoami

# 登出
npm logout

发布流程

# 发布前检查
npm pack --dry-run

# 查看将要发布的文件
npm pack --dry-run 2>&1 | grep "npm notice"

# 发布
npm publish

# 发布到指定镜像源
npm publish --registry https://registry.npmjs.org

# 发布 scoped 包(默认私有,需要付费)
# 公开 scoped 包
npm publish --access public

# 发布 beta 版本
npm publish --tag beta

# 发布 next 版本
npm publish --tag next

# 发布到私有仓库
npm publish --registry https://npm.mycompany.com

版本标签管理

# 查看包的所有标签
npm dist-tag ls lodash

# 添加标签
npm dist-tag add [email protected] stable

# 删除标签
npm dist-tag rm lodash old

# 安装特定标签的版本
npm install lodash@beta
npm install lodash@next

撤销发布

# 撤销特定版本(发布 24 小时内)
npm unpublish [email protected]

# 撤销整个包(谨慎使用)
npm unpublish my-package --force

# 弃用包(推荐)
npm deprecate my-package "This package is no longer maintained"
npm deprecate [email protected] "This version has security issues"

package-lock.json

package-lock.json 文件记录了实际安装的每个依赖的精确版本和来源。

作用

  • 锁定版本:确保团队成员和 CI/CD 环境安装完全相同的依赖
  • 加速安装:无需重新解析依赖关系
  • 可追溯性:记录依赖的完整来源和校验和
  • 完整性验证:通过 integrity 字段验证文件完整性

结构

{
"name": "my-project",
"version": "1.0.0",
"lockfileVersion": 3,
"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-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
"dependencies": {
"body-parser": "1.20.1",
"debug": "2.6.9"
}
}
}
}

注意事项

  • 必须提交到版本控制
  • 不要手动编辑
  • 使用 npm install 时自动更新
  • 使用 npm ci 时严格遵循锁文件

npx 命令

npx 用于执行 npm 包中的命令,无需全局安装。

基本用法

# 执行包命令(临时安装)
npx create-react-app my-app

# 执行本地安装的包
npx webpack

# 使用特定版本
npx [email protected]

# 使用特定标签
npx webpack@next

# 从 GitHub 执行
npx github:user/repo
npx github:user/repo#branch

# 从 Gist 执行
npx gist:github-gist-id

# 交互式创建项目
npx create-vite
npx create-next-app my-app
npx @nestjs/new my-api

# 执行命令并传递参数
npx webpack --config webpack.config.js

# 使用 -- 防止参数被 npx 解析
npx -- webpack --config webpack.config.js

# 强制使用本地安装的版本
npx --no-install webpack

# 忽略本地版本,使用远程版本
npx --ignore-existing webpack

# 使用不同的包管理器
npx --package pnpm create-react-app my-app

npx 与 npm exec

npm 7+ 引入了 npm exec 命令,功能类似 npx:

# npm exec 语法
npm exec -- create-react-app my-app
npm exec --package=webpack -- webpack --version

工作区 (Workspaces)

npm 7+ 原生支持单体仓库(Monorepo)管理。

配置

{
"name": "my-monorepo",
"private": true,
"workspaces": [
"packages/*",
"apps/*"
]
}

目录结构

my-monorepo/
├── package.json
├── package-lock.json
├── packages/
│ ├── core/
│ │ ├── package.json
│ │ └── src/
│ └── utils/
│ ├── package.json
│ └── src/
└── apps/
└── web/
├── package.json
└── src/

workspace 命令

# 安装所有工作区依赖
npm install

# 在指定工作区执行命令
npm run test --workspace=packages/core
npm run build -w packages/core

# 在多个工作区执行命令
npm run test --workspace=packages/core --workspace=packages/utils

# 在所有工作区执行命令
npm run test --workspaces

# 忽略错误继续执行
npm run test --workspaces --if-present

# 添加依赖到指定工作区
npm install lodash --workspace=packages/core

# 添加工作区依赖
npm install @myorg/core --workspace=packages/utils

# 创建新工作区
npm init -w packages/new-package

# 查看工作区信息
npm ls -a

workspace 协议

在 workspace 内部引用其他 workspace 包:

{
"dependencies": {
"@myorg/core": "*",
"@myorg/utils": "workspace:*"
}
}

发布时,workspace:* 会被替换为实际版本号。

npm ci

npm ci(Clean Install)专为 CI/CD 环境设计,比 npm install 更快更严格。

与 npm install 的区别

特性npm installnpm ci
读取 package-lock.json是(必须存在)
更新 package-lock.json
安装范围package.json 中的依赖仅 package-lock.json 中的依赖
node_modules 处理增量更新删除后全新安装
速度较慢更快
适用场景开发环境CI/CD 环境

使用

# 标准用法
npm ci

# 仅安装生产依赖
npm ci --production

# 忽略可选依赖
npm ci --omit=optional

# 指定安装目录
npm ci --prefix=/app

最佳实践

1. 锁定版本

  • 提交 package-lock.json 到版本控制
  • 生产环境使用 npm ci 而非 npm install
  • 使用 .npmrc 设置 save-exact=truesave-prefix=~

2. 安全审计

# 检查安全漏洞
npm audit

# 输出示例:
# found 2 vulnerabilities (1 low, 1 high)
# run `npm audit fix` to fix them

# 自动修复
npm audit fix

# 强制修复(可能有破坏性变更)
npm audit fix --force

# 查看详细报告
npm audit --json

# 仅检查生产依赖
npm audit --production

3. 使用 .npmignore

控制发布时包含的文件:

# .npmignore
*.test.js
*.spec.js
coverage/
docs/
examples/
.github/
.git/
.DS_Store
.eslintrc
.prettierrc
tsconfig.json
webpack.config.js

或者使用 files 字段白名单:

{
"files": [
"dist",
"lib",
"README.md",
"LICENSE"
]
}

4. 使用 engines 指定版本

{
"engines": {
"node": ">=18.0.0",
"npm": ">=9.0.0"
},
"engineStrict": true
}

5. 使用 overrides 和 resolutions

强制指定依赖版本:

{
"overrides": {
"lodash": "4.17.21",
"express": {
"debug": "4.3.4"
}
}
}

6. 清理缓存

# 清除缓存
npm cache clean --force

# 验证缓存
npm cache verify

# 查看缓存信息
npm cache ls

7. 检查环境

# 检查 npm 环境
npm doctor

# 输出示例:
# Check Value Recommendation
# npm ping ok
# npm -v 10.2.3
# node -v 20.10.0
# npm config get registry https://registry.npmjs.org
# git --version 2.43.0

常用命令速查

命令说明
npm init初始化项目
npm init -y使用默认值初始化
npm install安装所有依赖
npm install <pkg>安装依赖
npm install -D <pkg>安装开发依赖
npm install -g <pkg>全局安装
npm uninstall <pkg>删除依赖
npm update更新依赖
npm outdated检查过期依赖
npm run <script>运行脚本
npm list查看已安装依赖
npm list -g --depth=0查看全局依赖
npm search <pkg>搜索包
npm view <pkg>查看包信息
npm dedupe减少重复依赖
npm prune删除多余依赖
npm cache clean --force清除缓存
npm doctor检查环境
npm ciCI/CD 安装
npm audit安全审计
npm publish发布包
npm version <type>更新版本号
npm config list查看配置
npm config set <key> <value>设置配置
npm whoami查看当前用户
npm login登录
npm logout登出

了解更多