本指南将从零开始,全面介绍 npm 的诞生背景、核心概念、环境搭建及所有常用命令,并提供大量实例,确保你不仅"会用",更能"懂原理"。
1. 什么是 npm?
1.1 名称由来
npm 最初是 Node Package Manager 的缩写(Node 包管理器),如今官方更愿意将其描述为 "npm is the world's largest software registry"(世界上最大的软件注册中心),是一个基于 Node.js 的包管理和分发平台。
1.2 核心功能
- 代码复用:允许开发者发布、共享和复用代码片段(称为"包"或"模块")。
- 依赖管理:自动安装、更新、卸载项目所需的外部包,并处理版本冲突。
- 脚本运行 :通过
npm run执行自定义的任务脚本(如启动项目、测试、构建)。 - 版本控制 :严格遵循语义化版本规范,确保项目稳定性。
1.3 组成部分
| 组成部分 | 说明 |
|---|---|
| 网站 | www.npmjs.com/ -- 查找包、文档、统计信息 |
| 命令行工具 | 随 Node.js 一同安装,提供 npm 命令 |
| 注册表 | 一个庞大的公共数据库,存储着数百万个 JavaScript 包 |
2. 环境准备:安装 Node.js 与 npm
npm 作为 Node.js 的官方包管理器,安装 Node.js 时会自动安装 npm。但版本需要留意:较新的 npm 可能不会随旧版 Node.js 自动更新,建议使用长期支持版(LTS)。
2.1 下载安装
Windows / macOS / Linux
- 访问 Node.js 官网
- 点击 LTS 版本 (如
20.11.0)下载对应安装包- Windows:
.msi或.exe - macOS:
.pkg或通过 Homebrewbrew install node - Linux: 使用包管理器(如
apt install nodejs npm)或 nvm
- Windows:
- 运行安装程序,一路默认选项(建议勾选 Add to PATH)
验证安装
打开终端(Windows 使用 cmd 或 PowerShell,macOS/Linux 使用 bash)。
bash
# 查看 Node.js 版本
node -v
# 示例输出:v20.11.0
# 查看 npm 版本
npm -v
# 示例输出:10.2.4
如果两个命令都能正常显示版本号,说明环境准备成功。
2.2 使用 nvm(Node Version Manager)安装(可选但推荐)
nvm 可以管理多个 Node.js 版本,适合需要频繁切换环境的开发者。
安装 nvm
-
Windows: 下载 nvm-windows
-
macOS/Linux: 使用脚本
bashcurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
安装并切换 Node.js
bash
# 列出所有可用的 LTS 版本
nvm list-remote --lts
# 安装最新的 LTS 版本
nvm install --lts
# 切换到该版本
nvm use --lts
# 验证
node -v # v20.11.0
3. npm 初次运行与基础配置
安装 Node.js 后,npm 已有默认配置。我们可以根据网络环境和个人习惯进行优化。
3.1 查看所有配置
bash
npm config list
# 示例输出(部分):
# ; cli configs
# ; node bin location = /usr/local/bin/node
# ; cwd = /Users/me
# ; userconfig = /Users/me/.npmrc
#
# cache = "/Users/me/.npm"
# init-author-name = ""
# ...
3.2 配置镜像源(解决国内网络慢)
默认官方源:https://registry.npmjs.org/
国内可使用淘宝镜像:https://registry.npmmirror.com(原 npm.taobao.org 已迁移)
bash
# 查看当前源
npm config get registry
# 设置淘宝镜像源
npm config set registry https://registry.npmmirror.com
# 恢复官方源
npm config set registry https://registry.npmjs.org/
3.3 设置全局安装路径
全局安装的包默认存放位置:
- Windows:
%AppData%\npm\node_modules - macOS/Linux:
/usr/local/lib/node_modules
有时因权限问题,需要自定义路径(例如用户目录下)。
bash
# 创建全局目录
mkdir ~/.npm-global
# 配置 npm 使用该目录
npm config set prefix '~/.npm-global'
# 将该目录添加到系统 PATH(需要编辑 ~/.bashrc 或 ~/.zshrc)
export PATH=~/.npm-global/bin:$PATH
source ~/.bashrc
3.4 设置缓存路径
npm 下载的包会缓存到本地,下次使用时加快速度。
bash
# 查看当前缓存目录
npm config get cache
# 设置自定义缓存目录
npm config set cache ~/.npm-cache
3.5 配置代理(工作环境需要)
bash
# HTTP 代理
npm config set proxy http://proxy.company.com:8080
# HTTPS 代理
npm config set https-proxy http://proxy.company.com:8080
# 取消代理
npm config delete proxy
npm config delete https-proxy
3.6 保存配置至 .npmrc
以上所有配置最终会被写入用户目录下的 .npmrc 文件(如 ~/.npmrc)。你也可以直接编辑该文件:
ini
registry=https://registry.npmmirror.com
prefix=~/.npm-global
cache=~/.npm-cache
4. npm 初始化项目:npm init
任何使用 npm 管理的项目,根目录下都必须包含一个 package.json 文件。通过 npm init 可以快速生成。
4.1 基础初始化
bash
# 进入项目文件夹
mkdir my-project
cd my-project
# 交互式创建 package.json
npm init
你会被问到一系列问题:
yaml
package name: (my-project) my-demo
version: (1.0.0)
description: A simple demo project
entry point: (index.js)
test command: jest
git repository: https://github.com/user/my-demo
keywords: demo,example
author: Your Name
license: (ISC)
按回车接受默认值或输入自定义内容。最后会生成 package.json。
4.2 快速初始化(跳过交互)
bash
npm init -y # 或 --yes
这会使用默认值生成一个 package.json,稍后可手动编辑。
4.3 生成的 package.json 示例
json
{
"name": "my-demo",
"version": "1.0.0",
"description": "A simple demo project",
"main": "index.js",
"scripts": {
"test": "jest"
},
"keywords": ["demo", "example"],
"author": "Your Name",
"license": "ISC"
}
4.4 package.json 核心字段详解
| 字段 | 说明 | 示例 |
|---|---|---|
name |
包名,必须唯一(发布到 npm 时)。小写、无空格、可用 - 或 _ |
"my-awesome-tool" |
version |
遵循 semver 规范:major.minor.patch |
"2.1.3" |
description |
简短描述,用于 npm search |
"A CLI tool for ..." |
main |
入口文件,当 require('包名') 时加载的文件 |
"dist/index.js" |
scripts |
定义可执行脚本命令 | "start": "node server.js" |
dependencies |
生产环境依赖(项目运行时必须) | "express": "^4.18.0" |
devDependencies |
开发环境依赖(测试、构建等工具) | "jest": "^29.0.0" |
peerDependencies |
对等依赖,要求宿主环境提供 | "react": ">=17.0.0" |
engines |
指定 Node.js 或 npm 版本要求 | "node": ">=18.0.0" |
repository |
代码仓库地址 | "type": "git", "url": "..." |
keywords |
关键词数组,帮助在 npm 搜索 | ["cli","util"] |
author / contributors |
作者信息 | "John <john@example.com> (https://...)" |
license |
开源许可证 | "MIT" |
5. 安装依赖:npm install
npm 的核心功能------安装包。依赖包分为本地安装 (当前项目)和全局安装 (所有项目共享),以及生产依赖 与开发依赖。
5.1 本地安装(默认)
会在当前项目目录下创建 node_modules 文件夹,并将包下载到其中。同时更新 package.json 和 package-lock.json。
bash
# 安装最新版本的 lodash
npm install lodash
# 安装指定版本
npm install lodash@4.17.21
# 安装并保存到 dependencies(默认行为,npm 5+ 自动保存)
npm install lodash --save # 或者 -S(但 -S 已省略)
# 安装并保存到 devDependencies
npm install jest --save-dev # 简写: -D
# 安装指定 tag(如 beta)
npm install my-package@beta
结果示例:
package.json 中的变化:
json
"dependencies": {
"lodash": "^4.17.21"
},
"devDependencies": {
"jest": "^29.7.0"
}
5.2 全局安装
包会安装到全局路径(如 /usr/local/lib/node_modules),命令工具链接到 PATH,任何地方都可直接调用。
⚠️ 注意 :全局安装的包不能在项目中通过 require() 引入,除非你设置了 NODE_PATH。主要用于 CLI 工具。
bash
# 全局安装 yarn
npm install --global yarn # 简写: -g
# 全局安装特定版本
npm install -g npm@9.0.0
# 查看全局安装的包
npm list -g --depth=0
5.3 根据 package.json 安装所有依赖
当你克隆一个现有项目后,运行:
bash
npm install # 或 npm i
npm 会读取 package.json 中的 dependencies 和 devDependencies,并安装所有包到 node_modules,同时生成/更新 package-lock.json。
5.4 仅安装生产依赖(跳过 devDependencies)
bash
# 生产环境部署时常用
npm install --only=production # 或 --omit=dev
5.5 强制重新安装(清除缓存后)
bash
# 先删除 node_modules 和 package-lock.json
rm -rf node_modules package-lock.json # Windows: rmdir /s node_modules
# 重新安装
npm install
6. 理解版本号与语义化版本(Semver)
npm 依赖包的版本遵循 Semver 2.0.0,格式为:MAJOR.MINOR.PATCH
| 版本号变化 | 含义 | 场景 |
|---|---|---|
| PATCH(如 1.0.0 → 1.0.1) | 向下兼容的 bug 修复 | 修复了一个小错误,不影响 API |
| MINOR(如 1.0.0 → 1.1.0) | 向下兼容的新功能 | 添加了新方法,旧代码仍可运行 |
| MAJOR(如 1.0.0 → 2.0.0) | 不向下兼容的重大变更 | 删除了某个 API 或修改了参数 |
6.1 版本声明符号
在 package.json 中,依赖版本前通常会带符号,控制可接受的更新范围。
| 符号 | 含义 | 示例 "^1.2.3" |
允许安装的范围 |
|---|---|---|---|
^ |
兼容补丁和次要版本,但不修改 major | ^1.2.3 |
>=1.2.3 <2.0.0 |
~ |
仅兼容补丁版本 | ~1.2.3 |
>=1.2.3 <1.3.0 |
> >= < <= |
比较符 | ">1.2.3 <2.0.0" |
指定区间 |
x 或 * |
通配符 | 1.2.x 或 * |
1.2.0, 1.2.1... 或任意版本 |
- |
区间范围 | 1.2.3 - 2.3.4 |
等价于 >=1.2.3 <=2.3.4 |
实际例子:
json
"dependencies": {
"express": "^4.18.2", // 接受 4.18.x, 4.19.x, 但不会到 5.0.0
"lodash": "~4.17.21", // 接受 4.17.22, 4.17.23 但不接受 4.18.0
"moment": "2.29.4", // 锁定精确版本
"chalk": ">=5.0.0 <6.0.0" // 只接受 5.x.x
}
6.2 package-lock.json 的作用
- 精确锁定版本树 :记录了每个依赖包的确切版本及其依赖的子包的版本,以及下载地址、完整性哈希。
- 保证重现性 :团队成员或生产环境执行
npm ci时会严格按照 lock 文件安装,避免因版本范围导致的意外差异。 - 加速安装:跳过依赖解析步骤。
7. 更新、卸载与查看依赖
7.1 更新依赖
bash
# 检查哪些包可以更新(不实际安装)
npm outdated
# 示例输出:
# Package Current Wanted Latest Location
# lodash 4.17.20 4.17.21 4.17.21 my-project
# express 4.17.1 4.18.2 4.18.2 my-project
# 更新所有包到符合 semver 范围的最新版本(遵循 package.json 中的符号约束)
npm update
# 更新单个包
npm update lodash
# 强制更新到最新版本(突破版本约束,会修改 package.json)
npm install lodash@latest --save
7.2 卸载依赖
bash
# 卸载本地依赖(并从 package.json 中移除)
npm uninstall lodash # 或 npm remove lodash
# 卸载开发依赖
npm uninstall jest --save-dev
# 卸载全局包
npm uninstall -g yarn
# 只从 node_modules 删除,但保持 package.json 中的记录(很少用)
npm uninstall lodash --no-save
7.3 查看已安装的包
bash
# 查看当前项目的所有依赖(树状结构)
npm list
# 示例:
# my-demo@1.0.0 /path/to/project
# ├── express@4.18.2
# └── lodash@4.17.21
# 查看全局安装的包
npm list -g --depth=0
# 查看某个特定包的信息
npm list lodash
# 查看包是否安装及版本(只输出一行)
npm list lodash --depth=0
# 查看包的生产环境依赖或开发依赖
npm list --prod # 仅 dependencies
npm list --dev # 仅 devDependencies
7.4 搜索 npm 仓库
bash
# 在注册表中搜索包
npm search axios
npm search "webpack plugin"
# 或访问官网 https://www.npmjs.com/search
7.5 查看包的详细信息
bash
# 查看某个包的所有版本号
npm view lodash versions
# 查看包的最新版本
npm view lodash version
# 查看包的完整信息(包括依赖、主页、维护者等)
npm view lodash
8. npm scripts 脚本
package.json 中的 "scripts" 字段可以运行自定义命令,极大简化开发流程。
8.1 定义脚本
json
{
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest",
"build": "webpack --mode production",
"lint": "eslint src/",
"prepare": "npm run build" // 生命周期钩子
}
}
8.2 运行脚本
bash
npm run dev
npm run build
npm test # 'test' 可以省略 run
npm start # 'start' 可以省略 run
8.3 预钩子与后钩子
npm 会自动运行 pre 和 post 前缀的脚本。
json
{
"scripts": {
"prebuild": "rimraf dist",
"build": "webpack",
"postbuild": "echo 'Build finished!'"
}
}
执行 npm run build 时会依次运行:prebuild → build → postbuild。
8.4 传递参数给脚本
使用 -- 分隔符。
json
{
"scripts": {
"mocha": "mocha"
}
}
bash
npm run mocha -- --reporter spec # 实际执行: mocha --reporter spec
8.5 跨平台兼容性
- Windows 不支持
NODE_ENV=production,但可以使用cross-env包。
bash
npm install --save-dev cross-env
json
{
"scripts": {
"start": "cross-env NODE_ENV=production node server.js"
}
}
9. 依赖管理进阶:npm ci 与 npm audit
9.1 npm ci ------ 快速、严格的安装
适用于持续集成(CI)环境或必须保证依赖完全一致的情况。
- 必须存在
package-lock.json或npm-shrinkwrap.json - 会删除
node_modules再进行全新安装 - 严格按照 lock 文件安装,不会修改
package.json或 lock 文件 - 比
npm install快得多(跳过解析)
bash
# 在 CI 服务器或部署前执行
npm ci
9.2 npm audit ------ 检查安全漏洞
分析依赖树,报告已知漏洞并提供自动修复建议。
bash
# 扫描漏洞
npm audit
# 自动修复可修复的漏洞(会升级依赖版本)
npm audit fix
# 只修复不破坏 semver 的漏洞
npm audit fix --only=prod
# 强制升级到最新版本(可能破坏兼容性)
npm audit fix --force
10. 发布自己的 npm 包
如果你开发了一个可复用的模块,可以发布到 npm 公共仓库供他人使用。
10.1 注册账号
访问 npmjs.com 注册,或者命令行注册:
bash
npm adduser
# 输入用户名、密码、邮箱
10.2 登录
bash
npm login
10.3 准备发布内容
- 确保
package.json中name为唯一且可用(未被占用)。 - 准备
README.md,这是包的文档主页。 - 确定版本号(通常手动修改
version字段)。 - 可选:编写
.npmignore文件忽略不需要上传的文件(如test/、.git)。
10.4 发布
bash
# 当前目录发布
npm publish
# 发布 beta 标签版本
npm publish --tag beta
10.5 更新版本与再次发布
遵循 Semver 规则修改版本后再发布。
bash
# 手动修改 version,然后 npm publish
# 或使用 npm version 智能升级
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
10.6 撤销发布(24 小时内可撤销)
bash
npm unpublish my-package@1.0.0
⚠️ 官方强烈不建议撤销已发布的包,因为会被其他项目依赖。可以改为弃用:
bash
npm deprecate my-package@'<1.2.0' "This version has a critical bug, please upgrade!"
11. 常见问题与排查技巧
11.1 权限错误 EACCES
错误示例 :Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules'
解决方案:
-
不要使用
sudo(会导致后续权限混乱) -
按照 3.3 节修改全局路径到用户目录
-
或修复 npm 权限:
bashsudo chown -R $(whoami) ~/.npm sudo chown -R $(whoami) /usr/local/lib/node_modules
11.2 依赖冲突
现象 :npm ERR! code ERESOLVE 或版本无法满足。
解决:
bash
# 强制执行(不推荐,可能导致运行时错误)
npm install --legacy-peer-deps
# 或使用旧版 peerDep 处理方式
npm install --force
# 最好的办法是升级相关依赖或使用 overrides(npm 8.3+)
package.json 中可使用 overrides 强制指定版本:
json
{
"overrides": {
"lodash": "4.17.21"
}
}
11.3 网络超时或 SSL 错误
设置更大的超时或切换源:
bash
npm config set fetch-retry-mintimeout 20000
npm config set fetch-retry-maxtimeout 120000
npm config set registry https://registry.npmmirror.com
11.4 查看 npm 调试日志
bash
npm install --verbose
# 或查看错误日志文件 ~/.npm/_logs/
11.5 清除缓存
bash
npm cache clean --force # 一般不需要,除非缓存损坏
npm cache verify # 检查完整性
12. 总结与最佳实践
12.1 日常开发工作流
- 新建项目:
mkdir project && cd project && npm init -y - 安装依赖:
npm install express --save与npm install jest --save-dev - 编写代码,使用脚本:
npm start、npm test - 版本控制:提交
package.json和package-lock.json(切勿忽略 lock 文件) - 团队协作:同事克隆后执行
npm ci而非npm install - 定期更新:
npm outdated然后npm update,或使用npm-check-updates(ncu)工具
12.2 安全与性能建议
- 尽量锁定依赖版本(使用 lock 文件)。
- 定期运行
npm audit修复漏洞。 - 不要将敏感信息(如密码、token)发布到 npm 仓库。
- 使用
npm ci代替npm install在 CI 环境。 - 使用
npm prune删除多余包(极少用,npm ci已覆盖)。
附录:所有命令速查表
| 命令 | 说明 | 示例 |
|---|---|---|
npm init [-y] |
创建 package.json |
npm init -y |
npm install [pkg] |
安装包 | npm install lodash@4 |
npm install -g pkg |
全局安装 | npm install -g nodemon |
npm install --save-dev pkg |
开发依赖 | npm i -D jest |
npm uninstall pkg |
卸载包 | npm uninstall lodash |
npm update |
更新包 | npm update express |
npm outdated |
检查更新 | npm outdated |
npm list [-g] |
列出已安装 | npm list -g --depth=0 |
npm run <script> |
运行脚本 | npm run build |
npm test |
测试(脚本) | npm test |
npm start |
启动(脚本) | npm start |
npm ci |
基于 lock 文件安装 | npm ci |
npm audit [fix] |
安全审计 | npm audit fix |
npm view pkg |
查看包信息 | npm view axios |
npm search key |
搜索包 | npm search cli |
npm login / logout |
登录/退出 | npm login |
npm publish |
发布包 | npm publish |
npm version [patch/minor/major] |
升级版本 | npm version patch |
npm cache clean --force |
清除缓存 | npm cache clean --force |
npm config set <key> <value> |
设置配置 | npm config set registry ... |
npm config get <key> |
获取配置 | npm config get prefix |
最后提示:npm 生态巨大,遇到问题先查阅官方文档,或使用
npm help <command>查看内置帮助。祝开发顺利!