【问题标题】:How should I handle front end routing in webpack?我应该如何处理 webpack 中的前端路由?
【发布时间】:2021-10-18 00:41:29
【问题描述】:

我正在通过restful api构建一个前端和后端分离的网站。在开发前端 UI 时,我购买了一个使用 webpack 生成捆绑生产文件的模板。

目前我正在使用纯 javascript 来处理路由。例如,为了显示登录用户与其他用户的不同视图,我做了以下操作:

if (window.location.pathname === "/") {
    const token = window.localStorage.getItem("token")
    // if token exists and it has not expired, show the logged in homepage. 
    if (token && !jwt_expired(token)) {
        window.location.replace("/index-loggedIn.html")
    } else {
        window.location.replace("/index.html")
    }

这是我的问题:

  1. 我注意到window.location.replace 可能非常慢,从index.html 路由到index-loggedIn.html 需要半秒钟。这是正确的做法吗?

  2. 我打算在 Nginx 上部署前端静态文件作为 Web 服务器。我猜这个工作流程会是这样的: 用户向“/”路由发送请求 -> Nginx 以 index.html 响应 -> 上面的 javascript 代码运行 -> 对“/index-loggedIn.html”的另一个请求被发送到 Nginx -> Nginx 以索引响应 -登录.html

    这真的会发生吗?对我来说这听起来效率很低,因为我希望能够在提供主页之前检查用户的登录状态。

  3. 我可以使用任何其他前端服务器/框架来简化路由吗?然后我可以简单地将 Nginx 用作反向代理。我检查了 Angular,但我认为将整个模板转换为 Angular 的格式需要花费太多精力。我可以将 express 仅用于前端路由吗?

提前感谢您的建议!

【问题讨论】:

    标签: javascript nginx webpack frontend web-deployment


    【解决方案1】:

    你问的东西太多,假设太多。让我们一步一步地揭开它们的面纱。

    应用类型

    基本上,您可以构建两种类型的应用程序:SPA(单页应用程序)或多独立页面应用程序;或两个多页面 SPA 应用程序的混合。通常,我们使用 React/Vue/Angular 来构建 SPA 应用程序。

    SPA 应用程序中的路由

    在 SPA 应用程序中,路由完全在客户端完成。服务器在其中扮演的角色很小。我们使用 HTML History API 来实现这一点(这是您使用 replace 方法手动执行的操作)。

    使用此设置,您需要一个 UI 服务器(通常使用 Node.js 构建)或类似 Nginx 的反向代理。您的服务器不会知道客户端代码定义的路由。服务器/反向代理需要做两件事。首先,当请求是针对资产(请求以 .html、.css、.js、.png 等结尾)时,它应该尝试为该资产提供服务。当请求是针对非资产的(请求没有任何文件扩展名https://example.com/users/),那么您可以安全地假设这是一个必须由客户端处理的请求(您的客户端代码已定义路由),因此您必须始终且始终发送 index.html 页面,然后该页面将引导您的 SPA 应用程序。

    在 SPA 的初始引导序列中,您将读取 location 并确定这是否是有效路由。如果这不是有效的路由,您可以将用户(仅限客户端)重定向到某个默认视图或 404 视图。

    为什么需要这样做?因为最初,您的用户可能只是说https://example.com,然后通过某些操作导航到/users 路线。但是,如果用户在导航后进行整页刷新,您的后端服务器将看到路由为https://example.com/users。在那里,您需要处理回退路线以始终为index.html 提供服务。在这种情况下,必须使用客户端代码处理 404。所有主要的 UI 框架都提供路由解决方案。您无需手动操作。

    身份验证

    现在,如果您将 index-loggedIn.html 用于经过身份验证的视图和 index.html,那么从 SPA 的角度来看,您至少具有反模式或代码异味。您必须有一个 index.html 视图来处理经过身份验证和未经过身份验证的视图。在路由世界中,我们通常使用守卫来保护视图免受未经授权的访问。

    您正在执行的操作目前可行,但正如您所提到的,您在重定向之前看到了半秒的延迟。而且,这会在每次页面刷新时发生。但这正是完整的客户端 SPA 应用程序的一般问题。但是,通过适当的架构,您应该能够解决这个问题。

    多页面 SPA 或多页面应用程序中的路由

    如果您正在构建这样的应用程序,那么您的服务器需要更多地参与,并且必须处理更多的路由责任。在这种情况下,您可能应该使用 cookie 而不是 localstorage 来管理您的令牌。浏览器会自动将 cookie 发送到服务器,然后您的服务器可以决定是要提供 index.html 还是 index-loggedIn.html 页面。

    回答您的问题:

    这是正确的做法吗? - 它可以工作,但它是一种反模式。

    这真的会发生吗?听起来效率很低! - 只要您使用微调器正确加载视图并且不会给用户带来尴尬的用户体验,这并不是低效的。

    我可以仅将 express 用于前端路由吗? - 这是一个无效的问题。从字面上看,您不能将 express 用于前端路由。但是,如果您打算使用 express 实现 UI 服务器,那么您可以使用它来定义适当的路由架构,最终使其成为您前端堆栈的一部分。

    最后,请注意,您需要考虑的因素很少。当用户在服务器无法识别的某些路由上进行硬刷新时会发生什么?如何为您的用户正确支持书签功能?另外,您是在构建 SPA 还是传统的服务器渲染应用程序?如果是 SPA,请使用客户端框架。如果服务器呈现,则将所有逻辑保留在 Express 或等效代码中。如果是混合的,请确定架构边界。

    最后,如果这听起来太复杂,请考虑为您的 SPA 使用基于哈希的路由。这以不那么干净的 URL 为代价简化了许多事情。

    【讨论】:

    • 非常感谢您的详细回答。因此,前端基本上有两种选择,构建 SPA 或为传统 MPA(多页面应用程序)使用服务器端渲染。我想重用我当前的前端 html 页面,所以我想要第二个选项。但问题是,如果我使用服务器端渲染,那么我们又回到了嵌入在一起的前端和后端,而我的意图是将它们完全分开。这就是为什么我首先为后端构建了一个 RESTful api。
    • 前后端分离必须做SPA吗?有什么办法(例子)在前端有一个 MPA,在后面有一个 restful api?
    • @ShawnLi,当谈到 100% 客户端和服务器分离时,SPA 是最简单的方法。而且,如果您打算这样做,那么最好使用一些开箱即用的框架,因为它可以为您解决许多重要的低级问题。你可以自己做,但这意味着你必须自己组装所有东西。至少,您应该使用一些客户端路由器(有很多),然后用它运行您的代码。还有其他方法,但它们会更复杂,并且需要某种 UI 服务器,而不是传统的 Nginx 或同等产品。
    • 谢谢。像 React 这样的前端框架有路由器,让 SPA 变得非常容易。但是我找不到任何专注于 MPA 的框架。我所需要的只是一个前端框架,我可以轻松地使用静态页面构建路由。你知道任何例子吗?为什么它们不受欢迎?
    • @ShawnLi MPA 没有专门的框架。只需使用 React/Vue 并使用 Webpack 多页面构建创建多个应用程序。这两个将是两个不同的应用程序。
    猜你喜欢
    • 1970-01-01
    • 2015-10-16
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多