发布于 2026-01-05 4 阅读
0

前端到后端:从 Vite 到 Express❗ 路由简介:前端 vs 后端 从源代码到服务器 开发 vs 生产:顺序很重要:处理 Express 中的关键路径 结论❤️

前端到后端:从 Vite 到 Express❗

引言

路由:前端与后端

从源到服务器

开发与生产:

订单处理:快递中的关键路径管理

结论❤️

引言

大家好!🤗 如果你是后端开发新手,或者你已经掌握了一些基础知识,但想更深入地了解服务器背后的逻辑、请求路由以及所有这些基础概念,我真心希望这篇文章能对你有所帮助。🥰

一开始感到困惑或者无法立即理解所有内容都是完全正常的,你最终会在合适的时机弄明白!或许这篇文章能帮你解惑,或许只是印证了你已经知道的事情!


我们将讨论以下概念:

  1. 路由:前端与后端
  2. 服务器
  3. 开发与生产:不仅仅是一条指令
  4. 订单处理:快递中的关键路径管理

路由:前端与后端

路由是指当用户访问特定URL(路径或“路由”)时,决定返回哪段代码哪个页面。这正是这两个世界之间的第一个主要区别。

前端路由(Vite、React Router)

当我们使用现代前端框架(例如 React with Vite 或 Create React App)时,我们不需要处理静态文件的路由:

开发服务器非常智能:Vite 的开发服务器旨在帮助我们快速编写代码。它能够读取我们的源文件(位于 `<path>` 目录下的文件src/),并自动将其发布到相应的 URL 下。

自动路由:如果我们的 HTML 或 React 代码引用了某个文件/styles/main.css,Vite 服务器会立即知道在哪里找到该文件(在其内存或文件系统中),并立即将其发送浏览器。我们无需为此编写任何特殊代码❗

专注于应用逻辑:使用 React Router 等库,我们只需关注应用逻辑(例如,“如果 URL 是 [URL] /profile,则显示个人资料组件”)。路由在浏览器中进行,在 JavaScript 文件加载完毕之后。


后端手动路由(Express.js)

Express.js 只是一个极简框架。它没有任何假设,也没有任何内置的“魔法”。

路由是手动的:一旦我们将 Express.js 设置为主服务器,我们就必须明确地告诉它如何处理到达它的每个请求。

我们是否希望POST /api/login请求验证数据库中的密码❓ 我们必须写app.post('/api/login',...)

我们是否希望GET /api/users请求返回用户列表❓ 我们必须这样写app.get('/api/users', ...)

静态文件识别错误/main.css:如果没有明确指示, Express在收到对静态文件的请求时,无法识别这是一个静态文件。它会查找 API 路由或渲染逻辑。由于找不到,它会隐式返回404 Not Found 错误

在启动时,Vite 开发服务器会默默地执行一些神奇的操作,它会自动处理所有静态文件(如 CSS 和图像)的路由和提供,直接从内存中读取

然而,当我们引入 Express.js 时,一切就变得复杂了。Express 并不具备这种特性,它需要明确的指令。我们必须手动定义 API 路由app.get('/api/data'),更重要的是,我们必须使用 express.static()`<script>`标签手动告诉 Express:“这里存放着网页所需的所有静态文件。” 如果没有这一步手动操作,服务器将无法访问我们的 CSS 和 JavaScript 文件,从而导致页面无法正常显示!


从源到服务器

开发中的静态文件:

在开发过程中,当我们运行npm run devReact 项目时:

无物理文件夹:Vite 服务器直接从目录读取文件( .jsx, )并将其保存在 RAM(内存)中。它不会创建存放编译文件的物理文件夹。.csssrc/

速度:我们保存的任何更改都会通过 HMR(热模块重载)立即传输到浏览器,从而使编码体验流畅。

尚未准备好投入生产:虽然速度很快,但这种模式不稳定不安全没有针对互联网上成千上万的真实用户进行优化。


从源到分发:

何时以及为何需要编译❓ 在发布应用程序(上线生产环境)之前,我们必须编译代码:

命令npm run build
优化:此命令获取我们所有的源文件(React,,CSS等),对其进行压缩(使其体积小得多),将它们连接起来(将它们放入更少的包中),并对其进行优化以获得最大的加载速度。

结果dist:所有这些优化后的文件都被放入一个新的物理文件夹中,通常称为 `.fs`dist或 `.fs` 。该文件夹包含前端的build最终静态版本,随时可以提供服务。


进入express.static()

如何提供 dist 文件夹?❓ 现在我们有了优化后的 dist 文件夹,我们必须告诉 Express(后端)它需要公开提供的文件夹:

解决方案是express.static():这行代码是我们给 Express 服务器的指令:

// in production, Express serves the frontend's 'dist' folder
app.use(express.static(path.join(__dirname, 'client/dist')));

Enter fullscreen mode Exit fullscreen mode

工作原理:每当服务器收到HTTP 请求,且请求路径与我们定义的API 路由不匹配(​​例如,不以 `/` 开头/api)时,Express 都会在dist 文件夹中查找!如果找到与请求 URL 匹配的文件(例如,`/` /style.css),它会立即将该文件发送给客户端,并停止路由过程!


开发与生产:

