Clojure Kit框架入门介绍
Kit是Luminus的进化, 体验了以下, 做了个项目, 体验很棒, 本文是入手指南. 有兴趣的同事们可以尝试一下公司代码库中hospital这个项目, 应该都有权限.
Kit vs Luminus: 第一印象
Luminus 虽然能快速启动项目, 但初始生成的项目结构和依赖项相当庞杂. Kit 给人的初步印象是更轻量, 它提供了一个更简洁的模板, 允许开发者根据需要逐步添加功能模块.
另一个加分项是 Kit 使用了 clj-new 这个 Clojure CLI 工具来创建项目模板.
创建第一个 Kit 项目
首先需要安装 Kit 的 clj-new 模板. 如没有安装过 clj-new 工具,
它会自动下载.
# 安装 Kit 模板 (如果还没安装过 clj-new 会先下载)
clj -Ttools install io.github.kit-clj/kit-template '{:git/tag "v2.4.6"}' :as kit
注意: 这里使用了 v2.4.6 版本作为示例, 请根据实际情况使用最新或需要的版本
clj-new 源自 Boot 的 boot-new, 而 boot-new 又源自 Leiningen 的
line-new . Sean Corfield 也提到了他创建的 deps-new, 一个更轻量级的,
只关注 deps.edn 项目的模板工具.
安装好模板后, 创建项目就很简单了:
# 使用 kit 模板创建名为 my-guestbook 的项目
clj -T:new :template kit :name my-guestbook
项目结构概览
创建完成后, 进入项目目录 cd my-guestbook, 可以看到主要文件和目录包括:
deps.edn: 项目依赖和配置管理 .build.clj: 使用tools.build进行构建任务管理 .Dockerfile: 用于 Docker 容器部署 .README.md: 项目文档 .resources/system.edn: 系统配置, Kit 使用 Aero 库来管理配置. Aero 支持 profile, 可以方便地区分开发, 测试和生产环境.src/my_guestbook/core.clj: 应用程序入口, 负责启动和停止系统.- 环境特定目录 (
env/dev,env/test,env/prod): 包含各环境下的代码, 资源和配置 . 例如env/dev/src/user.clj包含方便 REPL 开发的辅助函数 (go, halt, reset) . resources/public/: 存放静态资源 .
Kit 使用 Integrant 来管理组件的生命周期和依赖关系. 这与 Luminus 常用的 Mount 或 Stuart Sierra 的 Component 有所不同.
Integrant 的配置是声明式的, 定义在 system.edn 中, 通过多重方法
(defmethod) 来实现组件的初始化 ig/init-key 和销毁 ig/halt-key.
Kit 模块: 按需添加功能
Kit 的一个核心特性是它的模块系统. 可以先创建一个最小化的项目, 然后根据需要"安装" 额外的功能模块, 比如 HTML 页面渲染, 数据库访问等.
在 REPL 中可以查看和管理模块:
同步所有模块(第一次是需要执行的, 从服务端获得所有模块列表):
(kit/sync-modules)
查看所有模块:
(kit/list-modules)
:kit/sql - adds support for SQL. Available profiles [ :postgres :sqlite ]. Default profile :sqlite
:kit/datomic - adds support for Datomic
:kit/hato - adds support for kit-Hato HTTP client
:kit/simpleui - adds support for HTMX using SimpleUI (previously called ctmx)
:kit/codox - adds support for codox
:kit/html - adds support for HTML templating using Selmer
:kit/sente - adds support for Sente websockets to cljs
:kit/cljs - adds support for cljs using shadow-cljs
:kit/dominoui - adds support for HTMX using SimpleUI and Domino
:kit/dominoui-postgres - adds support for HTMX using SimpleUI and Domino. Includes sample postgres
:kit/metrics - adds support for metrics using prometheus through iapetos
:kit/auth - adds support for auth middleware using Buddy
:kit/tailwind - adds support for tailwindcss
:kit/devcontainer - adds support for devcontainer. Available profiles [ :default :compose ]. Default profile uses a single docker file.
:kit/nrepl - adds support for nREPL
:kit/htmx - adds support for HTMX using hiccup
安装需要的模块:
(kit/install-module :kit/sql)
使用clj-rewirite, 安装模块会自动修改 deps.edn 添加依赖, 修改
system.edn 添加组件配置, 甚至可能修改 core.clj
等源文件来引入必要的命名空间.
这个自动修改代码的功能虽然强大, 但也让一些参与者表示谨慎, 建议在执行前提交代码到Git.
构建留言板: 模块实战
我们通过安装 :html 和 :sql 模块来构建留言板应用.
1. 添加 HTML 页面渲染
执行 (kit/install-module :kit/html) 后, Kit 会:
- 添加 Selmer 库依赖, 用于 HTML 模板渲染 . Selmer 类似 Django 的模板引擎, 允许在 HTML 中嵌入逻辑(如循环, 条件判断), 并且对设计师友好 .
- 在
resources/html目录下生成基础模板文件(如home.html,layout.html). - 添加处理页面渲染的路由和命名空间(如
my-guestbook.web.routes.pages和my-guestbook.web.pages.layout).
2. 添加数据库支持 (SQLite + HugSQL)
执行 (kit/install-module :kit/sql)
- 添加数据库相关依赖:
next.jdbc,conman(连接池管理 ),migratus(数据库迁移), 以及 SQLite 驱动. - 在
system.edn中添加数据库连接池 (:db.sql/connection) 和迁移配置 (:db/migrations) . - 在
resources/sql/queries.sql文件中定义 SQL 查询. HugSQL 通过 SQL 文件中的特殊注释(如-- :name save-message! :! :n)来定义 Clojure 函数. - 在
resources/migrations目录下生成数据库迁移文件(按时间戳命名, 包含up.sql和down.sql).
我们定义了创建 guestbook 表的迁移 和保存, 查询留言的 HugSQL 函数.
-- resources/migrations/<timestamp>-add-guestbook-table.up.sql
CREATE TABLE guestbook (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(255),
message TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- resources/sql/queries.sql
-- :name save-message! :! :n
-- :doc saves a message to the database
INSERT INTO guestbook (name, message)
VALUES (:name, :message);
-- :name get-messages :? :*
-- :doc selects all messages from the database
SELECT * FROM guestbook;
HugSQL 将 SQL 语句保留在 .sql 文件中, 通过注释映射到 Clojure 函数,
对于固定的查询很方便.
3. 连接前后端
- 更新路由 (
my-guestbook.web.routes.pages):- 在 Integrant 配置中引用数据库查询函数组件 (
:query-fn) . - 修改主页路由处理函数, 调用
get-messages查询并将结果传递给 Selmer 模板. - 添加处理 POST 请求的路由, 调用
save-message!控制器函数.
- 在 Integrant 配置中引用数据库查询函数组件 (
- 创建控制器 (
my-guestbook.web.controllers.guestbook):- 创建
save-message函数, 从请求中获取表单参数, 调用 HugSQL 的save-message!函数保存数据, 然后重定向回主页.
- 创建
- 更新 HTML 模板 (
resources/html/home.html):- 使用 Selmer 的
{% for %}标签遍历messages并显示留言列表. - 添加一个 HTML 表单, 包含姓名, 留言输入框和提交按钮, 目标指向新添加的
POST 路由 . 别忘了添加 CSRF 保护字段 (
{{csrf-field|safe}}).
- 使用 Selmer 的
- 添加样式: 我们还快速引入了 Bulma CSS 框架来美化页面.
运行和打包
在 REPL 中, 可以通过 (reset) 命令重新加载代码, 应用迁移并重启服务.
访问 http://localhost:3000 就能看到留言板应用了.
当需要部署时, 可以使用 tools.build 来打包成一个独立的 uberjar:
clj -T:build uber
可以运行这个 JAR 文件:
java -jar target/my-guestbook.jar
总结与思考
这次对 Kit 的探索非常有启发性.
优点:
- 模块化: 按需添加功能, 避免了 Luminus 一开始就引入大量依赖和配置的问题. 可以从一个非常小的 API 服务开始, 然后逐步添加 HTML, 数据库等.
- 循序渐进的复杂度: 对新手更友好, 不必一开始就面对庞大的系统.
- 基于
deps.edn和tools.build: 紧跟现代 Clojure 生态. - 强大的 REPL 集成: 通过
kit命令可以直接在 REPL 中管理模块.
值得注意的点:
- 自动代码修改: 模块安装时会自动修改代码和配置文件, 需要注意版本控制和潜在冲突 .
- Integrant: Kit 选择了 Integrant 作为组件管理库, 如果更熟悉 Mount 或 Component, 需要适应一下.
- HugSQL vs HoneySQL: Kit 默认使用 HugSQL.
Kit 提供了一个现代化, 模块化且对开发者友好的 Clojure Web 开发体验. 它在 Luminus 的基础上做了很多改进, 特别是模块化设计, 使得项目可以从小处着手, 逐步扩展. 对于想要开始 Clojure Web 开发的新手, 或者寻求更灵活框架的开发者来说, Kit 绝对值得一试.