npm 包管理器完整学习笔记

Claude Code 学习笔记 - 基础知识系列

分类:基础知识

核心主题:npm 包管理器全景学习——从基础概念到高级实践的完整指南

主要内容:全面介绍 npm 的安装配置、核心命令详解、package.json 文件结构、脚本自动化、包发布流程、安全最佳实践及与 Claude Code 的结合使用

关键词:npm, Node.js, package.json, node_modules, 包管理, JavaScript, npx, nvm, semver, lock文件, npm audit, npm publish, registry, yarn, pnpm

一、npm 概述

1.1 npm 的定位与历史

npm(Node Package Manager)是 Node.js 的官方包管理器,也是 世界上最大的软件注册中心。它于 2010 年由 Isaac Z. Schlueter 创建,随 Node.js 一起分发。npm 包含三个主要组件:

关键数据:截至 2026 年,npm registry 托管了超过 300 万个包,每周下载量超过 500 亿次,是全球最大的包生态系统之一。几乎所有现代 JavaScript 项目都依赖 npm 来管理依赖关系。

1.2 npm 与 Node.js 的关系

npm 与 Node.js 紧密集成。安装 Node.js 时会自动安装 npm,二者由 OpenJS Foundation 共同维护。npm 解决了 Node.js 开发中的核心问题:

包管理器的核心价值

在 npm 出现之前,JavaScript 开发者需要手动下载库文件并将其包含在项目中,管理依赖关系极其困难。npm 的出现彻底改变了这一局面——它通过中央 registry 和声明式 package.json 文件,将依赖管理从手动操作转变为声明式、自动化的流程。这一模式后来被 pip、RubyGems、Cargo 等几乎所有现代语言的包管理器所借鉴。

1.3 npm 生态全景

npm 生态不仅仅是一个包管理器,它构建了一个完整的 JavaScript 开发基础设施:

生态组件 说明 典型工具/平台
包注册中心 存储和分发包的中央仓库 npmjs.com, GitHub Packages, 私有 registry
命令行工具 管理包的生命周期 npm CLI, npx
包格式 标准化的包结构和元数据 package.json, node_modules
版本系统 基于 semver 的版本管理 package-lock.json, npm update
CI/CD 集成 在持续集成中使用 npm npm ci, GitHub Actions, CircleCI
安全审计 依赖安全审查和修复 npm audit, npm fund

1.4 npm vs yarn vs pnpm 对比

除了 npm,JavaScript 生态中还有其他流行的包管理器。以下是它们的核心对比:

特性 npm Yarn pnpm
发布时间 2010 2016 2017
安装策略 扁平化 node_modules 扁平化 + PnP 模式 硬链接 + 内容寻址存储
磁盘效率 中(每个项目独立安装) 中(与 npm 类似) 高(全局存储 + 硬链接)
安装速度 快(并行下载) 极快(缓存优化)
lock 文件 package-lock.json yarn.lock pnpm-lock.yaml
严格模式 默认不严格 默认不严格 严格(防止非法访问)
工作空间 支持(推荐) 支持(原生) 支持(原生)

选择建议

对于个人项目和新手,推荐使用 npm——它随 Node.js 一起安装,无需额外设置,生态系统最成熟。对于大型 monorepo 项目,推荐使用 pnpm 或 Yarn Workspaces。对于磁盘空间敏感的环境,pnpm 的硬链接方案优势明显。

二、安装与环境配置

2.1 Node.js 安装

安装 npm 的最简单方式是安装 Node.js。推荐使用以下方式:

方式一:官方安装包

访问 https://nodejs.org 下载 LTS(长期支持)版本安装包。LTS 版本经过充分测试,适合生产环境。

# 安装后验证版本 node --version # 输出示例:v22.14.0 npm --version # 输出示例:10.9.2

方式二:使用 nvm(推荐)

nvm(Node Version Manager)允许在同一台机器上安装和切换多个 Node.js 版本,是 开发环境的首选方案

# 安装 nvm(macOS/Linux) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash # 安装 nvm(Windows 使用 nvm-windows) # 下载 https://github.com/coreybutler/nvm-windows/releases # 安装指定版本的 Node.js nvm install 22 nvm install 20 # 切换默认版本 nvm alias default 22 nvm use 22 # 列出已安装版本 nvm ls

