为了账号安全,请及时绑定邮箱和手机立即绑定

使用Turborepo构建React和Express.js的单仓库项目:我解决了哪些问题

介绍

单独管理前端和后端的设置可能会耗费时间和令人沮丧。单代码库可以将这两个应用程序合并到一个代码库中,从而让开发和维护更加轻松。

在这个项目中,我们使用Turborepo来建立一个包含前端和后端的单一代码库,前端使用React作为前端,后端使用Express.js作为后端。Turborepo允许我们为每个应用保持独立的环境、包配置和依赖,同时,它们仍能无缝协作。

在继续往下读之前,请查看react-express-monorepo GitHub 项目,以便更清楚地了解整体结构。

今天这篇博客,我们将介绍如何搭建开发服务器、管理环境配置以及处理生产问题,确保一切在一处顺利运行。

为何选择 Turborepo?

管理单独管理前端和后端的设置可能会既耗时又令人沮丧。虽然有多重方法可以简化这个过程,这个项目使用了Turborepo来创建一个单仓库。

Turborepo 允许为不同应用维护独立的环境、package.json 文件和 node_modules,同时仍能使其无缝协作。这提供了独立开发每个应用的灵活性,同时也带来了统一单存储库结构的优势。

开发环境设置

问题:前端和后端用不同的端口

在这套配置中,前端使用了Vite,默认运行在localhost:5173,而后端使用Express.js,假设运行在端口3000上。API 以 /api 开头,但目标是让前端仅使用 /api(例如 /api/user/1)进行请求,而不是直接访问 localhost:3000/api。这样内部会将请求路由到后端的 localhost:3000

解决办法:Vite 代理

可以在 Vite 中配置代理,将请求转发到后端。这样一来,任何对 /api/api/* 的请求都会被转发到 localhost:3000/api,从而实现前后端的无缝通信。

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";

// https://vitejs.dev/config/
// 定义配置,用于配置插件和其他开发服务器设置
export default defineConfig({
  plugins: [react()],
  // 设置插件,使用 react 插件进行编译
  server: {
    proxy: {
      "/api": {
        // 设置代理,将 /api 请求转发到 http://localhost:3000
        target: "http://localhost:3000",
        changeOrigin: true
      }
    }
  }
});

这样的代理配置将确保前端发往 /api 的请求将会被转发到后端的 localhost:3000

注意: 请注意,所有后端路由都应以 /api 开头,以确保正确路由。比如 /api/users,以使得说明更加具体和易于理解。

    // Express.js 路由定义
    app.get("/api", (req, res) => {
      res.send("Hello, World!");
    });

    // 这是一个用于返回 'OK' 的健康检查路由
    app.get("/api/health", (req, res) => {
      res.send("OK");
    });

这保证前端和后端保持一致,并且所有的API路由都正确地代理。

问题2:一次性使用一条命令启动两个开发服务器

目标是通过一个命令,例如 pnpm dev,启动前端和后端的开发服务器,并采用同样的方式来打包构建、代码检查以及启动生产环境的服务器。

统一命令

要实现这一点,所有应用程序都应该放在一个 apps 文件夹里,例如,

  • 前端代码 : apps/react
  • 后端代码 : apps/express

在每个应用的 package.json 文件中定义了相同的 devbuildlintstart 命令后,我们就可以用 Turborepo 来高效管理这些命令。下面是如何设置的:

前端(React)

apps/react/package.json 文件中:

{
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint .",
    "preview": "vite preview"
  }
}
Express 后端开发 (Express hòu duān kāfā)

打开 apps/express/package.json 文件,可以看到:

{  
  "scripts": {  
    "dev": "tsx watch --clear-screen=false src/index.ts  # 开发模式命令,用于监视并编译src/index.ts文件",  
    "build": "tsup  # 构建命令,用于打包项目",  
    "start": "node dist/index.js  # 启动命令,用于运行dist/index.js文件"  
  }  
}
TurboRepo (全栈)

在根目录下的 package.json 文件中,使用 dotenvx 来加载 CLI 的环境变量。turbo 命令将协调运行前端和后端的脚本。

{
  "scripts": { // 脚本定义 (define scripts)
    "dotenvx": "dotenvx", // dotenvx 环境变量管理工具 (dotenvx is an environment variable management tool)
    "build": "dotenvx run -- turbo build", // 构建项目 (build the project)
    "dev": "dotenvx run -- turbo dev", // 开发环境启动 (start development environment)
    "lint": "dotenvx run -- turbo lint", // 代码检查 (code linting)
    "start": "node apps/express/dist/index.js" // 启动 Express 应用程序 (start the Express application)
  }
}

这样一来,我们可以确保以下几点:

  • 运行 pnpm dev 将同时运行前端和后端的开发脚本。
  • pnpm build 会构建前端和后端。
  • pnpm lint 会进行前端和后端的代码检查。
  • pnpm start 将启动生产后端。
问题三:访问:全局变量

在这种情况下,环境变量通过dotenvx注入到CLI中。虽然Vite(前端)可以轻松访问这些环境变量,但Express.js(后端)无法直接获取这些环境变量,除非进行额外配置。

使用方法:使用 dotenvx 并使用相对路径

为了确保 Express.js 能访问全局环境变量,需要使用 dotenvx(或 dotenv)配置一个相对于全局 .env 文件的路径。可以这样配置:

    import dotenv from "@dotenvx/dotenvx";  
    import path from "path";  
    dotenv.config({  
      path: path.join(__dirname, "../../../.env"), // 请根据实际情况修改路径
    });

通过指定全局 .env 文件的路径,后端可以像前端一样访问相同的环境变量,确保前后端应用的一致性。这样,后端可以像前端一样访问相同的环境变量,确保前后端应用的一致性。

生产环境服务器配置

Vite 代理配置在部署时不起作用,遇到了问题

在实际生产环境中,Vite 的代理设置在实际生产中不起作用了,因为在打包过程中,React 被转换成了静态文件(如 HTML、CSS 和 JS)。因此,直接将API请求代理到后端已经不可能了。

后端服务静态文件的技巧

一个简单的解决方法是从后端服务器提供前端的静态文件。后端会提供静态文件,任何未匹配的路由(除了API路由之外的)将回退到前端应用。

步骤如下:
  1. 服务静态文件: 使用《Express.js》来提供构建的 React 前端文件。
    // 用于提供静态文件服务
    app.use(express.static(path.join(__dirname, "../../react/dist")));
  1. 未匹配路由的默认处理方式: 如果某个路由与任何 API 路由都不匹配,则提供构建中 index.html 文件。这样 React Router(如果有在用的话)就能处理客户端的路由了。
如果任何API路由不匹配,则回退到前端显示,即发送请求到前端的HTML文件。
app.get("*", (req, res) => {  
  res.sendFile(path.join(__dirname, "../../react/dist/index.html"));  
});

有了这种设置,后端将服务静态的前端文件,并通过由 React 应用程序接管来处理所有非 API 路由,确保客户端路由在生产中正常运作。

结论

使用Turborepo可以同时管理前端和后端代码,让开发过程变得更加简单和高效。这样我们可以在一个地方搞定所有事情,同时在需要时仍然可以保持前端和后端的分离。

通过遵循此设置,你可以让你的工作流程更简单,使应用开发和部署更快捷。

想了解更多,请查看react-express-monorepo GitHub 仓库页面,查看设置情况。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消