Monorepo架构: Lerna、NX、Turbo等对比与应用分析

news2025/6/6 18:38:40

概述

  • 对于大型的 Monorepo 项目来说,Nx 绝对算是神器,在包管理和版本控制部分有优势
  • 对于大型 Monorepo 项目,Nx 是非常实用的工具,在包管理、版本控制以及构建、测试优化等方面都有一定作用
  • 下面我们来对比一下这几种工具

NPM 包流行度与状态分析

  • 首先打开浏览器,访问 @microsoft/rush-vs-lerna-vs-nx-vs-turbo
  • 我们看到一个横向的 NPM 下载记录。过去一年,下载量最多的是 Nx,其次是 Turbo,然后是 Lerna,最后是 Rush
  • 从下载量能看出它们的流行程度,Nx 的使用量最多
  • 再看这些项目仓库的状态,仓库数量最多的是 Lerna,其次是 Nx,它们的更新频次都很高,基本在一到两个月内都有提交,且版本都是正式版本,没有出现零点几的版本
  • 介绍 NPM 包的目的,一是了解包的流行度,从侧面了解其生态情况;二是了解包的更新频次和维护状态

需求选型及工具关系介绍


(一)Nx 与 Lerna 的关系

  • Nx 是由前谷歌员工开发的构建系统,利用了谷歌内部工具。Lerna 和 Nx 背后的公司都是 NRWL,NRWL 接管了 Lerna 的管理、维护和更新工作。
  • Nx 利用 Lerna 检测工作区中的包及其依赖关系,Lerna 遵循 Nx 强大的任务运行程序来运行脚本,允许并行运行、版本缓存结果,并将其分布在多台机器上,同时确保尊重包之间的依赖关系。
  • 有关 Lerna 和 Nx 版本的兼容信息,可在 Lerna 官网查看
  • Nx 的重心在构建功能,也包含开发、测试和构建优化等;而 Lerna 更聚焦于包的版本管理和发布
  • 如果不需要使用 Nx 扩展功能,开源项目免费;若使用云特性或云计算资源,则需收费
  • Nx 和 Lerna 可以互补使用,既可用 Lerna 管理包的版本和发布,也可用 Nx 加速构建过程、管理项目依赖

(二)Nx 与 Turbo 的关系

  • Turbo 是 2021 年 12 月发布的构建工具,借鉴了 Nx 的方法,因此有人会比较 Nx 和 Turbo。
  • Turbo 是 Nx 的一个子集,同时使用 Turbo 和 Nx 没有意义。Nx 发布了自己的 SaaS 产品,Turbo 虽也类似,但未分离出来,所以在指南中将 Turbo 与 Nx Cloud 进行联合比较。
  • 若不想使用 Nx Cloud,可以构建自己的 API 来缓存项目构建过程中的文件,以提速项目构建。

Nx 与 Turbo 的特性对比

1 ) 渐进式采用

Turbo 和 Nx 的集成只需在项目中添加一个新的配置文件,不会破坏项目结构。

2 ) 工作空间部分

对于复杂的工作空间,Nx 和 Turbo API 都会分析并生成配置文件
Nx 的可视化视图比 Turbo 更具体,有交互式工具查看,更直观

3 ) 检测受影响的项目或包

  • 两者都支持本地任务协调,包括任务并行,但 Nx 在可插拔方面支持得更好。

4 ) 本地计算缓存

  • 两者都支持,可利用缓存提升项目构建速度。不过在存储文件策略上有差异,Nx 的输出差异更小,Turbo 有自己的输出规则,在处理某些输出时效果不如 Nx

5 ) 远程计算缓存:两者都支持

6 ) 分布式任务执行

  • Nx 支持,能在多台机器上运行命令,保留单台机器开发体验
  • Turbo 不支持,对大型项目有影响

7 ) 生态方面

  • Nx 有专门的 VSCode 插件以及其他编辑器插件,对开发者更友好
  • Turbo 没有

8 ) 配置方面

  • 过去五年 Nx 不断壮大,Nx 和 Turbo 生成的配置量相同

9 ) 终端环境