实用技巧

在项目中创建 .nvmrc 文件指定 Node.js 版本,团队成员只需运行 nvm use 即可切换到正确版本:

# .nvmrc 文件内容 22

2.2 npm 版本管理

npm 自带了更新自身的功能。不同的 Node.js 版本捆绑了不同的 npm 版本:

# 更新 npm 到最新版本 npm install -g npm@latest # 安装指定版本的 npm npm install -g npm@10.9.2 # 查看 npm 版本和帮助 npm version npm help npm

2.3 npm config 配置

npm 的配置系统非常灵活,支持多级配置(从全局到项目级别):

# 查看所有配置 npm config list -l # 设置 registry(推荐设置国内镜像加速) npm config set registry https://registry.npmmirror.com # 设置代理 npm config set proxy http://proxy.company.com:8080 npm config set https-proxy http://proxy.company.com:8080 # 设置缓存路径 npm config set cache /path/to/cache # 删除配置 npm config delete registry
镜像源配置要点:国内用户建议将 registry 设置为淘宝镜像(https://registry.npmmirror.com),通常会大幅提升包下载速度。但注意,某些企业级包发布平台(如 GitHub Packages)需要特定的 registry 配置,可以通过 --registry 参数或项目级 .npmrc 实现混合配置。

2.4 .npmrc 文件

.npmrc 是 npm 的配置文件,可以存在于多个层级,按优先级从高到低排列:

  1. 项目级:项目根目录的 .npmrc(最高优先级)
  2. 用户级:~/.npmrc(当前用户的全局配置)
  3. 全局级:npm 安装目录的 etc/npmrc
  4. 内建配置:npm 内置的默认值
# 项目级 .npmrc 示例 registry=https://registry.npmmirror.com @mycompany:registry=https://npm.mycompany.com save-exact=true audit-level=high engine-strict=true

安全警告

切勿将包含认证令牌(auth token)的 .npmrc 文件提交到版本控制系统。使用环境变量或 secrets 管理工具来存储敏感信息。建议将 .npmrc 添加到 .gitignore,或使用 .npmrc.template 作为示例文件。

三、核心命令详解

3.1 npm init —— 初始化项目

npm init 是创建新项目的起点,它会引导你生成 package.json 文件:

# 交互式初始化 npm init # 使用默认值快速初始化 npm init -y # 使用指定的初始器创建项目 npm init @vitejs/app npm init react-app my-app

npm init <initializer> 模式

npm init <initializer> 是 npm 6.1+ 引入的强大功能。当运行 npm init foo 时,npm 会自动执行 npx create-foo,创建一个模板项目。这意味着像 npm init vitenpm init next-app 等命令可以直接使用,无需全局安装脚手架工具。

3.2 npm install —— 安装依赖

这是最常用的 npm 命令,用于安装项目依赖:

# 安装 package.json 中的所有依赖 npm install # 安装包并添加到 dependencies npm install express npm install express@4.18.0 # 安装到 devDependencies npm install -D typescript # 安装全局包 npm install -g eslint # 从 package-lock.json 精确安装(CI 环境推荐) npm ci # 安装可选依赖 npm install -O fsevents
npm install vs npm ci:npm install 会根据 package.json 中的 semver 范围解析最新兼容版本,并更新 lock 文件。而 npm ci 完全按照 lock 文件安装,速度更快,适合 CI/CD 环境。在 CI 中始终使用 npm ci,不要使用 npm install,以确保构建的可重复性。

3.3 npm uninstall —— 卸载依赖

# 卸载包并从 dependencies 中移除 npm uninstall lodash # 卸载全局包 npm uninstall -g eslint # 卸载并移除所有类型的依赖 npm uninstall gulp --save-dev

3.4 npm update —— 更新依赖

根据 package.json 中定义的 semver 范围更新已安装的包:

# 更新所有依赖到最新兼容版本 npm update # 更新特定包 npm update express # 检查可更新的包 npm outdated

3.5 npm list —— 查看依赖树

# 列出当前项目的依赖树 npm list # 查看全局安装的包 npm list -g --depth 0 # 查看特定包的依赖关系 npm list express # 查看包为什么被安装 npm explain eslint

3.6 npm audit —— 安全审计

扫描项目依赖中的已知安全漏洞:

# 执行安全审计 npm audit # 自动修复可修复的漏洞(会更新 lock 文件) npm audit fix # 仅修复次要漏洞并更新 package.json npm audit fix --force # 生成 JSON 格式的报告 npm audit --json

3.7 其他重要命令

命令 功能 使用场景
npm ci 从 lock 文件精确安装 CI/CD 环境、生产部署
npm publish 发布包到 registry 发布 npm 包
npm link 本地开发时链接包 调试本地依赖
npm cache 管理 npm 缓存 清理或验证缓存
npm pack 打包为 .tgz 文件 发布前测试
npm dedupe 去重重复依赖 优化 node_modules
npm doctor 诊断环境问题 排查 npm 环境故障

四、package.json 文件

4.1 package.json 字段详解

package.json 是 npm 项目的核心元数据文件,位于项目根目录:

{ "name": "my-project", "version": "1.0.0", "description": "An example project", "main": "index.js", "scripts": { "start": "node index.js", "test": "jest" }, "keywords": ["npm", "learning"], "author": "Your Name", "license": "MIT", "dependencies": { "express": "^4.18.0" }, "devDependencies": { "typescript": "^5.0.0" } }
字段 说明 是否必需
name 包名称,必须唯一且符合命名规范(小写、连字符) 是(发布时需要)
version 当前版本号,遵循 semver 规范 是(发布时需要)
description 包的简短描述,有利于搜索结果 推荐
main 包的入口文件路径 推荐
scripts 可执行的 npm 脚本定义 常用
dependencies 生产环境依赖 常用
devDependencies 开发环境依赖(测试、构建工具等) 常用
peerDependencies 宿主依赖(插件开发时指定) 特定场景
engines 指定兼容的 Node.js 版本 推荐

4.2 semver 版本号规范

语义化版本(Semantic Versioning)

semver 格式为 主版本号.次版本号.补丁号(如 4.18.2)。版本变更的含义:

  • 主版本号(Major):做了不兼容的 API 修改
  • 次版本号(Minor):向下兼容的功能新增
  • 补丁号(Patch):向下兼容的问题修复

npm 支持多种版本范围的写法:

写法 含义 示例匹配
^4.18.0 兼容主版本,允许更新次版本和补丁 4.18.0 ~ 4.x.x(不含 5.0.0)
~4.18.0 兼容次版本,只允许补丁更新 4.18.0 ~ 4.18.x
4.18.0 精确版本,不允许任何偏差 仅 4.18.0
>=4.18.0 <5.0.0 范围表达式 4.18.0 ~ 4.x.x
* 任意版本 任何版本
latest 最新发布的版本 registry 中的最新版本

版本锁定策略

生产环境 中,建议使用 lock 文件(package-lock.json)来锁定所有依赖的精确版本。在 开发库 中,dependencies 应使用宽松的版本范围(如 ^),以兼容宿主项目的版本。使用 npm config set save-exact=true 可以在安装时自动保存精确版本。

4.3 dependencies vs devDependencies

理解二者的区别至关重要:

使用 npm install --production 或设置 NODE_ENV=production 时,只有 dependencies 会被安装,这在 CI/CD 部署流程中可以显著减少安装时间和磁盘占用。

4.4 lock 文件(package-lock.json)

package-lock.json 是在调用 npm install 时自动生成的文件,记录了依赖树的 精确版本和完整性哈希值。它的核心作用:

关键提醒

package-lock.json 必须被提交到版本控制系统中!这是确保团队成员和生产环境使用相同依赖版本的关键。不要将 lock 文件添加到 .gitignore 中。如果 lock 文件未被跟踪,每个开发者可能安装到不同的依赖版本,导致"在我机器上能运行"的问题。

五、npm 脚本与自动化

5.1 scripts 基础

scripts 字段是 package.json 中最强大的功能之一,它允许开发者定义一系列可以通过 npm run 执行的命令:

{ "scripts": { "start": "node index.js", "dev": "nodemon index.js", "build": "tsc && vite build", "test": "jest --coverage", "lint": "eslint src/", "format": "prettier --write src/", "precommit": "npm run lint && npm run test" } }

npm 为一些常用命令提供了简写:npm startnpm testnpm stopnpm restart 可以直接运行,无需 run 关键字。

5.2 pre/post 生命周期钩子

npm 会自动为每个脚本生成 prepost 钩子。当运行 npm run build 时,npm 会按以下顺序自动执行:

  1. prebuild —— 构建前执行的脚本
  2. build —— 主构建脚本
  3. postbuild —— 构建后执行的脚本
{ "scripts": { "prebuild": "echo '清理构建目录...' && rm -rf dist", "build": "vite build", "postbuild": "echo '构建完成,开始部署...' && ./deploy.sh", "pretest": "npm run lint", "test": "jest", "posttest": "echo '测试完成,生成覆盖率报告'" } }

生命周期事件

npm 定义了多个内置生命周期事件。除了 buildtest,以下生命周期也支持 pre/post 钩子:installuninstallpublishversionpackshrinkwrap 等。这些钩子可以用来自动化版本管理(如发布前自动运行测试、更新 changelog 等)。

5.3 npx 使用

npx 是 npm 5.2+ 自带的包执行工具。它允许直接运行 npm registry 中的包,而无需事先安装:

# 直接执行包,无需安装 npx create-react-app my-app npx degit user/repo my-project # 执行指定版本的包 npx typescript@5.0 --version # 从本地 node_modules 执行 npx eslint src/ # 强制使用本地安装的版本(而非缓存) npx --no-install eslint src/ # 使用不同的 registry npx --registry https://registry.npmmirror.com create-react-app my-app
npx 的核心价值:npx 取代了全局安装工具包的做法。使用 npx create-react-app 而不是 npm install -g create-react-app 可以避免全局包版本冲突,且每次使用都能获取最新版本。在 CI 环境中,npx 可以避免安装不必要的全局工具,减少构建时间。

5.4 常用脚本模式

模式 脚本示例 说明
开发服务器 "dev": "vite" 启动热重载开发服务器
生产构建 "build": "tsc && vite build" 先编译 TS 再构建
并行任务 "dev": "concurrently \"npm run server\" \"npm run client\"" 同时运行前后端
参数传递 "test": "jest --passWithNoTests" 传递额外参数 npm run test -- --watch(使用 -- 分隔)
环境变量 "start": "NODE_ENV=production node index.js" 设置环境变量(Windows 需要 cross-env

cross-env 跨平台兼容

由于 Windows 和 Unix 系统设置环境变量的语法不同(SET NODE_ENV=production vs NODE_ENV=production),推荐使用 cross-env 包实现跨平台兼容:

npm install -D cross-env # 然后脚本中写道: "start": "cross-env NODE_ENV=production node index.js"

六、包发布与版本管理

6.1 npm 账号管理

要发布 npm 包,首先需要注册 npm 账号:

# 创建账号(或访问 npmjs.com 注册) npm adduser # 登录已有账号 npm login # 查看当前登录用户 npm whoami # 退出登录 npm logout

安全警告

切勿在 CI 配置或代码中硬编码 npm token。使用 CI/CD 平台提供的 secrets 管理功能(如 GitHub Secrets)来存储 NPM_TOKEN。在 .npmrc 中使用 //registry.npmjs.org/:_authToken=${NPM_TOKEN} 引用环境变量。

6.2 发布流程

发布一个 npm 包的标准流程:

  1. 准备包:确保 package.json 包含 nameversionmain 等必要字段
  2. 测试打包:运行 npm pack 生成 .tgz 文件,检查包内容是否正确
  3. 版本更新:使用 npm version 命令更新版本号
  4. 发布:运行 npm publish
# 更新版本号(自动修改 package.json 并创建 git tag) npm version patch # 1.0.0 -> 1.0.1 npm version minor # 1.0.1 -> 1.1.0 npm version major # 1.1.0 -> 2.0.0 # 发布包 npm publish # 发布公开包 npm publish --access public # 发布测试版本 npm publish --tag beta # 测试打包内容 npm pack --dry-run

6.3 版本号规范与 tag

npm 的 dist-tag 机制允许为同一包的不同版本添加标签:

标签 用途 说明
latest 最新稳定版 默认标签,npm install 安装此版本
next 下一个候选版本 发布预发布版本时使用
beta Beta 测试版 需要社区测试的新功能
alpha 内部测试版 不稳定的早期版本
legacy 旧版维护 已弃用的旧版本
# 设置标签 npm dist-tag add my-package@2.0.0-beta.1 beta # 查看当前标签 npm dist-tag ls my-package # 安装特定标签的版本 npm install my-package@beta # 移除标签 npm dist-tag rm my-package beta

6.4 弃用与组织范围包

弃用(Deprecate)

当包不再维护或存在安全问题时,应弃用特定版本:

# 弃用特定版本 npm deprecate my-package@1.0.0 "此版本存在安全问题,请升级" # 弃用所有版本 npm deprecate my-package "不再维护,请迁移到 new-package"

组织范围包(Scoped Packages)

命名格式为 @组织名/包名,如 @angular/core@vue/cli

# package.json 中使用 scope npm init --scope=my-org # 默认私有包需要付费,使用 --access public 发布公开 scope 包 npm publish --access public # 配置组织 registry(用于私有包) npm config set @my-org:registry https://npm.mycompany.com

七、安全与最佳实践

7.1 npm audit 与安全审查

npm 内置了强大的安全审计功能:

审计分级:npm audit 将漏洞分为四个等级:Critical(严重)、High(高)、Moderate(中等)、Low(低)。可以通过 --audit-level 设置报告阈值,例如 npm audit --audit-level=high 只在存在高或严重漏洞时退出码为非零。

7.2 权限最小化原则

遵循最小权限原则来管理 npm 操作:

# 配置全局安装路径(避免 sudo) npm config set prefix ~/.npm-global echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc # 创建 publish-only token # 在 npmjs.com -> Access Tokens -> Generate New Token -> 选择 Publish # 验证已安装包的完整性 npm audit signatures

7.3 锁文件管理

锁文件最佳实践

  • 始终提交 package-lock.json:确保所有环境使用相同的依赖版本
  • 代码审查时检查 lock 文件:lock 文件的变更应随代码审查一起进行
  • 使用 npm ci 而非 npm install:在 CI/CD 环境中严格锁定版本
  • 定期更新依赖:使用 npm outdated 查看可更新依赖,有计划地升级

7.4 registry 安全

使用第三方 registry 时需要注意安全问题:

安全措施 说明 实现方式
HTTPS 通信 确保 registry 通信加密 默认 npm registry 使用 HTTPS
完整性校验 验证包内容未被篡改 lock 文件中的 integrity 哈希值
签名验证 验证发布者身份 npm registry 支持包签名
私有 registry 企业内部包隔离 Verdaccio、GitHub Packages、AWS CodeArtifact
依赖审查 防止恶意包混入 Socket.dev、npm audit、Snyk

供应链安全

npm 生态的开放性也带来了供应链攻击的风险。典型风险包括:依赖混淆攻击(将恶意包发布到公共 registry,名称与内部私有包相同)、恶意包名混用(如 event-stream 被植入恶意代码)。应对措施:使用 --registry 明确作用域包的 registry 来源,定期审计依赖,使用 npm fund 了解包的维护状况。

7.5 最佳实践清单

npm 安全最佳实践

  1. 提交 lock 文件:始终将 package-lock.json 纳入版本控制
  2. 使用 npm ci:CI/CD 中只使用 npm ci 而非 npm install
  3. 定期审计:npm audit 集成到 CI 流程中
  4. 最小依赖原则:引入新依赖前慎重评估其必要性
  5. 固定版本范围:生产环境使用精确版本或 ^ 范围
  6. 引擎限制:package.json 中设置 engines 字段
  7. 启用 2FA:npm 账号开启双因素认证
  8. 检查维护状态:使用 npm outdatednpm fund 了解包的健康状况
  9. 避免全局安装:npx 替代全局工具安装
  10. 使用 .npmrc 分层:项目级、用户级配置分离

八、与 Claude Code 的结合

8.1 在 Claude Code 中使用 npm

Claude Code 可以自动执行 npm 命令来管理项目依赖。以下是在 Claude Code 工作流中使用 npm 的典型场景:

# Claude Code 可以自动执行这些命令 # 初始化 Node.js 项目 npm init -y # 安装依赖 npm install express mongoose dotenv npm install -D typescript @types/node jest # 运行项目脚本 npm run dev npm test npm run build # 安全审计 npm audit
工作流优势:在 Claude Code 中使用 npm,你只需要用自然语言描述需求(如"安装 Express 和 TypeScript 依赖"),Claude Code 就会自动执行相应的 npm 命令。这大大简化了项目初始化和依赖管理的操作步骤。

8.2 自动安装依赖

在 Claude Code 中,当你编写代码并使用了一个 npm 包时,可以通过以下方式让 Claude Code 自动安装依赖:

提示词技巧

在 Claude Code 中,使用以下提示词可以获得更好的 npm 管理体验:

  • "创建一个 Node.js 项目,初始化 npm,安装 express 和 typescript"
  • "检查当前项目的依赖是否有安全漏洞,并帮我修复"
  • "更新所有依赖到最新兼容版本"
  • "为这个项目生成一个完整的 package.json,包含 scripts 脚本"
  • "帮我分析 node_modules 的大小,找出占用空间最大的几个包"

8.3 package.json 生成

Claude Code 可以根据项目需求自动生成完整的 package.json 文件:

{ "name": "claude-code-npm-demo", "version": "1.0.0", "description": "A demo project created with Claude Code", "main": "dist/index.js", "scripts": { "dev": "tsx watch src/index.ts", "build": "tsc", "start": "node dist/index.js", "test": "vitest run", "lint": "eslint src/" }, "engines": { "node": ">=18.0.0" } }

8.4 常见问题排查

问题 原因 解决方案
安装慢或失败 网络问题、registry 访问慢 切换到国内镜像:npm config set registry https://registry.npmmirror.com
版本冲突 依赖包的 semver 范围不兼容 使用 npm ls <package> 查看依赖树,使用 npm dedupe 去重
缺失依赖 peerDependencies 未安装 运行 npm install --legacy-peer-deps 或手动安装 peer 依赖
权限错误 全局安装时权限不足 配置 npm prefix 到用户目录,避免使用 sudo
lock 文件冲突 多人修改 package.json 导致 lock 文件不一致 运行 npm install 重新生成 lock 文件
ENOENT 错误 node_modules 损坏或缓存问题 删除 node_modules 和 lock 文件,重新安装

Claude Code 中的故障排查流程

当遇到 npm 相关问题时,可以指示 Claude Code 按以下顺序排查:先检查 Node.js 和 npm 版本是否匹配 → 检查 registry 配置是否正确 → 检查 package.json 格式 → 删除 node_modules 和 lock 文件重新安装 → 使用 npm cache clean --force 清理缓存。这种系统化的排查方法可以高效地解决大多数 npm 问题。

九、核心要点总结

npm 包管理器:关键要点

  1. 生态基石:npm 是 JavaScript 生态系统的核心基础设施,托管超过 300 万个包,每周下载量超 500 亿次。理解 npm 是成为合格的 JavaScript 开发者的基本要求。
  2. 版本管理是核心能力:semver 语义化版本规范是 npm 的基石。理解 ^~、精确版本的区别,以及 lock 文件的作用,是避免"依赖地狱"的关键。
  3. package.json 是项目蓝图:从依赖声明到脚本配置,package.json 不仅是元数据文件,更是驱动整个开发工作流的配置文件。合理利用 scripts 可以大幅提升开发效率。
  4. 安全不容忽视:npm 生态的开放性带来了供应链安全风险。定期执行 npm audit、启用 2FA、提交 lock 文件、使用 npm ci 是最基本的安全实践。
  5. CI/CD 集成:在持续集成环境中始终使用 npm ci 而非 npm install,确保构建的可重复性和速度。
  6. 工具选择:npm、yarn、pnpm 各有优劣。npm 适合大多数场景,pnpm 在大项目和 monorepo 中表现更优,yarn 在特定工作流中有其独特优势。
  7. npx 是新时代的执行器:使用 npx 可以避免全局安装工具的混乱,确保每次使用最新版本,是现代 JavaScript 开发的标准实践。
  8. 与 Claude Code 协同:通过自然语言指令即可完成依赖安装、脚本运行、安全审计等操作,大幅降低 npm 的使用门槛。
学习心得:npm 作为 JavaScript 生态的"包管家",其设计哲学深刻影响了现代软件开发——声明式依赖、语义化版本、可重复构建、安全审计等理念已成为业界标准。掌握 npm 不仅是学习一个工具,更是理解现代软件工程的最佳实践。无论你是前端、后端还是全栈开发者,深入理解 npm 都将使你受益终生。