npm 完整使用指南
# 📦 npm 完整使用指南
命令优先、可快速检索的 npm 速用指南。
# 什么是 npm
npm (opens new window)(Node Package Manager)是 Node.js 官方包管理器,覆盖包安装/更新/卸载、依赖与版本管理、脚本运行、包发布、安全审计。
npm -v # npm 版本
node -v # Node.js 版本
npm config list # 当前生效配置
npm -l # 所有命令用法一览
2
3
4
# 基础命令
# 项目初始化
npm init # 交互式创建 package.json
npm init -y # 全默认值快速创建
npm init vite@latest my-app # 用初始化器创建项目(vite / react-app 等)
2
3
# 查看包信息
npm view react # 包详情
npm view react version # 最新版本
npm view react versions # 所有版本
npm view react dependencies # 指定字段(description / homepage 等同理)
npm search react # 搜索包
npm root -g # 全局包安装路径
2
3
4
5
6
# 包管理
# 安装依赖
npm install # 安装所有依赖(npm i)
npm i react react-dom # 安装指定包(可多个),默认记入 dependencies
npm i -D eslint prettier # 开发依赖(--save-dev)
npm i -g typescript # 全局安装(--global)
npm i [email protected] # 指定版本;@latest / @beta(dist-tag)同理
npm i git+https://github.com/user/repo.git # Git 仓库
npm i file:../local-package # 本地路径
npm i --no-save # 不写入 package.json
npm i --force # 绕过缓存强制重新拉取(排障用)
npm i --verbose # 详细输出
2
3
4
5
6
7
8
9
10
# 更新依赖
npm update # 范围内更新:升到 semver 允许的最高版本(npm up)
npm up react # 更新指定包
npm outdated # 查看过时包(-g 看全局)
npx npm-check-updates -u && npm i # 跨范围升级:改写 package.json 到最新
2
3
4
# 卸载依赖
npm uninstall react # 自动识别 dependencies / devDependencies(un / rm 等价)
npm un -g typescript # 全局
npm un react --no-save # 只删 node_modules,不动 package.json
2
3
# 查看依赖
npm ls # 直接依赖(npm 7+ 默认 depth=0)
npm ls --depth=2 # 深入两层
npm ls -g --depth=0 # 全局已装
npm ls react # 某包装在哪、被谁依赖
npm ls --json # JSON 输出(脚本用)
npm ls --omit=dev # 只看生产依赖
2
3
4
5
6
# 查看子依赖
npm ls <dep> # 谁依赖了它、实际解析的版本
npm view <package> dependencies # 这个包声明了哪些依赖
grep -A 3 '"<dep>"' package-lock.json # lock 文件中的实际解析版本
2
3
# 深入理解 npm install
# 安装流程:三棵树的收敛
npm install 本质是把三棵树对齐(npm 内部称为 reify):依赖树(package.json 声明的)→ 理想树(idealTree,按 semver 应该装什么)→ 实际树(node_modules 里实际装了什么)。展开为五步:
- 解析依赖树:读 package.json,按 semver 范围递归计算 idealTree;有 lock 文件则直接按 lock 精确解析,跳过 registry 元数据拉取——这就是
npm ci更快的根本原因 - 下载 tarball:取包元数据(packument)→ 解析 tarball 地址 → 下载 → 校验 sha512 integrity(防篡改)→ 写入缓存
~/.npm/_cacache(按内容寻址,同一 tarball 全局只存一份) - 扁平化安装:尽量把所有包提升到
node_modules/顶层;版本冲突时嵌套进node_modules/<pkg>/node_modules/ - 生成 bin 软链(见下节)
- 执行生命周期钩子 → 更新 package-lock.json
# bin 软链机制
包在 package.json 声明 bin 字段(字符串 = 命令名同包名;对象 = 多个命令):
{ "bin": { "husky": "./bin.js" } }
npm install 时在 node_modules/.bin/ 下为它创建可执行软链。bin.js 文件头带 shebang:
#!/usr/bin/env node
shell 据此把它交给 node 执行。npm 执行 scripts 时把 node_modules/.bin 注入 PATH 最前面——这就是 scripts 里能直接写 vite / jest / husky 命令名的原因。全局安装(-g)则软链到全局 bin 目录(nvm 管理的 node 不需要 sudo)。
# 生命周期钩子执行顺序
root 包与各依赖包的钩子在安装过程中交错执行:
root preinstall
→ 逐个安装依赖(每个依赖自己的 preinstall → install → postinstall 在此期间执行,
典型如 node-gyp 编译原生模块)
→ root postinstall
→ root prepare
2
3
4
5
| 钩子 | 时机 | 典型用途 |
|---|---|---|
preinstall | 安装任何依赖前 | 环境检查 |
install | 依赖安装中 | 依赖包编译原生模块(node-gyp) |
postinstall | 依赖装完后 | patch-package、初始化 |
prepare | 本地 install 后、装 git 依赖时、publish 打包前 | 激活 husky |
"prepare": "husky" 完整机制(husky 是 CLI 不是函数):
npm install 装完依赖
→ husky 进入 node_modules/.bin(bin 软链已生成)
→ 自动触发 prepare
→ PATH 含 node_modules/.bin,husky 命令可执行
→ 执行后设置 git core.hooksPath=.husky
→ Git 改从 .husky/ 目录读 hooks
2
3
4
5
6
它不是"安装 husky",而是"依赖装完后运行 husky CLI 激活 Git hooks"——新同事 clone 后只需 npm install,hooks 自动配好。
# 幽灵依赖
扁平化安装的副作用:未在 package.json 声明的包,因被提升到顶层而能被 require(phantom dependency)。隐患:某次上游升级不再提升它,你的代码直接崩。pnpm 用符号链接 + 严格 node_modules 从机制上杜绝此问题。
# 安全:install 脚本即任意代码执行
依赖的 postinstall 可执行任意代码,是供应链攻击的标准入口(如 node-ipc、ua-parser-js 事件)。审计陌生依赖时:
npm i --ignore-scripts # 跳过所有 install 钩子(副作用:原生模块不编译、husky 不激活)
# 版本控制
# 语义化版本
npm 遵循语义化版本 (opens new window)(SemVer,实现为 node-semver (opens new window)),格式 MAJOR.MINOR.PATCH:
- MAJOR:不兼容的 API 变更
- MINOR:向后兼容的功能新增
- PATCH:向后兼容的问题修正
范围(range)描述的是一组满足条件的版本集合;npm install 在集合内选取满足范围的最高版本(有 lock 文件时以 lock 为准)。在线验证:Version range syntax examples (opens new window)
# 版本范围符号
| 写法 | 含义 |
|---|---|
1.2.3 | 精确版本 |
^1.2.3 | 锁主版本(1.x.x),npm 默认,推荐 |
~1.2.3 | 锁次版本(1.2.x) |
>=1.2.3 <2.0.0 | 范围组合 |
1.2.3 - 2.3.4 | 闭区间 |
1.2.3 \|\| 2.3.4 | 或关系 |
* / latest | 任意 / 最新(避免使用) |
git+https://github.com/user/repo.git | Git 仓库 |
file:../local-package | 本地路径 |
预发布版本(如
1.2.3-beta.1)默认不会被^1.2.3选中,除非范围本身带-beta或显式安装对应 dist-tag——即 npm 不会自动把测试版带进项目。
# package.json 示例
{
"name": "my-project",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest",
"build": "webpack --mode production",
"lint": "eslint ."
},
"dependencies": {
"express": "^4.18.0"
},
"devDependencies": {
"jest": "^29.0.0",
"webpack": "^5.0.0"
},
"engines": {
"node": ">=14.0.0"
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 脚本管理
# 运行脚本
npm run # 列出所有可用脚本
npm run dev # 自定义脚本必须带 run
npm start # start / test / stop / restart 可省略 run
npm run build -- --prod # 传参:-- 之后接参数
npm run lint && npm run test # 串行执行
npx npm-run-all --parallel lint test # 并行执行
2
3
4
5
6
脚本里可直接写
vite/jest/husky等命令名的原因(bin 软链 + PATH 注入)见深入理解 npm install。
# pre/post 钩子
任意脚本自动拥有 pre<script> / post<script>,按序自动执行:
npm run build # 实际执行:prebuild → build → postbuild
install / publish / version 相关的内置钩子,见深入理解 npm install与发布与维护。
# 常用脚本模板
{
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"test": "jest",
"test:coverage": "jest --coverage",
"lint": "eslint . --ext .ts,.tsx",
"lint:fix": "eslint . --ext .ts,.tsx --fix",
"format": "prettier --write \"src/**/*.{ts,tsx,json}\"",
"clean": "rm -rf dist node_modules"
}
}
2
3
4
5
6
7
8
9
10
11
12
# 源管理
# 查看和设置源
npm config get registry # 当前源
npm config set registry https://registry.npmmirror.com # 换源
npm i <pkg> --registry https://registry.npmmirror.com # 临时指定(不动全局配置)
npm info react # 验证源是否可用
2
3
4
# 常用镜像源
| 源 | 地址 |
|---|---|
| npm 官方 | https://registry.npmjs.org |
| 淘宝镜像(推荐) | https://registry.npmmirror.com |
| 华为 | https://mirrors.huaweicloud.com/repository/npm/ |
| 腾讯 | https://mirrors.cloud.tencent.com/npm/ |
# nrm 管理源
npm i -g nrm
nrm ls # 列出所有源(* 为当前)
nrm test # 测速
nrm use taobao # 切换
nrm add company https://npm.company.com # 添加私有源
nrm del company # 删除
2
3
4
5
6
# .npmrc 配置
# 项目级(仓库根目录,随 git 分发,优先级高于用户级)
registry=https://registry.npmmirror.com
electron_mirror=https://npmmirror.com/mirrors/electron/
# 用户级(~/.npmrc)
init-license=MIT
# 认证 token(发布用)
//registry.npmjs.org/:_authToken=YOUR_TOKEN
2
3
4
5
6
7
8
9
# 缓存管理
npm config get cache # 缓存目录
npm cache verify # 校验缓存完整性
npm cache clean --force # 清理缓存(必须 --force)
2
3
缓存异常排障三板斧(lock 删除后依赖会按范围重新解析,最后手段):
npm cache clean --force
rm -rf node_modules package-lock.json
npm install
2
3
# 安全审计
npm audit # 检查漏洞
npm audit --json # JSON 报告(CI 解析用)
npm audit fix # 自动修复(范围内)
npm audit fix --force # 强制修复(可能跨大版本,破坏性变更)
npm audit --omit=dev # 只审计生产依赖
2
3
4
5
漏洞级别:low(低危)→ moderate(中危)→ high(高危)→ critical(严重)。
# 发布与维护
# 登录与预检
npm login # 登录
npm whoami # 确认身份
npm pack # 打出 tgz,验证将要发布的内容
npm logout # 登出
2
3
4
# 发布
npm publish # 发布
npm publish --tag beta # 本次发布打 dist-tag 为 beta(默认 latest)
npm publish --access public # scoped 包默认私有,需显式公开
npm unpublish <pkg>@<version> # 撤销(72 小时内且无下游依赖)
npm deprecate <pkg>@<version> "已废弃,请用 v2"
2
3
4
5
# 版本号管理
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 version prerelease # 1.0.0-0 -> 1.0.0-1(配合 publish --tag beta)
npm version 2.0.0 # 直接指定
2
3
4
5
在 git 仓库中
npm version会自动创建 commit 和 tag。
# 发布相关钩子
| 钩子 | 时机 | 典型用途 |
|---|---|---|
prepublishOnly | 仅 npm publish 前 | 构建测试,防误发布 |
preversion / version / postversion | npm version 前 / 中 / 后 | 检查 / git add / 推 tag |
{
"scripts": {
"prepublishOnly": "npm run build && npm test",
"postversion": "git push --follow-tags"
}
}
2
3
4
5
6
# 其他实用命令
# npx:执行命令,本地优先、远程兜底(无需安装)
npx [email protected] --version # 指定版本执行
npx create-vite@latest my-app # 执行远程脚手架
# link:本地包联调
cd /path/to/my-package && npm link # 注册全局软链
cd /path/to/my-project && npm link my-package # 项目内接入
npm unlink my-package # 解除
# rebuild:原生模块重建
npm rebuild bcrypt --build-from-source # 指定包强制源码编译
2
3
4
5
6
7
8
9
10
11
# 常见问题
# node/npm 版本不兼容
用 nvm 隔离多版本:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
nvm install 18 && nvm use 18
nvm alias default 18 # 设默认版本
nvm ls # 已装版本
2
3
4
# 全局安装权限不足
# 方法1(推荐):用 nvm 管理的 node 不需要 sudo
# 方法2:改全局安装目录
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
2
3
4
5
永远不要
sudo npm i -g(权限污染)。
# 依赖版本冲突
npm ls <package> # 先看冲突详情
npm 8.3+ 官方方案 overrides,强制统一传递依赖版本:
{
"overrides": {
"package-name": "1.0.0"
}
}
2
3
4
5
# 安装速度慢
npm config set registry https://registry.npmmirror.com # 换镜像源
npm i --prefer-offline # 优先用本地缓存
npm ci # CI 环境用:按 lock 精确安装,更快更可靠
2
3
更快的替代品:pnpm(硬链接共享 + 严格依赖)。
# 最佳实践
- 提交 package-lock.json,CI/服务器用
npm ci安装——严格按 lock、可重现 - 版本范围:默认
^;避免*/latest;确需锁死用精确版本 - 区分依赖类型:运行时进
dependencies,构建/测试工具进devDependencies - 定期更新:
npm outdated→npx ncu -u→npm i→npm test回归 - 钩子自动化:
prepublishOnly防误发布,prepare自动装 hooks,postversion自动推 tag