Nx 不会修改终端环境,对喜欢自己终端环境的开发者更友好
Turbo 会有自己的输出颜色设置

10 ) 插件支持:Nx 的插件支持范围更广

11 ) 构建性能:

  • 相同的五个 Next.js 应用项目,使用 Nx 构建大概花费 0.64 秒,使用 Turbo 大概花费 4.4 秒
  • 测试时 Turbo 已处于相对稳定状态,后续可能有性能提升
  • 虽然 Turbo 主要由 Go 和 Rust 编写,Nx 由 TS 编写,但大部分繁重计算核心用 Node.js 和 Rust 功能模块完成,性能不受影响
  • Nx 借鉴了类似 React 的方法,在很多方面比 Turbo 快,但启动时每次会消耗 70 毫秒,不过实际中影响不大, 启动1k个项目也是 70毫秒

Nx 与 Rush 的关系及对比

Rush 由微软的 SharePoint 团队维护和推动,有中文文档,对中文开发者友好,其生态也较完整。与 Nx 对比:

1 ) 构建特定项目

  • 有人认为 Nx 不支持直接针对某个项目构建,实际上目前 Nx 已支持

2 ) NPM 依赖项隔离

  • Rush 默认所有项目使用根 package.json 中特定的一组共享包
  • 更符合 Node 模块使用习惯。

3 ) 查看依赖关系图

  • Rush 没有社区插件,不支持使用现代化工具或框架
  • 如 Next.js、Storybook、Vue 等

4 ) 语义化包依赖发布

  • Rush 可以提供语义化的包依赖发布,Nx 可借助 Lerna 提供类似功能

Lerna解析:常用命令、版本控制与发包

1 ) 初识Lerna

  • 我们先打开Lerna的官网,官网页面有这样一句话 “The original tool for JavaScript monorepos”,这表明Lerna的应用场景主要是针对Monorepo架构。
  • 官网还提到,Lerna提供了 init 命令,帮助我们快速初始化Lerna项目。点击 “Get started” 处会有相关视频,大家可以参考视频学习Lerna的一些命令。

2 )Lerna基础操作与核心概念

  • Lerna作为一个CI工具,可以操纵和运行任务。在官网的 “features” 中,第一个功能是 “run tasks”,这和我们常用的PNPM类似
  • 当执行某一个 run 命令时,它会对Monorepo中的所有项目执行相同命令,比如 build 命令,无需手动逐个执行
  • 并行运行命令:Lerna提供了并行运行命令,如 lerna run test, field, mete,会同时针对所有workspace运行这三个脚本
  • 针对特定包运行:如果要针对某一个包运行命令,可使用 scope 参数。这和PNPM的 filter 关键词类似,但使用方式不同,Lerna是将 scope 加在命令后面

3 )项目实践

  • 课程资料文件夹中有一个名为 “nernon” 的示例项目,这是一个基础的React应用,即使不了解React,也不影响我们学习Lerna命令。
  • 下载并解压项目后,在终端使用Node 18.19.0版本,用PNPM安装依赖。
  • 项目中有四个workspace,我们可以使用PNPM的 filter 过滤特定名称的应用并执行脚本。
  • 例如,项目中的 remixapp 依赖于 futureheader 组件,使用PNPM运行项目时,需要依次执行多个命令,较为繁琐。而使用Lerna可以简化这个过程。

4 )Lerna与PNPM对比

  • 使用PNPM管理Monorepo项目时,执行构建命令可能需要手动处理依赖关系。
  • 而Lerna通过初始化命令(如 npx lerna init)可以创建 lerna.json 文件,记录项目基础信息。
  • 使用 npx lerna ls 命令可以查看Lerna管理的包。

