npm 基础认知与环境准备(超详细版)

5 阅读5分钟

本指南将从零开始,全面介绍 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

  1. 访问 Node.js 官网
  2. 点击 LTS 版本(如 20.11.0)下载对应安装包
    • Windows: .msi.exe
    • macOS: .pkg 或通过 Homebrew brew install node
    • Linux: 使用包管理器(如 apt install nodejs npm)或 nvm
  3. 运行安装程序,一路默认选项(建议勾选 Add to PATH

验证安装

打开终端(Windows 使用 cmdPowerShell,macOS/Linux 使用 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: 使用脚本
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
    

安装并切换 Node.js

# 列出所有可用的 LTS 版本
nvm list-remote --lts

# 安装最新的 LTS 版本
nvm install --lts

# 切换到该版本
nvm use --lts

# 验证
node -v   # v20.11.0

3. npm 初次运行与基础配置

安装 Node.js 后,npm 已有默认配置。我们可以根据网络环境和个人习惯进行优化。

3.1 查看所有配置

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 已迁移)

# 查看当前源
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

有时因权限问题,需要自定义路径(例如用户目录下)。

# 创建全局目录
mkdir ~/.npm-global

# 配置 npm 使用该目录
npm config set prefix '~/.npm-global'

# 将该目录添加到系统 PATH(需要编辑 ~/.bashrc 或 ~/.zshrc)
export PATH=~/.npm-global/bin:$PATH
source ~/.bashrc

3.4 设置缓存路径

npm 下载的包会缓存到本地,下次使用时加快速度。

# 查看当前缓存目录
npm config get cache

# 设置自定义缓存目录
npm config set cache ~/.npm-cache

3.5 配置代理(工作环境需要)

# 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)。你也可以直接编辑该文件:

registry=https://registry.npmmirror.com
prefix=~/.npm-global
cache=~/.npm-cache

4. npm 初始化项目:npm init

任何使用 npm 管理的项目,根目录下都必须包含一个 package.json 文件。通过 npm init 可以快速生成。

4.1 基础初始化

# 进入项目文件夹
mkdir my-project
cd my-project

# 交互式创建 package.json
npm init

你会被问到一系列问题:

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 快速初始化(跳过交互)

npm init -y   # 或 --yes

这会使用默认值生成一个 package.json,稍后可手动编辑。

4.3 生成的 package.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.jsonpackage-lock.json

# 安装最新版本的 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 中的变化:

"dependencies": {
  "lodash": "^4.17.21"
},
"devDependencies": {
  "jest": "^29.7.0"
}

5.2 全局安装

包会安装到全局路径(如 /usr/local/lib/node_modules),命令工具链接到 PATH,任何地方都可直接调用。

⚠️ 注意:全局安装的包不能在项目中通过 require() 引入,除非你设置了 NODE_PATH。主要用于 CLI 工具。

# 全局安装 yarn
npm install --global yarn   # 简写: -g

# 全局安装特定版本
npm install -g npm@9.0.0

# 查看全局安装的包
npm list -g --depth=0

5.3 根据 package.json 安装所有依赖

当你克隆一个现有项目后,运行:

npm install   # 或 npm i

npm 会读取 package.json 中的 dependenciesdevDependencies,并安装所有包到 node_modules,同时生成/更新 package-lock.json

5.4 仅安装生产依赖(跳过 devDependencies)

# 生产环境部署时常用
npm install --only=production   # 或 --omit=dev

5.5 强制重新安装(清除缓存后)

# 先删除 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

实际例子

"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 更新依赖

# 检查哪些包可以更新(不实际安装)
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 卸载依赖

# 卸载本地依赖(并从 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 查看已安装的包

# 查看当前项目的所有依赖(树状结构)
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 仓库

# 在注册表中搜索包
npm search axios
npm search "webpack plugin"

# 或访问官网 https://www.npmjs.com/search

7.5 查看包的详细信息

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

# 查看包的最新版本
npm view lodash version

# 查看包的完整信息(包括依赖、主页、维护者等)
npm view lodash

8. npm scripts 脚本

package.json 中的 "scripts" 字段可以运行自定义命令,极大简化开发流程。

8.1 定义脚本

{
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "test": "jest",
    "build": "webpack --mode production",
    "lint": "eslint src/",
    "prepare": "npm run build"   // 生命周期钩子
  }
}

