Skip to content
On this page

npm 基础概念

理解和充分应用 npm,需要掌握其核心概念和工作机制。本章将详细介绍 npm 的核心概念和工作原理。

npm生态系统

npm 生态系统由三个主要部分组成:

  1. npm 命令行工具,可在您的计算机上运行,执行命令行操作
  2. npm 注册表,安全存储大量 JavaScript 软件包,供全球开发者使用
  3. npm 网站,用于搜索、发现和管理软件包的网页界面

npm 注册表

npm 注册表是存储开源 JavaScript 软件包的中央仓库,包含:

  • 公开包(默认)
  • 私有包(需订阅)
  • 组织包(企业级功能)

package.json 文件

package.json 是 npm 项目的核心配置文件,包含:

json
{
  "name": "项目名称",
  "version": "版本号",
  "description": "项目描述",
  "main": "入口文件",
  "scripts": {
    "脚本命令": "执行的命令"
  },
  "dependencies": {
    "运行时依赖": "版本范围"
  },
  "devDependencies": {
    "开发时依赖": "版本范围"
  },
  "keywords": ["关键词"],
  "author": "作者信息",
  "license": "许可证",
  "repository": {
    "type": "git",
    "url": "仓库地址"
  }
}

项目名称规范

  • 必须是小写字母
  • 不能包含空格
  • 不能使用特殊字符(除连字符和下划线)
  • 不能与现有包名冲突

版本号规范(SemVer)

语义化版本控制格式:MAJOR.MINOR.PATCH

  • MAJOR:破坏性变更时递增
  • MINOR:新增功能但向后兼容时递增
  • PATCH:修复bug时递增

依赖类型

dependencies

运行时必需的依赖:

bash
npm install package-name

devDependencies

开发时需要但运行时不需要的依赖:

bash
npm install package-name --save-dev

peerDependencies

对宿主环境的依赖,确保兼容性:

json
{
  "peerDependencies": {
    "react": "^17.0.0"
  }
}

optionalDependencies

可选依赖,即使安装失败也不影响项目:

json
{
  "optionalDependencies": {
    "fsevents": "^2.3.2"
  }
}

node_modules目录

当安装包时,npm会创建node_modules目录:

node_modules/
├── package-a/
│   ├── package.json
│   ├── index.js
│   └── node_modules/ (package-a的依赖)
├── package-b/
└── .bin/ (可执行文件链接)

npm使用扁平化策略来减少嵌套,但可能仍会创建嵌套结构以解决版本冲突。

package-lock.json

package-lock.json文件确保依赖树的一致性:

  • 记录精确的包版本
  • 记录依赖树结构
  • 确保团队成员安装相同依赖
  • 提高安装速度

语义化版本控制(SemVer)

版本号格式:MAJOR.MINOR.PATCH

版本前缀符号

  • ^1.2.3:允许更新到1.x.x的最新版本(不包括2.0.0)
  • ~1.2.3:允许更新到1.2.x的最新版本(不包括1.3.0)
  • 1.2.3:固定版本
  • >=1.0.0:大于等于1.0.0
  • 1.x1.*:1.x.x的任何版本
  • *:任何版本

版本范围

json
{
  "dependencies": {
    "express": ">=1.0.0 <2.0.0",
    "lodash": "1.2.3 - 2.3.4",
    "react": "17.x"
  }
}

npm脚本系统

npm脚本是定义在package.json中的命令:

json
{
  "scripts": {
    "build": "webpack --mode production",
    "dev": "webpack serve --mode development",
    "test": "jest",
    "test:watch": "jest --watch",
    "lint": "eslint src/",
    "prebuild": "npm run lint",
    "postbuild": "echo 'Build completed!'"
  }
}

脚本钩子

  • pre:在脚本执行前运行
  • post:在脚本执行后运行
  • 例如:prebuildbuild前执行

作用域包(Scoped Packages)

作用域包使用@前缀:

json
{
  "dependencies": {
    "@babel/core": "^7.0.0",
    "@angular/core": "^14.0.0"
  }
}

作用域包的特点:

  • 只能发布到npm注册表
  • 可以是公开或私有的
  • 有助于避免包名冲突

npm配置系统

npm配置可以通过多种方式设置:

配置文件层次

  1. 项目级:./.npmrc
  2. 用户级:~/.npmrc
  3. 全局级:$PREFIX/etc/npmrc
  4. npm内置:path/to/npm/npmrc

常用配置项

bash
# 设置默认作者
npm config set init-author-name "Your Name"

# 设置默认邮箱
npm config set init-author-email "email@example.com"

# 设置注册表
npm config set registry "https://registry.npmjs.org/"

# 设置缓存目录
npm config set cache "/path/to/cache"

工作区(Workspaces)

工作区允许在单个存储库中管理多个包:

json
{
  "name": "my-workspace-project",
  "workspaces": [
    "packages/*",
    "frontend",
    "backend"
  ]
}

工作区优势

  • 共享依赖
  • 简化开发流程
  • 统一版本管理
  • 支持交叉引用

npm安全模型

安全审计

npm内置安全审计功能:

bash
# 检查安全漏洞
npm audit

# 修复安全漏洞
npm audit fix

# 查看详细报告
npm audit --audit-level high

内容安全

  • 所有包都经过完整性检查
  • 使用内容哈希验证包
  • 支持包签名(实验性功能)

npm缓存机制

npm使用缓存来提高性能:

bash
# 查看缓存目录
npm config get cache

# 查看缓存统计
npm cache verify

# 清理缓存
npm cache clean --force

钩子和生命周期

npm在包安装和使用过程中提供钩子:

包脚本生命周期

  • prepublish:发布前(已弃用)
  • prepare:安装后,发布前
  • prepack / postpack:打包前后
  • preinstall / postinstall:安装前后

事件钩子

包可以定义生命周期脚本,在特定事件发生时执行。

这些基础概念构成了npm工作原理的核心,理解它们将帮助您更有效地使用npm进行包管理和项目开发。