Yarn Workspaces:像专业人士一样组织项目的代码库

已发表: 2022-03-10
快速总结 ↬ Yarn 工作区让您可以使用单一存储库 (monorepo) 来组织项目代码库。 在这篇文章中,Jorge 解释了为什么它们是一个很棒的工具,以及如何使用 Yarn 和基本的 npm 脚本创建你的第一个 monorepo,并为每个应用程序添加所需的依赖项。

每当我开始着手一个新项目时,我都会问自己:“我应该为后端服务器和前端客户端使用单独的 git 存储库吗? 组织代码库的最佳方式是什么?”

在我的个人网站上工作了几个月后,我遇到了同样的问题。 我最初将所有代码都放在同一个存储库中:后端使用 Node.js,前端使用 ES6 和 Pug。 我采用这种组织方式是为了方便,因为将两个项目放在同一个 repo 中可以很容易地搜索函数和类,并促进重构。 但是,我发现了一些缺点:

  • 没有独立部署。
    两个应用程序都使用相同的package.json ,并且两个项目没有明确的分离。
  • 界限不清。
    由于我依赖全局package.json ,我没有为后端和前端设置特定版本的机制。
  • 无需版本控制的共享实用程序和代码。

经过一些研究,我发现 Yarn 工作区是解决这些缺点的好工具,它是创建 monorepo 项目的有用工具(稍后会更多!)。

在本文中,我分享了 Yarn 工作区的介绍。 我们将一起完成一个关于如何使用它创建您的第一个项目的教程,最后我们将进行回顾和后续步骤。

跳跃后更多! 继续往下看↓

什么是纱线工作区?

Yarn 是 Facebook 的一个包管理器,它有一个很棒的功能,叫做 Yarn 工作区。 Yarn 工作区让您可以使用单一存储库 (monorepo) 来组织项目代码库。 这个想法是单个存储库将包含多个包。 包是孤立的,可以独立于更大的项目而存在。

纱线工作区

作为替代方案,我们可以将所有这些包放入单独的存储库中。 不幸的是,这种方法会影响在包及其依赖项目上进行开发时的可共享性、效率和开发人员体验。 此外,当我们在单个存储库中工作时,我们可以更快地移动并构建更具体的工具来改进整个开发生命周期的流程。

Monorepo 项目已被 Google 或 Facebook 等大公司广泛接受,并且证明 monorepo 可以扩展。

React 是 monorepo 开源项目的一个很好的例子。 此外,React 使用 Yarn 工作区来实现这一目的。 在下一节中,我们将学习如何使用 Yarn 创建我们的第一个 monorepo 项目。

使用 Yarn 工作区通过六个步骤创建一个带有 React 和 Express 的 Monorepo 项目

到目前为止,我们已经了解了 Yarn 是什么,monorepo 是什么,以及为什么 Yarn 是创建 monorepo 的好工具。 现在让我们从头开始学习如何使用 Yarn 工作区设置一个新项目。 要继续学习,您需要一个安装了最新 npm 的工作环境。 下载源代码。

先决条件

要完全完成本教程,您需要在机器上安装 Yarn。 如果您之前没有安装 Yarn,请按照这些说明进行操作。

这些是我们将在本教程中遵循的步骤:

  1. 创建您的项目和根工作区
  2. 创建一个 React 项目并将其添加到工作区列表
  3. 创建一个 Express 项目并将其添加到工作区
  4. 安装所有依赖项并向 yarn.lock 打个招呼
  5. 使用通配符 (*) 导入所有包
  6. 添加脚本以运行两个包

1. 创建您的项目和根工作区

在本地机器终端中,创建一个名为example-monorepo的新文件夹:

 $ mkdir example-monorepo

在文件夹中,使用我们的根工作区创建一个新的package.json

 $ cd example-monorepo $ touch package.json

这个包应该是私有的,以防止意外发布根工作区。 将以下代码添加到新的package.json文件以使包成为私有:

 { "private": true, "name": "example-monorepo", "workspaces": [], "scripts": {} }

2.创建一个React项目并将其添加到工作区列表中

在这一步中,我们将创建一个新的 React 项目并将其添加到根工作空间内的包列表中。

首先,让我们创建一个名为packages的文件夹,我们将在其中添加我们将在教程中创建的不同项目:

 $ mkdir packages

Facebook 有一个创建新 React 项目的命令: create-react-app 。 我们将使用它来创建一个包含所有必需配置和脚本的新 React 应用程序。 我们正在步骤 1 中创建的文件夹中创建这个名为“client”的新项目。

 $ yarn create react-app packages/client

一旦我们创建了新的 React 项目,我们需要告诉 Yarn 将该项目视为一个工作区。 为此,我们只需在根package.json的“workspaces”列表中添加“client”(我们之前使用的名称)。 确保使用与运行create-react-app命令时相同的名称。

 { "private": true, "name": "example-monorepo", "workspaces": ["client"], "scripts": {} }