5 )Lerna的优势

  • 缓存功能:Lerna通过 lerna cache 命令提供缓存功能。执行 npx lerna cache 会有向导提示,我们可以根据项目情况选择需要按顺序执行的脚本、可缓存的脚本以及脚本的输出目录等信息。配置完成后,会生成 nx.js 文件记录配置信息。再次执行构建命令时,如果项目文件未发生变化,会使用本地缓存,大大提高构建速度。
  • 版本控制:Lerna可以方便地进行语义化版本号控制,使用 npx lerna version 命令并可添加 --no-private 参数,排除私有仓库的包。在执行该命令前,需要确保项目的Git仓库已正确配置并推送到远程仓库。执行命令后,会出现可供选择的版本号列表,选择合适的版本号并确认后,Lerna会自动更新版本号并提交到仓库。
  • 包发布:Lerna发布包非常方便,使用 lerna publish 命令可以自动推送和发布 packages 中发生修改且版本号变化的包。如果要发布到远端仓库,可添加 --from-package 参数。发布前需要确保已登录到相应的NPM仓库。

6 )Lerna的其他功能

  • 监视功能:Lerna的 watch 功能在6.4.0版本之后可用。使用 lerna watch 命令可以监视workspace文件的变化,并执行对应的NPM脚本。可以通过 --scope 指定包名,或使用 --since 参数,只有当文件发生变化时才执行构建命令。使用 lerna watch 的好处是构建出的版本直接适用于最终发布,免去了中间构建文件不适合发布的问题
  • Lerna在Monorepo项目管理中具有诸多优势,如缓存、版本控制、包发布等功能,能有效提高开发效率和项目管理的便捷性。下节课我们将学习其他工具

Turborepo上手:缓存、运行脚本与Lerna、NX横向对比

  • Turborepo,它有三种应用场景
    • 1.添加到现有项目(Add to existing project):即 Turborepo 加入到已存在的项目中
    • 2.创建全新的 Monorepo 项目(Create a new Monorepo):使用 Turborepo 创建一个新的 Monorepo 项目
    • 3.添加到已有的 Monorepo 项目:将 Turborepo 添加到已有的 Monorepo 项目里
  • 之前实践的 Lerna,通常是在已有的项目中添加,这种场景更为常见。
  • Turborepo 也具备创建新的 Monorepo 的能力,它内置了一些模板
  • 接下来我们进行实践,包括添加到项目中,并与所选项目做对比

1 ) 创建新的 Monorepo 项目

我们来创建一个新的 Monorepo 项目,查看其代码形式。选择 pnpm,打开终端工具,找到一个空的目录。

  • 执行命令:使用 pnpm dlx turborepo@latest 回车执行。
  • 进入提示列表:显示询问是否要创建 Turborepo,输入一个名字,如 turborepo-monorepo-model-create 回车执行。
  • 选择模板:选择 pnpm - workspace - base,然后开始下载对应的文件。
  • 等待初始化:下载完成后,会帮我们完成初始化,包含 docs 文档、web 页面等。紧接着开始安装对应的依赖。
  • 运行项目:执行 pnpm run dev 回车。需 cd 到刚才创建项目的目录。

2 ) 项目结构与构建测试
项目初始化完成后,我们可以查看其项目结构。在根目录的 package.json 中,有 Turborepo 相关配置,以及 ESLint 配置、TypeScript 配置等。

  1. 构建项目:执行 pnpm build 回车。首次执行时,没有缓存,会开始执行构建流程,构建完成后会将结果缓存下来。构建完成 web 和 docs 总共花费了 14.061 秒。
  2. 再次构建:再次执行构建命令,速度明显加快,仅用 290 毫秒就执行完成,这体现了缓存的作用。

3 ) Turborepo 的能力与不足

能力

  1. 缓存能力:Turborepo 支持缓存,包括本地缓存和远端缓存。远端缓存有两种方式:一是使用 Vercel,但在国内连接可能不稳定;二是自定义远端缓存(Custom Remote Cache),不过需要开发对应的接口,且没有具体开发指引,适合大型团队。
  2. 运行脚本能力:Turborepo 能自动处理依赖,支持并行运行任务。例如同时执行 pnpm run link build test 命令,它会智能处理任务顺序,充分利用 CPU 多线程能力。多次执行构建命令,会因缓存加速,显示所有任务都被 Turborepo 加速和缓存。

不足

  1. 缺乏 Lerna 的版本控制和发包能力。
  2. 其任务图(Task Graph)没有像 NX 那样全面美观的 UI 界面。不过在过滤运行、配置等方面,NX 和 Lerna 也有较好的支持。

