You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
importcorsfrom"cors";importexpressfrom"express";importmorganfrom"morgan";constapp=express();app.use(morgan("tiny"));app.use(express.json({limit: "100mb"}));app.use(cors({credentials: true,origin: ["http://localhost:3000"],}),);constport=process.env.PORT||3001;app.get("/",(_,res)=>{res.send("Hello from Express!");});app.listen(port,()=>{console.log(`Server is running on http://localhost:${port}`);});
作为一名开发者或实习生,你可能遇到过在单个项目中管理多个应用程序或软件包的挑战。无论是在开发前端应用的同时构建后端 API,还是在项目的不同部分之间共享 UI 组件和实用工具函数,事情都可能很快变得难以管理。
这就是 monorepos 发挥作用的地方。通过将代码组织到一个包含多个应用程序和共享包的仓库中,你可以简化开发流程并改善协作。在本指南中,我们将引导你使用 Turbopack、Biome、Next.js 15、Express.js、Tailwind CSS 和 ShadCN 设置一个 monorepo。我们还将使用 pnpm 作为我们的包管理器来优化依赖管理。
在本教程结束时,你将拥有一个功能齐全的 monorepo,其中包含两个应用程序(Next.js 和 Express.js)和三个共享包(UI 组件、TypeScript 类型和实用工具函数)。让我们开始吧!
前提条件
在开始本教程之前,请确保已安装以下内容:
什么是 Monorepo?
在我们开始构建之前,让我们先弄清楚什么是 monorepo 以及它为什么有用。
定义
Monorepo 是一个包含多个项目或软件包代码的仓库。与为每个应用程序或共享库设置单独的仓库不同,所有内容都放在一个地方。
使用 Monorepo 的好处
在本指南中,我们将创建一个 monorepo (turborepo),其中包含:
为什么使用 pnpm 和 Turbopack?
为了使我们的 monorepo 高效且可扩展,我们将使用两个关键工具:用于包管理的 pnpm 和用于快速构建的 Turbopack/Turborepo。
pnpm
pnpm 是 npm 和 Yarn 的替代方案,具有以下优点:
Turbopack
Turbopack 是 Vercel 为 Next.js 推出的新打包器。它被设计为比 Webpack 快得多,尤其是在开发过程中:
有了这些工具,让我们继续设置我们的项目结构。
项目结构概述
以下是我们的最终项目结构:
我们将项目组织成两个主要目录:
apps/
: 这将包含我们的两个主要应用程序—web
(Next.js) 和server
(Express.js)。packages/
: 这将包含两个应用程序都可以使用的共享代码—ui
用于共享 UI 组件,types
用于 TypeScript 类型,utils
用于共享的工具函数,tsconfig
用于typescript配置文件。现在我们对结构有了大致的了解,让我们开始设置 monorepo。
设置 Monorepo
步骤 1:使用 pnpm 工作区初始化 Monorepo
首先,如果你还没有安装 pnpm,需要全局安装它:
接下来,创建你的主项目目录:
初始化一个新的工作区:
此命令在项目的根目录创建一个
package.json
文件。现在我们需要通过在根目录创建pnpm-workspace.yaml
文件来告诉 pnpm 哪些目录应该是工作区的一部分:此配置告诉 pnpm,
apps/
或packages/
中的任何文件夹都应被视为工作区的一部分。步骤 2:配置 Turbopack
接下来,我们将通过在项目的根目录创建一个
turbo.json
文件来配置 Turbopack:此配置定义了 Turbopack 应如何在你的工作区中处理构建。
步骤 3:全局配置
接下来,我们将更新我们的根
package.json
以添加脚本和依赖项。对于 Biome 配置,我们将创建一个名为
biome.json
的文件:一个非常重要的文件是
.gitignore
,在这个文件中,我们将告诉 Git 我们不想跟踪哪些文件。此配置定义了我们的项目默认值。现在我们已经设置了工作区配置文件,让我们继续创建我们的应用程序。
步骤 3: .vscode 文件夹
.vscode
文件夹存储专门针对 Visual Studio Code 的配置设置。这些设置允许你个性化和优化 VS Code 以满足你的项目或工作区需求。以下是两种主要的设置类型:node_modules
)。VS Code 使用 JSON 文件来存储这些设置,从而可以通过版本控制轻松进行自定义和共享。为了便于管理,你可以直接在 JSON 文件中修改设置,也可以使用设置编辑器,它提供了一个方便的图形界面。
对于我们的项目,我们将创建两个存储这些配置的文件。首先,在根目录创建一个名为
.vscode
的文件夹。然后,创建extensions.json
:我们需要最后一个配置就是全局设置, 创建一个
settings.json
文件:创建第一个包 (tsconfig)
为了创建将在我们所有 monorepo 中使用的 typescript 配置以及我们 web 和 server 的单独配置,我们将创建我们的 tsconfig 包。
我们将有 6 个 Typescript 配置文件:
base.json
next.json
express.json
ui.json
首先,我们将创建我们的
package.json
:然后我们将创建我们的
base.json
配置文件(你可以在这里找到每个 tsconfig 设置):现在我们将创建
next.json
配置:然后我们需要创建
express.json
配置文件:为我们的共享类型包创建一个
types.json
配置文件:此外,我们需要添加最后一个配置文件
ui.json
,此文件将在我们的共享 UI 包中使用。最后, 创建utils.json配置:
这是你的 tsconfig 包文件夹的样子:
恭喜,我们刚刚完成了 typescript 的配置。现在让我们进入激动人心的部分:创建我们的应用程序!
创建应用程序
步骤 1:设置 Next.js 15 应用 (
web
)创建并导航到
apps/
目录:使用 pnpm 创建一个新的 Next.js 应用程序:
此命令将在
web/
文件夹中创建一个新的 Next.js 应用程序,并启用 TypeScript,将 Turbopack 设置为默认打包器和 Tailwind CSS。要将我们的 tsconfig 包集成到 Web 应用程序中,我们需要更新默认的
package.json
:现在,更新默认的
tsconfig.json
:添加
biome.json
,以便我们可以在文件夹上激活它:你的 Next.js 应用程序现已设置完毕!让我们继续使用 Express.js 设置我们的后端应用程序。
步骤 2:设置 Express 应用 (
server
)导航回
apps/
目录并创建一个 Express 应用程序:更新服务器的
package.json
以添加 Express、其类型、cors、morgan 和 ts-node-dev:将
tsconfig.json
添加到服务器:在
src/server.ts
中创建一个基本的 Express 服务器:你现在已经设置了前端 (Next.js) 和后端 (Express) 应用程序!让我们继续创建两个应用程序都可以使用的共享包。
创建共享包
在本节中,我们将创建三个共享包:一个用于 UI 组件 (
ui
),一个用于 TypeScript 类型 (types
),一个用于实用工具函数 (utils
)。这些包将位于packages/
目录中。步骤 1:创建
utils
包我们将创建的第一个包是用于实用工具函数 (
utils
) 的包。要进行设置:在
packages/
中创建文件夹,并进行初始化:更新
package.json
以添加脚本和导出:添加
biome.json
:添加
tsconfig.json
:我们将创建的第一个(也是唯一的)util 函数是
cn
,这是一个用于有条件地合并 tailwind 类的实用工具函数,它在 ShadCN 组件中大量使用。我们需要添加以下依赖项:在
src/style.ts
中添加 cn 通用实用工具函数:步骤 2:创建
ui
包 (Tailwind CSS + ShadCN)导航回
packages/
目录:安装 React 以及 Tailwind CSS(开发依赖项)和 ShadCN(我们将使用 new york 样式):
按照与我们在 Next.js 应用程序中执行的类似步骤设置 Tailwind CSS—初始化 Tailwind CSS (
npx tailwindcss init
) 并在tailwind.config.ts
中对其进行配置:我们还需要为 Tailwind CSS 配置
postcss.config.mjs
:由于我们还将在该包上使用 Biome,因此请添加
biome.json
:更新
package.json
以添加tsconfig
、utils
包和自定义脚本:创建一个
tsconfig.json
文件:在
src/styles/globals.css
创建一个样式文件:ShadCN 要求你创建一个
components.json
(启用 CLI 使用):现在你可以开始在此包中添加可重用的 UI 组件!例如,要导入 ShadCN Button 组件,只需在根工作区运行以下命令:
你可以在此处找到每个 ShadCN 组件,以及在此基础上创建的其他组件。现在我们准备设置我们的共享类型包并集成我们设置的所有内容!
步骤 3:创建
types
包types
包将包含两个应用程序都可以使用的共享 TypeScript 类型。要创建它:导航回
packages/
,创建文件夹并进行初始化:创建biome.json文件:
创建
tsconfig.json
文件:我们将创建的第一个类型将是一个简单的 API 客户端,以便我们可以在
server
和web
之间共享类型。创建src/
文件夹,并在其中创建api/
文件夹。然后创建simple-api-client.ts
:更新
package.json
以添加导出、脚本和 devDependencies:现在,在 src/api 文件夹中创建一个 index.ts 并从 simple-api-client.ts 导出所有内容(你将使用其他文件复制它以获得单一导入源):
最后,在 src 文件夹中创建一个 index.ts 并从 api 导出所有内容:
我们的共享类型包已全部设置完毕!你的存储库应如下所示:
现在,让我们继续本教程的最后一部分:集成所有内容并运行开发环境。
在本地运行你的 Monorepo
现在一切都设置好了,让我们在本地运行这两个应用程序!
步骤 1:安装所有依赖项
一次性安装工作区中的所有依赖项(记得将目录更改回根目录):
此命令将安装两个应用程序(
web
、server
)以及所有共享包(ui
、types
等)的所有必要依赖项。此命令会同时启动你的前端 (Next.js)(在端口 3000 上)和后端 (Express)(在端口 3001 上)!
Web 和 Server 集成
为了在我们的应用程序和包之间创建一个简单的集成,我们将开发一个组件,该组件将使用我们在本教程前面创建的共享类型从服务器获取数据。但是,在此之前,让我们更新我们的 Tailwind CSS 文件和全局样式以使用我们在
UI
包中定义的那些。将 tailwind.config.ts 的内容替换为以下内容:现在将
postcss.config.mjs
内容替换为:在我们的根布局 (
src/app/layout.tsx
) 中,更新 globals.css 导入以使用我们在 UI 包中创建的那个:这样做是为了我们可以从共享 UI 包控制我们的应用程序 UI 样式和配置,这样如果我们创建另一个 Web 应用程序(例如管理仪表板),我们将拥有一致的样式!
要开始开发我们的应用程序,我们将按照以下规则组织我们的 Web 文件夹结构:仅在页面中使用的组件应位于
app
目录中与页面文件夹同级的名为components
的文件夹中。应用程序共享组件应位于src/components
文件夹中。因此,让我们在
app
目录src/app/components
中创建一个 components 文件夹(我们将创建一个仅在第一页中使用的组件),并创建一个名为get-test.tsx
的文件,其中包含以下内容:看看该文件,我们有一个使用我们在共享类型中定义的类型化响应对服务器进行的简单提取,这使我们可以轻松地处理响应。服务器路由将很快定义。首先,让我们通过在我们的 page.tsx 中导入组件来完成
web
部分:Web 设置完成后,转到
server
应用程序并使用我们将使用的路由更新server.ts
。在app.listen
之前添加以下路由:最后,一切都完成了,你可以使用以下命令运行整个应用程序(记得将目录更改回根目录):
你将能够在页面上查看呈现的以下组件。
组件呈现后,我们会在 useEffect 中获取服务器并设置要呈现的状态(不需要 setTimeout,它只是为了可视化状态更改),然后你将看到以下内容。
总结
恭喜!你已经成功地设置了一个可扩展的 monorepo,其中包含两个应用程序——一个使用 Next.js 构建的前端,使用 Tailwind CSS 设置样式,通过来自 ShadCN 的可重用组件增强,以及一个 Express 后端——所有这些都使用 pnpm 工作区进行有效管理,以及由 Turbopack 提供支持的极快构建和使用 Biome 进行的几乎即时的校验!
以下是你今天完成的工作:
我们已经完成了本教程,现在你可以自由地发挥你的想象力,使用最好的 monorepo 架构创建任何你想要的东西
The text was updated successfully, but these errors were encountered: