开发者生态
evening
Biff.core:Clojure Web 应用程序的系统组成
2026-06-09
1 阅读
jacobobryant
首页 文档 新闻 GitHub 新库:biff.core Jacob O'Bryant | 2026 年 6 月 9 日 正如我之前所写的,我一直致力于将 Biff 拆分为一堆独立的库,并在此过程中更改各种内容。我已经完成了所有 12 个库的草稿,现在正在逐一浏览它们,以完善并发布它们。第一个库现已准备就绪。 biff.core :Biff 项目的系统组成和其他接口。这是将所有其他库粘合在一起的粘合剂,这就是我首先发布它的原因。长期以来,Biff 一直采用这种“模块和组件”结构,其中项目中的每个应用程序名称空间都公开一个“模块”映射,然后您有一堆样板将这些模块中的内容组合成单个“系统”映射,然后我们在启动时通过“组件”函数将系统映射线程化。 Biff 2 保留了该结构,并且添加了一些额外的内容来处理该样板文件。有关我正在讨论的示例,请参阅此代码,该代码从模块中获取 :routes (和 :api-routes )键并将它们转换为系统映射的 :biff/handler 值。我想要一种一流的方法能够将这种逻辑干净地提取到库中,以便库的指令可以只是“将此模块添加到您的项目中”,而无需附带“然后将所有这些内容粘贴到您的主命名空间中”。因此,这个新的 biff.core 库包含“init 函数”的概念。这些函数采用模块集合并返回可以合并到系统映射中的单个映射。哒哒。这是一个例子。 Init 函数存储在模块映射中的 :biff.core/init 键中,因此我们得到了很好的“您需要的只是模块(以及组件)”效果。这里的主要复杂之处在于,在应用程序代码中定义 (def handler ...) var 的样板实际上有一个很好的副作用:后期绑定。如果您更改任何模块,处理程序 var 将得到更新,并且如果您将系统映射中的 :biff/handler 设置为 var 而不是值 ( #’handler ),传入的 Ring 请求将获得最新的处理程序,而无需重新启动 Web 服务器。如果我们将该样板提取到库代码中,我们就不会得到 var。我最终得到了这个解决方案:初始化函数采用模块向量的 var,而不是向量值本身。系统映射中您想要在不重新启动的情况下更新的任何内容都需要是一个函数。在某些情况下,这意味着您需要设置一个返回 my-thing 的 :com.example/get-my-thing 函数,而不是在系统映射上设置 :com.example/my-thing 键。系统映射上的该函数应该取消引用模块 var 并将其传递给一个记忆函数,该函数构建您需要的任何东西(例如 Ring 处理程序)。再次参见这个例子。结果在美学上令人愉悦:您将获得一个漂亮干净的主命名空间,不需要进行太多更改,您所做的就是添加模块和组件。总是存在进一步整合事物的诱惑。为什么还要有一个单独的分量向量?为什么不让模块支持 :biff.core/on-start 和 :biff.core/on-stop 键,然后通过某种方式来表达这些生命周期函数之间的依赖关系,以便我们可以按正确的顺序调用它们?答案是,我们不必通过某种方式来表达这些生命周期函数之间的依赖关系,这样我们就可以按正确的顺序调用它们。自己将组件按正确的顺序排列并不难(特别是因为 Biff 入门项目为您做到了这一点),然后更容易理解组件的工作原理。它只是您传递地图的一系列函数。如果您处理的项目具有如此多的有状态资源,以至于很难跟踪所有资源,那么您始终可以在顶部分层一些东西,在将其传递给 biff.core 之前计算出组件向量应该是什么。 Plug:我的团队正在招聘一名高级软件工程师,主要编写 ClojureScript 和 Python。我们为可再生能源项目制作建模软件。注册 Biff:时事通讯、公告、博客文章等等。订阅 该电子邮件似乎无效。尝试另一种。 reCAPTCHA 检查失败。再试一次。出现意外错误。再试一次。 RSS 提要 · 存档 本网站受 reCAPTCHA 保护,并适用 Google 隐私政策和服务条款。