4 ) 与 NX 对比

  • 后续将 Turborepo 与 NX 在相同项目中进行比较,从构建时间、速度和加速效果等方面做横向对比。
  • 在 Turborepo 项目中加入 NX,使用 npx nx init 执行,完成 NX 的初始化。
  • buildlink 加入缓存,构建 build 需按顺序执行,link 则不需要。
  • 在配置输出目录时,NX 的 nx.json 只支持一个输出目录。
  • 通过执行构建命令对比发现,使用缓存后,NX 和 Turborepo 都能提升构建速度,且 NX 的执行速度相对较快。

Turborepo 远程缓存使用流程(Vercel 配合)

远端缓存就是在一个团队里共享其他人构建过后的缓存文件,以提升 Monorepo 项目的构建速度

  • 如果在单台机器上执行 npm rebuild,花费了 9.4 秒。另外一台机器再运行同样的操作,同样需要花费 9.4 秒。

  • 这样,每个人执行 Monorepo 项目时,即便项目没有修改,都需要花费 9.4 秒。

  • 但如果加入了远端缓存,只要有一个小伙伴运行过一次项目,其他小伙伴再运行时就会进入加速状态,缓存得到有效应用。

  • 这样一来,对机器性能的要求就不需要那么高,也不用等待那么长时间。我们可以用一台机器做 CI,将推送到仓库的代码全部进行构建。

  • 在本地调试或进行业务功能开发时,把已缓存的公共模块的打包文件拉取到本地,运行调试脚本或构建脚本,从而加速本地开发。

  • 那它是怎么操作的呢?这里直接给出了几个命令,这种学习方式不太友好

  • 有 Vercel 出品的关于如何将 Turborepo 部署到 Vercel 上的流程文档,更加详细

  • 下面以文档为例,介绍集成步骤,主要分为两个步骤:

1 ) 步骤一:处理本地环境变量

  • 主要在 package.json 中设置一些环境变量,如 NODE_ENV 环境变量以及 GLOBAL_ENV 环境变量等。
  • 这些环境变量是在传递项目时使用的,生产环境和本地环境所需的变量可能不同,需根据实际情况设置。

2 ) 步骤二:在 Vercel 上创建项目

  1. 登录 Vercel 界面。若未注册登录,可选择使用 GitHub 账号登录。登录后,在左侧选择自己的账号。
  2. 在 GitHub 上创建一个远端仓库。创建好后,在 Vercel 界面点击 Import,进入项目配置界面。
  3. 配置界面中有 Build Settings,采用默认选项即可。可切换构建类型,如选择 web,然后点击 Continue,上面会显示默认命令,无需修改,继续下一步。
  4. 配置完成后,回到相关界面,有一个 Setup Remote Cache for Turborepo on Vercel 的操作。打开新终端,执行 npx turborepo login 进行跳转授权。授权完成后,执行 npx turborepo link,会询问是否同意远端缓存,选择账号后回车执行,显示成功设置。

3 ) 测试缓存效果

  • 在官方脚本或命令中有说明,删除 node_modules 下的 cache 文件夹,再执行构建命令,若出现 Remote Caching Enabled 标志,说明缓存生效。
  • 执行构建时,首次执行可能会从远端下载缓存,花费时间较长,但之后再执行就会变快。

已有项目集成 Turborepo 和 Vercel 远程缓存的流程

  1. 创建账号和仓库:创建 Vercel 账号,在 GitHub 上创建一个自己的仓库,如 turborepo-learn-remote-caching,复制仓库地址。
  2. 初始化项目仓库:在项目中初始化仓库,添加远程仓库地址,将本地代码进行 commit 提交并推送到远端。
  3. 配置项目文件:打开项目的 package.json,添加 packageManager 字段,选择 npm 并指定版本,如 8.12.1
  4. 安装和配置 Turborepo:全局安装 turborepo,在项目根目录创建 turbo.json 文件,复制相关 schema 内容并粘贴。创建 pipeline 并粘贴到 schema 后面,删除不必要的注释和 output 部分。
  5. 添加依赖和测试:在 package.json 中添加 turbo 依赖,打开终端工具安装依赖。先在本地执行 turbo build 进行测试,确保能正常构建。
  6. 集成 Vercel:在 Vercel 上点击 New Project,选择在 GitHub 上创建的仓库进行 Import。使用 npx turborepo link 关联项目,选择相应项目范围,显示 success 表示关联成功。
  7. 同步缓存:小伙伴们在本地执行 turbo build 前,先删除 node_modules 里的对应缓存,这样执行时不仅会产生缓存文件,还会将其同步到远端服务器。再次删除缓存文件后执行 turbo build,就相当于模拟其他小伙伴执行构建命令,会使用远端服务器上的缓存。

