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

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

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: 使用脚本

    bash 复制代码
    curl -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.jsonpackage-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 中的 dependenciesdevDependencies,并安装所有包到 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 会自动运行 prepost 前缀的脚本。

json 复制代码
{
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "webpack",
    "postbuild": "echo 'Build finished!'"
  }
}

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

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 cinpm audit

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

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

  • 必须存在 package-lock.jsonnpm-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.jsonname 为唯一且可用(未被占用)。
  • 准备 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 权限:

    bash 复制代码
    sudo 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 日常开发工作流

  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.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> 查看内置帮助。祝开发顺利!

相关推荐
长大19881 小时前
生成器(Generators)与内存救赎:处理百万级数据导出的极简方案
后端
小强19881 小时前
构造函数属性提升的利与弊:如何优雅地编写价值对象(Value Object)
后端
二月龙1 小时前
类型系统攻防战:PHP混合类型与联合类型对隐式类型转换漏洞的防御策略
后端
掘金者阿豪2 小时前
虚拟支付 vs 聚合支付 vs 苹果内购:一文彻底讲透三种支付体系,99%的开发者都搞混了!
后端
uzong2 小时前
更简单的架构如何让我成为更好的高级开发者
后端·架构
uzong2 小时前
何时使用以及何时不应使用微服务:没有银弹
后端·架构
uzong2 小时前
架构对比:单体架构与微服务架构
后端·架构
uzong2 小时前
从单体架构到微服务架构:模式与最佳实践
后端·架构
AI攻城狮2 小时前
CLAUDE.md 的最佳实践:为什么你的配置文件基本上是废的
人工智能·后端·openai