全部学科
Python全栈
python
NodeJS全栈
nodejs
📅 2026-05-25 8 分钟 ✍️ juanwangdev

npm workspaces与Monorepo管理

npm workspaces 是 NPM 原生支持的 Monorepo 方案,无需额外工具即可管理多包仓库。

npm workspaces配置

基本目录结构

JSON
my-monorepo/
├── package.json          # 根配置
├── packages/
│   ├── utils/
│   │   └── package.json  # @my/utils
│   ├── core/
│   │   └── package.json  # @my/core
│   └── cli/
│       └── package.json  # @my/cli
└── node_modules/         # 统一提升到根目录

workspaces 声明

Bash
// 根 package.json
{
  "name": "my-monorepo",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

private: true 防止根包被误发布。workspaces 支持 glob 模式,也可显式列出路径数组。

初始化工作区

Bash
# 在已有项目中启用 workspaces
npm init -w packages/utils

# 从零创建 monorepo
mkdir my-monorepo && cd my-monorepo
npm init -y
# 编辑 package.json 添加 workspaces 字段
npm install

查看工作区状态

JSON
# 列出所有工作区
npm ls -a --depth=0

# 查看工作区依赖树
npm ls --all

# 查看特定工作区信息
npm query ".workspace"

npm install 在根目录执行时,自动将所有工作区依赖提升到根 node_modules,工作区之间通过符号链接关联。

工作区依赖管理

工作区内部依赖

Bash
// packages/core/package.json
{
  "name": "@my/core",
  "dependencies": {
    "@my/utils": "workspace:*"
  }
}
  • workspace:* 声明对同一 monorepo 内部包的依赖
  • NPM 自动创建符号链接 node_modules/@my/utils -> packages/utils
  • 发布时 workspace:* 会被替换为实际版本号
Bash
# 为特定工作区添加依赖
npm install lodash -w @my/core

# 添加开发依赖
npm install -D jest -w @my/core

外部依赖提升机制

Bash
# 查看依赖提升情况
npm ls lodash
# ├─┬ @my/core
# │ └── lodash@4.17.21
# └─┬ @my/cli
#   └── lodash@4.17.21 deduped
  • 多个工作区引用同一外部包时,NPM 自动提升到根 node_modules
  • 版本冲突时,各自安装在自己的 node_modules

工作区依赖版本一致性

JSON
# 检测版本不一致
npm ls lodash --depth=0
# 若出现多个版本,使用 dedupe 合并
npm dedupe

不同工作区依赖同一包的不同主版本会导致重复安装,增加体积。团队应约定共享依赖版本。

工作区发布配置

Bash
// packages/utils/package.json
{
  "name": "@my/utils",
  "version": "1.0.0",
  "main": "dist/index.js",
  "files": ["dist"],
  "publishConfig": {
    "access": "public",
    "registry": "https://registry.npmjs.org"
  }
}

发布前确认 files 字段白名单,避免源码或测试文件泄露。publishConfig 覆盖发布目标。

工作区脚本批量执行

批量运行脚本

Bash
# 在所有工作区执行 build
npm run build -ws

# 在指定工作区执行
npm run test -w @my/core

# 按依赖拓扑顺序执行
npm run build -ws --if-present

-ws 在所有工作区执行,-w <name> 在指定工作区执行。--if-present 跳过未定义该脚本的工作区。

脚本执行顺序控制

Bash
# 并行执行(默认)
npm run test -ws

# 串行执行
npm run build -ws --workspaces-sort=topological

# 从特定工作区开始(含依赖)
npm run build -w @my/cli
# 自动先 build @my/utils -> @my/core -> @my/cli

工作区过滤

JSON
# 排除特定工作区
npm run test -ws --workspace-exclude @my/cli

# 使用 npm query 过滤
npm query ".workspace[name=@my/core]" --json

根脚本编排

text
// 根 package.json
{
  "scripts": {
    "build": "npm run build -ws",
    "test": "npm run test -ws",
    "clean": "npm run clean -ws && rimraf node_modules",
    "lint": "npm run lint -ws --if-present"
  }
}

根脚本作为统一入口,开发者无需关心工作区内部细节。CI 中直接调用根脚本即可。

要点总结

  • workspaces 在根 package.json 声明,支持 glob 匹配,根包必须 private: true
  • 内部依赖用 workspace:*,NPM 自动符号链接,发布时替换为实际版本
  • 外部依赖自动提升到根 node_modules,版本冲突时各自安装
  • -ws 批量执行脚本,-w <name> 执行指定工作区,--if-present 跳过无脚本的工作区
  • 根脚本统一编排,CI 直接调用根脚本,无需感知工作区结构
想在手机上练习这篇文章的配套题目?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码
← 上一篇 NPM供应链攻击与防护
下一篇 → npm完整生命周期流程
扫码体验小程序
加载中
想在手机上刷题学习?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码