存在的问题

  1. turbo.json 的配置不够自动化,不如其他工具(如 Nx)方便。
  2. 不一定非要部署到 Vercel 上,有更多选择会更灵活。
  3. Vercel 对于国内小伙伴来说,连接速度可能较慢,部分区域网络连通性不佳。
  4. Vercel 共享缓存的功能需要开通付费版本(Pro Plan),每月费用 20 美元。若没有刚需,使用本地缓存即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2401983.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

谷粒商城-分布式微服务项目-高级篇[三]

十五、商城业务-支付 15.1 支付宝支付 15.1.1 进入“蚂蚁金服开放平台” 支付宝开放 平台地址: 支付宝开放平台 15.1.2 下载支付宝官方 demo,进行配置和测试 开发者文档:支付宝开放平台文档中心 电脑网站支付文档:小程序文…

实现购物车微信小程序

实现一个微信小程序购物车页面,包含以下功能: 需求说明: 商品列表:显示商品名称、价格、数量加减按钮,支持修改商品数量(数量≥1)。 全选 / 反选功能:顶部 “全选” 复选框&#…

26考研 | 王道 | 计算机组成原理 | 四、指令系统

26考研 | 王道 | 计算机组成原理 | 四、指令系统 文章目录 26考研 | 王道 | 计算机组成原理 | 四、指令系统1.指令系统0.指令集体系结构1. 指令格式1.按地址码数目不同来分2.指令-按指令长度分类3.指令-按操作码长度分类4.指令-按操作类型分类 2. 扩展操作码指令格式 2.指令的寻…

在 Windows 系统安装 Git

前往官网下载Git - Downloads 目录 一、下载安装包 二、安装 Git 三、安装完成 四、验证安装 五、问题解决 解决步骤 一、下载安装包 点击页面右侧 “Download for Windows” 按钮。 点击页面最上方 “Click here to download” ,下载 Git for Windows/x64 …

基于InternLM的情感调节大师FunGPT

基于书生系列大模型,社区用户不断创造出令人耳目一新的项目,从灵感萌发到落地实践,每一个都充满智慧与价值。“与书生共创”将陆续推出一系列文章,分享这些项目背后的故事与经验。欢迎订阅并积极投稿,一起分享经验与成…

【性能调优系列】深入解析火焰图:从基础阅读到性能优化实战

博客目录 一、火焰图基础:结构与阅读方法二、深入分析火焰图:关键观察点与性能瓶颈识别1. 识别最宽的函数块2. HTTP 请求处理分析3. 数据库操作分析4. 业务逻辑分析 三、性能优化实战:从火焰图到解决方案1. 线程池性能优化2. 数据库访问优化3…

Docker 与容器技术的未来:从 OCI 标准到 eBPF 的演进

Docker 的出现无疑是云计算发展史上的一个里程碑。它以其直观的打包、分发和运行方式,极大地简化了应用程序的部署和管理,从而推动了微服务架构和 DevOps 文化的普及。然而,容器技术的未来并非仅仅局限于 Docker,它正朝着更深层次的标准化和更底层的操作系统内核创新方向演…

PLC远程控制网关支持多塘口水环境数据边缘计算与远程安全传输的配置指南

一、项目背景 渔业养殖是关系到我国食物安全和海洋经济发展的重要产业,随着科技的不断进步,传统的养殖模式面临着诸多挑战,如养殖环境复杂、水质变化难以实时监测、设备运行状态不稳定等,这些问题不仅增加了养殖成本,还…

C++11 中 final 和 override 从入门到精通

