[英]How should I handle front end routing in webpack?
I am building a website with separated front end and back end via restful api. When I develop the front end UI, I bought a template that uses webpack to generate the bundled production files.我正在通过 restful api 构建一个前后端分离的网站。当我开发前端 UI 时,我购买了一个使用 webpack 生成捆绑生产文件的模板。
Currently I am using pure javascript to handle the routing.目前我正在使用纯 javascript 来处理路由。 For example, to show different view for logged in users compare to other users, I did the following:
例如,为了显示登录用户与其他用户的不同视图,我执行了以下操作:
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")
}
Here are my questions:这是我的问题:
I notice window.location.replace
could be pretty slow and it would take half a second to route from index.html
to index-loggedIn.html
.我注意到
window.location.replace
可能非常慢,从index.html
路由到index-loggedIn.html
需要半秒。 Is this the right way to do it?这是正确的方法吗?
I am planning to deploy the front end static files on Nginx as a web server.我打算在Nginx上部署前端static文件作为web服务器。 I guess this workflow will be like: User sends a request to the "/" route -> Nginx responds with
index.html
-> The above javascript code gets ran -> Another request to "/index-loggedIn.html" gets sent to Nginx -> Nginx responds with index-loggedIn.html我猜这个工作流程将是这样的:用户向“/”路由发送请求 -> Nginx 以
index.html
响应 -> 上面的 javascript 代码运行 -> 另一个对“/index-loggedIn.html”的请求被发送到Nginx -> Nginx 响应 index-loggedIn.html
Is that what actually will happen?那真的会发生吗? It sounds very inefficient to me since I would like to be able to check user's log in status before serving the home page.
这对我来说听起来效率很低,因为我希望能够在提供主页之前检查用户的登录状态。
Is there any other frontend server/framework I can use to make the routing easier?我可以使用任何其他前端服务器/框架来简化路由吗? Then I can use Nginx simply as a reverse proxy.
然后我可以简单地使用 Nginx 作为反向代理。 I checked out Angular but I think it will take too much effort to convert the whole template into Angular's format.
我查看了 Angular 但我认为将整个模板转换为 Angular 的格式会花费太多精力。 Can I use express just for front end routing?
我可以仅将 express 用于前端路由吗?
Thanks in advance for your suggestions!提前感谢您的建议!
You are asking too many things with too many assumptions.你问的东西太多了,假设太多了。 Let us try to uncover them step by step.
让我们尝试逐步揭开它们。
Basically, you can build two types of applications: SPA (Single Page Application) or Multiple independent pages application;基本上,您可以构建两种类型的应用程序:SPA(单页应用程序)或多独立页面应用程序; or the hybrid of two Multi-page SPA application.
或两个多页面 SPA 应用程序的混合体。 Typically, we use React/Vue/Angular to build a SPA application.
通常,我们使用 React/Vue/Angular 来构建 SPA 应用程序。
In a SPA application, the routing is completely done on the client-side.在 SPA 应用程序中,路由完全在客户端完成。 The server plays very little role in it.
服务器在其中起的作用很小。 We use HTML History API to achieve this (This is what you are doing by hand using
replace
method).我们使用 HTML History API 来实现这一点(这是您使用
replace
方法手动执行的操作)。
With this setup, you need a UI Server (typically build with Node.js) or a Nginx like Reverse proxy.使用此设置,您需要一个 UI 服务器(通常使用 Node.js 构建)或一个 Nginx 之类的反向代理。 Your server won't be aware of the routes that client-side code has defined.
您的服务器不会知道客户端代码定义的路由。 The server/reverse-proxy needs to do two things.
服务器/反向代理需要做两件事。 First, when the request is for asset (request ending with.html, .css, .js, .png, etc.), then it should try to serve that asset.
首先,当请求针对资产(请求以 .html、.css、.js、.png 等结尾)时,它应该尝试提供该资产。 When the request is for non asset (request without any file extension
https://example.com/users/
), then you can safely assume that it is a request that must be handled by the client (your client-side code has defined the routing) and thus you must always and always send index.html
page which then will bootstrap your SPA application.当请求是针对非资产的(没有任何文件扩展名的请求
https://example.com/users/
),那么您可以放心地假设这是一个必须由客户端处理的请求(您的客户端代码已定义路由),因此您必须始终发送index.html
页面,然后该页面将引导您的 SPA 应用程序。
In the initial boot sequence of the SPA, you would read the location
and determine if this is a valid route.在 SPA 的初始启动序列中,您将读取该
location
并确定这是否是有效路径。 If this is not a valid route, you can redirect user (client-side only) to some default view or 404 view.如果这不是有效路由,您可以将用户(仅限客户端)重定向到某个默认视图或404视图。
Why you would need to do this?为什么你需要这样做? Because initially, your user may just say
https://example.com
and then navigate to /users
route by some action.因为最初,您的用户可能只是说
https://example.com
然后通过一些操作导航到/users
路由。 But, if user does full page refresh after navigation, you back-end server will see the route as https://example.com/users
.但是,如果用户在导航后进行整页刷新,您的后端服务器会将路由视为
https://example.com/users
。 There you need to handle the fallback route to always serve index.html
.在那里你需要处理后备路由以始终服务
index.html
。 In this case, 404 must be handled by using client-side code.在这种情况下,必须使用客户端代码处理404 。 All the major UI frameworks provide routing solution.
所有主要的 UI 框架都提供路由解决方案。 You don't need to do it by hand.
您无需手动操作。
Now if you using using index-loggedIn.html
for authenticated views and index.html
, then from SPA perspective, you have a anti-pattern or code-smell at least.现在,如果您将
index-loggedIn.html
用于经过身份验证的视图和index.html
,那么从 SPA 的角度来看,您至少有反模式或代码异味。 You must have a single index.html
view which takes care of both authenticated and un-authenticated views.您必须有一个
index.html
视图,它同时处理经过身份验证和未经过身份验证的视图。 In routing world, we typically use guards to protect the views from unauthorized access.在路由世界中,我们通常使用守卫来保护视图免受未经授权的访问。
What you are doing would currently work but as you mentioned that you see the lag of half seconds before redirect.您正在做的事情目前可以正常工作,但正如您提到的那样,您会在重定向前看到半秒的滞后。 And, that would happen on every page refresh.
而且,这会在每次页面刷新时发生。 But that exactly is the problem with full client-side SPA apps in general.
但这正是完整的客户端 SPA 应用程序通常存在的问题。 However with proper architecture, you should be able to address this.
但是,通过适当的架构,您应该能够解决这个问题。
If you are building an application like this, then your server needs to be more involved and must handle more routing responsibility.如果您正在构建这样的应用程序,那么您的服务器需要更多地参与并且必须处理更多的路由责任。 In this case, you should probably use cookie instead of localstorage for managing your token.
在这种情况下,您可能应该使用cookie而不是localstorage来管理您的令牌。 Browser automatically sends the cookies to the server and your server then can make the decision if it wants to serve
index.html
or index-loggedIn.html
page.浏览器自动将 cookies 发送到服务器,然后您的服务器可以决定是否要提供
index.html
或index-loggedIn.html
页面。
Is this the right way to do it?
这是正确的方法吗? - It would work but it is an anti-pattern.
- 它会起作用,但它是一种反模式。
Is that what actually will happen?
那真的会发生吗? It sounds very inefficient.
听起来效率很低。 - It is not inefficient as long as you are properly loading the views with spinner and doesn't cause awkward UX for the users.
- 只要您使用微调器正确加载视图并且不会给用户带来尴尬的用户体验,它就不会低效。
Can I use express just for front end routing?
我可以仅将 express 用于前端路由吗? - It is an invalid question.
- 这是一个无效的问题。 Literally, you cannot use express for front-end routing.
从字面上看,你不能使用 express 进行前端路由。 But then if you plan to implement UI server using express, then you can use it to define proper routing architecture eventually making it part of your front-end stack.
但是如果你打算使用 express 实现 UI 服务器,那么你可以使用它来定义适当的路由架构,最终使其成为你的前端堆栈的一部分。
In the end, note that there are few more consideration that you need to take into account.最后,请注意您需要考虑的因素很少。 What happens when user is doing hard refresh when he is on some route that server doesn't recognize?
当用户在服务器无法识别的某些路线上进行硬刷新时会发生什么? How to properly support bookmarking capability for your users?
如何正确支持用户的书签功能? Also, are you building SPA or traditional server rendered application?
此外,您是在构建 SPA 还是传统的服务器呈现应用程序? If SPA, use client-side framework.
如果是 SPA,请使用客户端框架。 If server rendered, then keep all the logic inside Express or equivalent code.
如果服务器呈现,则将所有逻辑保留在 Express 或等效代码中。 If it is hybrid, determine the architectural boundary.
如果是混合的,确定架构边界。
Finally, if this sounds too complex consider using hash-based routing for your SPA.最后,如果这听起来太复杂,请考虑为您的 SPA 使用基于哈希的路由。 That simplifies many things at the cost of not-so clean URLs.
这以不太干净的 URL 为代价简化了很多事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.