3. 创建一个 Express 项目并将其添加到工作区

现在是时候添加后端应用了! 我们使用express-generator创建一个包含所有必需配置和脚本的 Express 框架。

确保您的计算机上安装了express-generator 。 您可以使用 Yarn 使用以下命令安装它:

 $ yarn global add express-generator --prefix /usr/local

使用express-generator ,我们在文件夹中创建一个名为“server”的新 Express 应用程序。

 $ express --view=pug packages/server

最后,将新包“server”添加到根package.json内的工作区列表中。

 { "private": true, "name": "example-monorepo", "workspaces": ["client", "server"], "scripts": {} }

注意本教程仅使用两个包(服务器和客户端)进行了简化。 在一个项目中,您通常可以拥有所需数量的包,按照惯例,开源社区使用这种命名模式: @your-project-name/package-name例如:我在我的网站上使用@ferreiro/server

4. 安装所有依赖并向 yarn.lock 打个招呼

一旦我们添加了我们的 React 应用程序以及我们的 Express 服务器,我们需要安装所有的依赖项。 Yarn 工作空间简化了这个过程,我们不再需要去每个应用程序手动安装它们的依赖项。 相反,我们执行一个命令 — yarn install — Yarn 神奇地为每个包安装所有依赖项,并优化和缓存它们。

运行以下命令:

 $ yarn install

此命令生成一个yarn.lock文件(类似于此示例)。 它包含您项目的所有依赖项,以及每个依赖项的版本号。 Yarn 会自动生成这个文件,你不应该修改它。

5. 使用通配符 (*) 导入所有包

到目前为止,对于我们添加的每个新包,我们还被迫更新根package.json以将新包包含到workspaces:[]列表中。

我们可以使用通配符 (*) 来避免这个手动步骤,它告诉 Yarn 将所有包包含在文件夹中。

在根package.json中,使用以下行更新文件内容: "workspaces": ["packages/*"]

 { "private": true, "name": "example-monorepo", "workspaces": ["packages/*"], "scripts": {} }

6.添加一个脚本来运行这两个包

最后一步! 我们需要有一种方法来同时运行这两个包——React 客户端和 Express 客户端。 对于这个例子,我们将使用concurrently 。 这个包让我们可以并行运行多个命令。

concurrently添加到根package.json

 $ yarn add -W concurrently

在根工作区package.json中添加三个新脚本。 两个脚本分别初始化 React 和 Express 客户端; 另一个同时使用concurrently运行两个脚本。 请参阅此代码以供参考。

 { "private": true, "name": "example-monorepo", "workspaces": ["packages/*"], "scripts": { "client": "yarn workspace client start", "server": "yarn workspace server start", "start": "concurrently --kill-others-on-fail \"yarn server\" \"yarn client\" } }

注意我们不需要将start脚本写入“服务器”和“客户端”包,因为我们用来生成这些包的工具( create-react-appexpress-generator )已经为我们添加了这些脚本。 所以我们很高兴!

最后,确保更新 Express 启动脚本以在端口 4000 上运行 Express 服务器。否则,客户端和服务器将尝试使用相同的端口 (3000)。

转到packages/server/bin/www并更改第 15 行中的默认端口。

 var port = normalizePort(process.env.PORT || '4000');

现在我们准备好运行我们的包了!

 $ yarn start

从这往哪儿走

让我们回顾一下我们所涵盖的内容。 首先,我们了解了 Yarn 工作空间以及为什么它是创建 monorepo 项目的好工具。 然后,我们使用 Yarn 创建了我们的第一个 JavaScript monorepo 项目,我们将应用程序的逻辑分为多个包:客户端和服务器。 此外,我们创建了我们的第一个基本 npm 脚本并为每个应用程序添加了所需的依赖项。

从这一点来看,我建议您详细查看开源项目,了解它们如何使用 Yarn 工作区将项目逻辑拆分为多个包。 反应是一个很好的。

Jorge Ferreiro 的网站使用 yarn 工作区和带有后端和前端应用程序的包
Jorge Ferreiro 的网站使用 yarn 工作区和带有后端和前端应用程序的包(大预览)

另外,如果你想看到一个生产网站使用这种方法将后端和前端应用程序分成独立的包,你可以查看我的网站的来源,其中还包括一个博客管理员。 当我迁移代码库以使用 Yarn 工作区时,我使用 Kyle Wetch 创建了一个拉取请求。

此外,我为使用 React、webpack、Node.js 和 Yarn 工作区的黑客马拉松项目设置了基础设施,您可以在此处查看源代码。

最后,学习如何发布独立包以熟悉开发生命周期对您来说真的很有趣。 有几个有趣的教程值得一看:yarn publish 或 npm publish。

如有任何意见或问题,请随时在 Twitter 上与我联系。 此外,在接下来的几个月里,我将在我的博客中发布更多关于此的内容,因此您也可以在那里订阅。 快乐编码!