8.2 运行脚本

npm run dev
npm run build
npm test        # 'test' 可以省略 run
npm start       # 'start' 可以省略 run

8.3 预钩子与后钩子

npm 会自动运行 prepost 前缀的脚本。

{
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "webpack",
    "postbuild": "echo 'Build finished!'"
  }
}

执行 npm run build 时会依次运行:prebuildbuildpostbuild

8.4 传递参数给脚本

使用 -- 分隔符。

{
  "scripts": {
    "mocha": "mocha"
  }
}
npm run mocha -- --reporter spec  # 实际执行: mocha --reporter spec

8.5 跨平台兼容性

  • Windows 不支持 NODE_ENV=production,但可以使用 cross-env 包。
npm install --save-dev cross-env
{
  "scripts": {
    "start": "cross-env NODE_ENV=production node server.js"
  }
}

9. 依赖管理进阶:npm cinpm audit

9.1 npm ci —— 快速、严格的安装

适用于持续集成(CI)环境或必须保证依赖完全一致的情况。

  • 必须存在 package-lock.jsonnpm-shrinkwrap.json
  • 删除 node_modules 再进行全新安装
  • 严格按照 lock 文件安装,不会修改 package.json 或 lock 文件
  • npm install 快得多(跳过解析)
# 在 CI 服务器或部署前执行
npm ci

9.2 npm audit —— 检查安全漏洞

分析依赖树,报告已知漏洞并提供自动修复建议。

# 扫描漏洞
npm audit

# 自动修复可修复的漏洞(会升级依赖版本)
npm audit fix

# 只修复不破坏 semver 的漏洞
npm audit fix --only=prod

# 强制升级到最新版本(可能破坏兼容性)
npm audit fix --force

10. 发布自己的 npm 包

如果你开发了一个可复用的模块,可以发布到 npm 公共仓库供他人使用。

10.1 注册账号

访问 npmjs.com 注册,或者命令行注册:

npm adduser
# 输入用户名、密码、邮箱

10.2 登录

npm login

10.3 准备发布内容

  • 确保 package.jsonname 为唯一且可用(未被占用)。
  • 准备 README.md,这是包的文档主页。
  • 确定版本号(通常手动修改 version 字段)。
  • 可选:编写 .npmignore 文件忽略不需要上传的文件(如 test/.git)。

10.4 发布

# 当前目录发布
npm publish

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

10.5 更新版本与再次发布

遵循 Semver 规则修改版本后再发布。

# 手动修改 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 小时内可撤销)

npm unpublish my-package@1.0.0

⚠️ 官方强烈不建议撤销已发布的包,因为会被其他项目依赖。可以改为弃用:

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 权限:
    sudo chown -R $(whoami) ~/.npm
    sudo chown -R $(whoami) /usr/local/lib/node_modules
    

11.2 依赖冲突

现象npm ERR! code ERESOLVE 或版本无法满足。
解决

# 强制执行(不推荐,可能导致运行时错误)
npm install --legacy-peer-deps

# 或使用旧版 peerDep 处理方式
npm install --force

# 最好的办法是升级相关依赖或使用 overrides(npm 8.3+)

package.json 中可使用 overrides 强制指定版本:

{
  "overrides": {
    "lodash": "4.17.21"
  }
}

11.3 网络超时或 SSL 错误

设置更大的超时或切换源:

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 调试日志

npm install --verbose
# 或查看错误日志文件 ~/.npm/_logs/

11.5 清除缓存

npm cache clean --force   # 一般不需要,除非缓存损坏
npm cache verify          # 检查完整性

12. 总结与最佳实践

12.1 日常开发工作流

  1. 新建项目:mkdir project && cd project && npm init -y
  2. 安装依赖:npm install express --savenpm install jest --save-dev
  3. 编写代码,使用脚本:npm startnpm test
  4. 版本控制:提交 package.jsonpackage-lock.json(切勿忽略 lock 文件)
  5. 团队协作:同事克隆后执行 npm ci 而非 npm install
  6. 定期更新: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.jsonnpm 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> 查看内置帮助。祝开发顺利!