12k
All articles

使用 Nx 进行 Monorepo 管理入门指南

介绍如何搭建 Nx monorepo 工作区,管理 React 应用,共享代码库,并通过智能缓存和 affected 命令优化构建速度。

OpenReplay Team
OpenReplay Team
使用 Nx 进行 Monorepo 管理入门指南

管理多个相关项目很快就会变得复杂。随着代码库的增长,您需要工具来帮助维护一致性、高效共享代码并优化构建时间。Nx 是专门为这些挑战而设计的强大解决方案。

本指南将向您展示如何设置和使用 Nx 来有效管理 monorepo。您将学习核心概念、创建基本工作区,并了解 Nx 的智能功能如何显著改善您的开发工作流程。

核心要点

  • Nx 通过强大的依赖跟踪、缓存和代码生成功能简化了 monorepo 管理
  • 项目图表帮助可视化代码库中组件之间的关系
  • 受影响的命令通过仅构建和测试已更改的内容来节省时间
  • 共享库实现了跨应用程序的高效代码重用
  • 智能缓存显著加快了开发和 CI 环境中的构建速度

什么是 Monorepo?

Monorepo 是一种版本控制策略,其中多个项目存储在单个仓库中。与为每个项目设置单独仓库(polyrepo)不同,monorepo 将所有相关项目包含在一个地方。

Monorepo 的优势

  • 代码共享 - 在项目间重用代码,无需复杂的包管理
  • 原子性更改 - 在单个提交中更新多个项目
  • 一致的工具 - 在所有项目中应用相同的开发标准
  • 简化的依赖关系 - 在一个地方管理项目关系
  • 协调发布 - 同步相互依赖项目的更新

然而,monorepo 也带来了挑战,如管理构建依赖关系和随着代码库增长而扩展。这就是 Nx 的用武之地。

什么是 Nx?

Nx 是专门为 monorepo 管理设计的可扩展构建系统。最初为 Angular 应用程序开发,Nx 现在支持多种前端和后端框架,包括 React、Vue、Node.js 等。

Nx 的主要特性

  • 智能缓存 - 避免重新构建未更改的代码
  • 依赖图 - 可视化项目之间的关系
  • 受影响的命令 - 仅构建和测试受更改影响的内容
  • 代码生成器 - 创建一致的项目结构
  • 可扩展插件 - 支持各种框架和工具

设置您的第一个 Nx 工作区

让我们创建一个带有 React 应用程序和共享库的基本 Nx 工作区。

前置条件

  • Node.js (v14 或更高版本)
  • npm 或 yarn

创建 Nx 工作区

# 全局安装 Nx CLI(可选)
npm install -g nx

# 创建新工作区
npx create-nx-workspace@latest my-workspace

在设置过程中,您将被提示选择:

  1. 使用哪个技术栈(选择 “React”)
  2. 应用程序名称(例如 “web-app”)
  3. 样式格式(CSS、SCSS 等)
  4. Nx Cloud 设置(可选但推荐用于团队项目)

这将创建一个具有以下结构的工作区:

my-workspace/
├── apps/
│   └── web-app/
├── libs/
├── nx.json
├── package.json
└── tsconfig.base.json

理解工作区结构

  • apps/ - 包含您的应用程序(前端、后端、移动端)
  • libs/ - 保存跨应用程序使用的共享代码库
  • nx.json - 配置 Nx 行为和插件
  • package.json - 管理整个工作区的依赖项

向工作区添加项目

现在让我们添加一个共享 UI 库,看看 Nx 如何管理依赖关系。

创建共享库

nx g @nx/react:lib ui-components

这会在 libs/ui-components/ 中创建一个库,可以被工作区中的任何应用程序导入。

在库中创建组件

nx g @nx/react:component button --project=ui-components --export

这会在您的 UI 库中生成一个 Button 组件,并导出它以供其他项目使用。

在应用程序中使用库

编辑您的应用程序以使用新组件:

// apps/web-app/src/app/app.tsx
import { Button } from '@my-workspace/ui-components';

export function App() {
  return (
    <div>
      <h1>Welcome to My App</h1>
      <Button>Click me</Button>
    </div>
  );
}

