創(chuàng)建您自己的基于文件路徑的路由:揭開路由的神秘
了解路由、Dalle-2
大多数 JavaScript 框架都在采用的一种趋势是提供基于路径的路由功能。这意味着你想要访问的每个 URL 对应于项目中的一个特殊文件夹,该文件夹包含路由处理函数。
也就是说,如果你访问 http://<your host>/users/list
,处理函数会在那里(或者根据你的喜好,可能在 users/list/index.js
中),看你的喜好。
这个特性很好,而且我们在使用像Next、Fresh或其他框架时常常认为理所当然。
话说,我不喜欢把事情当作理所当然,所以我试着在这篇文章里理解它是怎么运作的。
我们来看看如何用Express实现基于路径的路由。
为何要做这个?也就是说,除了尝试解释清楚几乎所有现代框架内部深处的一个机制之外,这个功能非常不错,通过简化你的路由处理程序设置方式,有助于改善开发体验。
在此之前,我们曾使用过不太理想的方法,比如有一个单一的路由映射文件,这个文件包含了所有路由以及相应的处理文件。
比如说:这样
如果你的应用程序很小,只有几个路由,那确实是个不错的解决办法。你甚至可以将路由处理程序存储在不同的地方,这样灵活度很高。但是,如果你正在开发的是一个大型企业级应用,这个文件可能会有数百行代码。正如你可能想象的那样,没有人愿意去维护这个文件,而且在这个文件里添加错误也很容易。
所以,通过使用传统的"约定优于配置"这里,我们有一个更简单的办法来定义代码的哪些部分处理哪些路由,而不需要额外维护一个文件。我觉得这很棒!
正是由于它改善了开发体验,我喜欢这种类型的特性。
当然,这样做很可能会决定你网页项目的构建方式,但如果你自己构建路由器,你也可以根据具体需求进行相应的调整。
我们来看看这种实现会是怎样的。
我们来搭建自己的路由器在这一个例子中,我将使用ExpressJS,但不会用到它自带的路由功能,因为那样做没有意义,不过它使创建web服务器的过程更简单,这并不是本例的重点。所以这会让事情简单一些。
目的是提供一个能应对这种结构的路由器。
看看routes
文件夹里的内容
- 我们有一个
index.js
文件,它应该对应于应用的主要路由。 - 我们可以使用文件名作为处理程序,例如
users.js
用于处理/users
的请求,以及处理/books
请求的books/index.js
文件。 - 我们还有更深层次的路由,如
books/addresses/index.js
文件来处理/books/addresses
路径。 - 最后,锦上添花的是,有了
/books/[book].js
文件,我们甚至可以处理动态路由。 - 该文件将处理所有位于
/books
路径下,除了根目录和/books/addresses
的其他请求。
所以总的来说相当齐全,正如你将要看到的,唯一真正复杂的部分是负责动态路由的部分,其余部分则相当简单。
添加基于文件路径的路由我们先来看看简单的逻辑:除了动态路由之外的所有内容。
安装了ExpressJS之后,咱们先来用all
方法设置一个通用处理程序。
代码处理了所有路由(得益于/*
路由)和所有HTTP方法(得益于使用了all
)。
每次请求被此处理器拦截时,我们会检查URL中在routes
文件夹内是否有带.js
扩展名的文件。如果没有找到,则认为这是一个文件夹,并在该文件夹内查找index.js
文件。
好了,接下来我们只需调用 executeRoute
函数,然后就能得到结果值。如果结果是 false
,我们就认为执行失败是因为找不到文件。因此,我们会将此错误处理成“404 — 未找到”的响应。
拼图中缺失的部分是 executeRoute
函数,如下所示:
我们使用动态 import
函数,如果找到的文件存在,我们就继续,并获取请求中使用的 HTTP 动词。这样,你可以定义一个名为 handler
的万能处理程序(我知道,这个命名真是绝了!)或者直接用动词名称作为方法名。如果你定义了这个,代码就会用你定义的那个。
如果导入失败并抛出异常,那是因为没有文件可供导入,这意味着该特定路由没有被映射,因此我们需要返回一个 404 错误。
不管你信不信,这差不多就是你需要的所有东西来实现文件路径的路由了。
当然,如果我们还想添加之前提到的动态路由支持功能,我们需要“几行代码”。
支持动态路由功能的添加现在我们知道了如何根据用户请求的 URL 导入路由处理程序,在这种情况下,我们需要为 executeRoute
函数返回 false
的情况添加一些逻辑。毕竟,这意味着该路由没有直接对应的文件,但我们也在考虑支持“通配符”类型的文件。
添加逻辑可以这样表示:
- 如果没有直接映射的文件,则先提取动态参数的名称及其对应的值。
- 从URL中去掉名称,以便确定特殊文件所在的文件夹。
- 将动态参数名称用方括号括起来,形成新的文件名。
- 尝试导入新文件并调用
executeRoute
方法。
下面举一个例子:
- 路径
/api/users/donald
被请求了。 - 我们查找文件
/routes/api/users/donald.js
或/routes/api/users/donald/index.js
,但没有找到这些文件。 - 因此我们将“donald”从 URL 中移除,然后在
/routes/api/users
文件夹内查找名为[user]
的文件。我们找到了[user].js
文件。 - 现在我们知道动态参数叫作“user”,其值为“donald”。
- 现在我们可以导入动态文件,并将参数添加到 Request 对象中,供动态处理器使用。
这就变成了这样:
以上是我们服务器的完整代码。你可以忽略你已经熟悉的部分,但请查看我在第58行添加的false
部分里的逻辑。这和我之前解释的一样。
我把文件名和参数名的组合称为“动态处理器”,并编写了一个函数来从URL中获取动态处理器。
位于上述代码顶部的getDynamicHandler
函数会探索应该存放“特殊”文件的文件夹。它读取该文件夹内的所有文件,并寻找名字带括号的文件。由于每个路由只应该有一个动态处理函数,一旦找到该文件,我们就不再查找。
通过一个整洁的正则表达式,我也能捕获参数名(即文件名中的括号内容)。
这样一来,我就可以同时返回参数名称以及包含处理程序代码的文件。记住,参数的实际值是从URL直接获取的。
就这样,动态路由器现在可以处理简单的路由、多种HTTP动词,以及通过特定命名的处理程序文件的动态路由。
而且所有这些内容都包含在一个不到100行代码的文件里。
嗯,当然,和我所有的类似实验一样,这是一个学习项目。如果你想把这段代码投入生产使用的话,我建议你稍微优化一下代码,可能还需要添加一些缓存机制以避免每次动态请求时都从磁盘读取数据,并且最后加一些单元测试。
说完了,我想希望这篇文章对你有帮助,如果你之前自己写过文件路径路由器,欢迎在评论区告诉我你是怎么做的,我很乐意和你交流一下经验!
用像樂高積木一樣可重複使用的組件來構建應用程序
Bit的开源工具,帮助250,000+开发者使用组件构建应用。
将任何用户界面、功能或页面转变为一个可重用组件,并在你的应用程序之间共享它。这样可以更轻松地协作并更快地开发。
将应用拆分成组件,让应用开发更轻松,并享受你所需的流程的最佳体验。
→ 微前端架构 → 如何在项目间复用React组件 → 单仓库 (Monorepo) 要了解更多详情 我们如何构建微前端架构通过构建微前端架构来加速和扩展我们的 web 开发流程。 我们如何构建组件设计体系通过构建组件设计体系来标准化和规模化我们的UI开发流程。
blog.bitsrc.io
共同學習,寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章