npm run dev→ 如果我们在前端(React)和后端(Express)项目目录中都看到了同一个命令,我们可能会认为它们的作用相同。但事实并非如此❗这是一个至关重要的区别,尤其是在考虑安全性性能时。


双服务器npm run dev:两台服务器,两种用途

当我们谈到开发模式(Dev)和生产模式(Prod)时,我们是在描述我们正在运行的代码的状态目的

开发模式(我们的工作台):

开发模式是我们的工作台,它针对速度和调试进行了优化。

目的:唯一目标是促进快速编码测试调试
前端设置:服务器在一个端口上运行Vite 开发服务器(例如5173)。
后端工具:我们使用诸如 之类的工具,以便在保存更改后nodemon立即自动重启服务器。
错误:错误信息清晰详细(堆栈跟踪),并直接打印到您的控制台,帮助您立即解决问题
。 →优化:文件按原样提供,仅进行最小程度的优化,因为文件大小和速度并非主要考虑因素。


生产模式(线上公共服务器)

生产模式是最终的、经过优化的版本,面向公众发布,其设计注重稳定性安全性

目的:旨在为用户提供稳定、快速安全的
体验。 →前端设置:前端代码首先经过构建(编译和压缩),然后由单个Express 服务器在其指定端口(例如 8080 3000)上提供服务。
后端工具:我们使用高度优化的进程管理器(例如 PM2)来确保服务器持续稳定运行。 →错误:错误会在内部记录,但绝不会向公众用户显示,从而防止安全漏洞。
优化:文件经过高度压缩和积极缓存,以实现 最佳性能,并为所有用户提供更快的加载速度。


安全风险:

为什么我们不在生产环境中运行开发模式
在运行中的公共服务器上以开发模式运行 Express 服务器是一个重大的安全漏洞强烈不建议这样做

安全漏洞:开发错误通常会泄露敏感数据,例如服务器上的文件路径、环境变量,甚至数据库结构的细节。将这些信息泄露给攻击者是一个严重的安全漏洞

性能:开发模式旨在提供便利,而非追求速度。在实际用户负载下,您会遇到响应速度慢、资源管理不善以及可扩展性有限等问题。

稳定性:类似这样的工具nodemon在每次保存更改时重启代码。对于需要 24/7 全天候运行的面向公众的应用程序来说,这种行为不可预测且极不稳定❗


订单处理:快递中的关键路径管理

现在,让我们来看看设置路由和中间件的关键过程,确保 Express 能够正确处理所有请求。

中间件的作用:app.use()

在 Express 中,中间件就是一个在请求-响应周期中执行的函数。它可以访问请求对象req响应对象res以及周期中的下一个函数。next

app.use(middleware):此方法主要用于注册中间件。它会对所有HTTP方法(GET、、POST等)和所有路径执行提供的函数(除非我们指定路径前缀)。

黄金法则:中间件必须按照代码中定义的顺序执行。一旦某个中间件发送了响应(例如,`response.getResponse() res.send('Hello')`),循环就会停止,后续的中间件路由处理程序都不会执行❗

流程示例顺序

  1. app.use(cors)
  2. app.use(express.json)
  3. app.use('/api', apiRouter)
  4. app.use(express.static(dist_path))<- 这是关键的分离点❗
  5. ……其他路线……

React Router 的陷阱:

为什么我们需要❓这是将我们的后端逻辑与前端app.get('*')应用程序连接起来的最后一块拼图

用途:该app.get('*')路由是通配符处理程序。它使用通配符*来匹配任何GET尚未之前定义的任何中间件或路由处理的请求。

场景:当用户mysite.com/profile在浏览器中输入类似这样的直接链接时,服务器会收到对该链接的请求/profile

  1. Express检查路线API(例如,/api)。未找到匹配项❗
  2. 快速检查 express.static()名为 profile 的文件。未找到匹配项。❗
  3. 请求归于……app.get('*')

解决方案:我们告诉 Express 对于任何未匹配的路径,直接提供主应用程序文件(index.html


app.get('*', (req, res) => {
    // we tell Express: "Send the HTML file and let React Router handle the URL."
    res.sendFile(path.resolve(FRONTEND_BUILD_PATH, 'index.html'));

});
Enter fullscreen mode Exit fullscreen mode

结果:浏览器加载index.html完毕,React 接管,React Router 读取/profileURL 并显示正确的组件,从而实现流畅的单页应用体验❗


结论❤️

如果你是后端开发新手,一开始没能理解这些概念,别灰心,它们一开始确实会让人困惑。我想我们刚开始的时候都遇到过这些问题……我肯定也遇到过!🙃

主要挑战在于我们需要转变思维方式从像 Vite 这样的前端工具的自动内存服务,转变为 Express更手动、更结构化的路由方法。

希望这篇文章对你有所帮助,或者能让你想起当初后端开发初期遇到的种种困难。🤗我很好奇有多少人一开始
也经历过同样的迷茫,如果你也曾被后端开发困扰过,请在评论区留言!我很想知道自己并非孤身一人。🤗🥰

祝您阅读愉快!如果这篇文章对您有帮助或您觉得有用,请点个赞哦!🤗


更多文章:
Node.js——构建你的第一个服务器的步骤❗
我的第一个Node.js:掌握基础知识❗

文章来源:https://dev.to/cristea_theodora_6200140b/frontend-to-backend-from-vite-to-express-2c83