使用 Nx 运行任务

Nx 提供了一种统一的方式来跨项目运行任务。

常用命令

# 启动开发服务器
nx serve web-app

# 构建应用程序
nx build web-app

# 运行测试
nx test web-app

# 代码检查
nx lint web-app

为所有项目运行任务

nx run-many --target=build --all

利用 Nx 的智能功能

随着工作区的增长,Nx 的强大功能变得明显。让我们探索其最有价值的功能。

可视化项目依赖关系

nx graph

这会打开项目依赖关系的交互式可视化,帮助您理解 monorepo 的架构。

理解受影响的项目

当您进行更改时,Nx 可以确定哪些项目受到影响:

nx affected:graph

这只显示受您最近更改影响的项目。

仅构建已更改的内容

nx affected --target=build

这只构建受您更改影响的项目,在 CI/CD 管道中节省大量时间。

缓存以提高速度

Nx 自动缓存任务结果。如果您使用相同的输入运行相同的任务,Nx 会使用缓存结果而不是重新运行:

# 首次运行(执行任务)
nx build web-app

# 第二次运行(使用缓存)
nx build web-app

Nx 工作区配置

nx.json 文件控制 Nx 的行为。以下是基本配置:

{
  "npmScope": "my-workspace",
  "affected": {
    "defaultBase": "main"
  },
  "tasksRunnerOptions": {
    "default": {
      "runner": "nx/tasks-runners/default",
      "options": {
        "cacheableOperations": ["build", "lint", "test", "e2e"]
      }
    }
  },
  "targetDefaults": {
    "build": {
      "dependsOn": ["^build"]
    }
  }
}

关键设置:

  • npmScope - 导入库的前缀
  • affected.defaultBase - 要比较的 git 分支
  • cacheableOperations - 应该被缓存的任务
  • dependsOn - 任务依赖关系(例如,在应用程序之前构建库)

实际示例:全栈应用程序

让我们创建一个更完整的示例,包含 React 前端和 Node.js 后端:

# 创建 React 应用
nx g @nx/react:app client

# 创建 Node.js API
nx g @nx/node:app api

# 创建共享类型库
nx g @nx/js:lib shared-types

这为您提供了一个包含以下内容的工作区:

  1. React 客户端应用程序
  2. Node.js API 服务器
  3. 用于通用类型的共享库

您可以同时运行两个应用程序:

nx run-many --target=serve --projects=api,client --parallel

结论

Nx 使 monorepo 管理变得简单高效。通过处理项目依赖关系和构建优化的复杂性,它让您专注于编写代码而不是管理仓库结构。从本指南中显示的简单设置开始,随着项目的增长而扩展。

常见问题

Nx 与其他 monorepo 工具如 Lerna 或 Turborepo 有何不同?

Nx 提供更高级的功能,如计算缓存、受影响的命令和代码生成。它还提供更好的可视化工具,并开箱即用地支持更多框架。

我可以将现有项目迁移到 Nx 吗?

是的,Nx 提供工具来在现有项目中逐步采用它。您可以从在仓库中添加 Nx 开始,然后逐步将项目移动到 Nx 工作区结构中。

Nx 是否适用于任何 CI/CD 系统?

是的,Nx 适用于所有主要的 CI/CD 系统。它为 GitHub Actions、CircleCI 和其他系统提供特定的集成,以使用其缓存功能优化构建时间。

Nx 如何处理 monorepo 中的版本控制?

Nx 通过像 @nx/npm-package 这样的插件支持统一版本控制(所有项目共享相同版本)和独立版本控制(每个项目有自己的版本)。

Nx 只适用于 JavaScript/TypeScript 项目吗?

虽然 Nx 在 JavaScript 和 TypeScript 方面效果最好,但它通过插件支持其他语言。对 Go、Python 和其他语言的支持正在增长。

我可以将 Nx 用于单个项目吗?

是的,Nx 可以用于独立项目,以利用其缓存、任务运行和代码生成功能,即使没有多个项目。

Listen to your bugs 🧘, with OpenReplay

See how users use your app and resolve issues fast.
Loved by thousands of developers

We use cookies to improve your experience. By using our site, you accept cookies.