文章目录 一、引言二、final 关键字2.1 final 关键字的基本概念2.2 final 关键字的语法2.3 final 关键字的使用示例2.3.1 防止类被继承2.3.2 防止虚函数被重写 2.4 final 关键字的使用场景2.5 final 关键字的注意事项 三、override 关键字3.1 override 关键字的基本概念3.2 ove…

大数据-275 Spark MLib - 基础介绍 机器学习算法 集成学习 随机森林 Bagging Boosting

点一下关注吧!!!非常感谢!!持续更新!!! 大模型篇章已经开始! 目前已经更新到了第 22 篇:大语言模型 22 - MCP 自动操作 FigmaCursor 自动设计原型 Java篇开…

git互联GitHub 使用教程

一、下载git Git 公司 右键 git config --global user.name "name" git config --global user.email "email" ssh-keygen -t rsa -C email :生成的ssh密钥需要到github 网站中保存ssh 二、GitHub新建repository 三、本地git互联GitHub 找…

SpringBoot+Mysql实现的停车场收费小程序系统+文档

💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

面向对象进阶 | 深入探究 Java 静态成员与继承体系

个人主页 文章专栏 文章目录 个人主页文章专栏 一、static(静态)1.static 静态变量代码展示内存图 2.static 静态方法工具类:练习: 3.static注意事项4.重新认识main方法 二、继承1.继承概述2.继承的特点3.子类到底能继承父类中的…

人脸识别技术成为时代需求,视频智能分析网关视频监控系统中AI算法的应用

一、应用背景:时代需求与技术革新的双重驱动​ 1)传统安防系统的困境​:传统监控系统依赖人工逐帧筛查海量视频,在人流密集场所极易漏检,且缺乏实时锁定和主动预警能力,面对突发安全事件响应迟缓。​ 2&a…

pc端小卡片功能-原生JavaScript金融信息与节日日历

代码如下 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>金融信息与节日日历</title><…

Go语言学习-->第一个go程序--hello world!

Go语言学习–&#xff1e;第一个go程序–hello world! 1 写代码前的准备 1 创建编写代码的文件夹 2 使用vscode打开3 项目初始化 **go mod init*&#xff08;初始化一个go mod&#xff09;Go Module 是 Go 1.11 版本引入的官方依赖管理系统&#xff0c;用于替代传统的 GOPATH…

高雄市12岁以下身心障碍儿童口腔保健合作院所名单数据集

描述&#xff1a; 关键字&#xff1a;儿童、口腔、保健、院所、名单 字段特征&#xff1a;序号、院所分级、合作医疗院所、市话、地址 语言&#xff1a;繁体 行数/数量&#xff1a;129行&#xff0c;5列 数据量 &#xff1a;7.27KB 格式&#xff1a;CSV、JSON、XML 目录…

破局新能源消纳难题!安科瑞智慧能源平台助力10KV配电网重构未来

一、政策驱动&#xff1a;新型配电网迎来 “智慧化” 刚需 随着分布式光伏、工商业储能、电动汽车充电桩等新型电力设施大规模并网&#xff0c;传统 10kV 配电网正面临 “高渗透、强波动、多交互” 的运行挑战。2025 年 6 月 1 日正式实施的《配电网通用技术导则》&#xff08;…

TIA博途中的程序导出为PDF格式的具体方法示例

TIA博途中的程序导出为PDF格式的具体方法示例 如下图所示&#xff0c;选中想要导出为PDF的程序块&#xff0c;右击选择“打印”&#xff0c; 如下图所示&#xff0c;选择“导出为WPS PDF” 或者“Microsoft Print to PDF”&#xff0c; 如下图所示&#xff0c;设置文档布局相关…

【大模型:知识图谱】--4.neo4j数据库管理(cypher语法1)

使用neo4j的cypher语法对图数据库进行管理&#xff1b;官网地址&#xff1a;Create, start, and stop databases - Operations Manual 目录 1.neo4j--简介 1.1.Neo4j版本的标准数据库 1.2.默认数据库 1.3.每用户主数据库 1.4.system数据库 2.neo4j--数据库管理 2.1.命名…