使用 HTMX 和 Bun 进行全栈 Web 开发

将 HTMX 放在前端,Bun 放在后端,然后将它们与 Elysia 和 MongoDB 连接起来,形成快速便捷的技术栈,使开发 Web 应用程序变得轻而易举。

Bun 和 HTMX 是目前软件领域最有趣的两个事情。 Bun 是一个速度极快的一体化服务器端 JavaScript 平台,而 HTMX 是一种 HTML 扩展,用于创建简单而强大的界面。在本文中,我们将使用这两个出色的工具来开发一个全栈应用程序,该应用程序使用 MongoDB 进行数据存储,并使用 Elysia 作为其 HTTP 服务器。

技术栈

本文的重点是技术栈的四个主要组成部分如何相互作用。这四个组成部分分别是 Bun、HTMX、Elysia 和 MongoDB。这种架构提供了一个快速部署的设置,易于配置并且灵活变化。

  • Bun 是一个 JavaScript 运行时、打包器、包管理器和测试运行器
  • Elysia 是一个高性能 HTTP 服务器,基于 Bun 构建
  • HTMX 提供了一种向 HTML 添加细粒度交互性的新颖方法
  • MongoDB 是旗舰级 NoSQL 面向文档的数据存储

请注意,本文有两个部分。后续我们将合并 Pug、HTMX 模板引擎,用它来开发一些奇特的前端交互。

安装和设置

您需要安装 Bun.js,这很容易做到。我们还将在我们的开发机器上将 MongoDB 作为服务与 Bun 一起运行。安装这些软件包后,bun -vmongod -version 命令都可以在命令行中运行。

接下来,让我们开始一个新项目:

bun create elysia iw-beh

这告诉 bun 使用 Elysia 模板创建一个新项目。 Bun 中的模板是使用 create 命令快速启动项目的便捷方法。Bun 可以像 Node.js 一样工作,无需任何配置。

现在,进入新目录 cd iw-beh,并按原样运行项目 bun run src/index.js

最后一个命令告诉 bun 运行 src/index.js 文件。src/index.js 文件是启动 Elysia 服务器的代码:

import { Elysia } from "elysia";

const app = new Elysia()
  .get("/", () => "Hello Elysia")
  .listen(3000);

console.log(
  `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`
);

在此文件中,我们导入 Elysia 并使用它实例化一个新服务器,该服务器侦听端口 3000 并在根目录下有一个 GET 端点。该端点返回一个文本字符串「Hello Elysia」,其工作原理与 Express 的相似。如果您访问 localhost:3000,您会收到一条简单的问候语。

现在我们已经运行了 Elysia,让我们添加 static 插件。 Elysia 有几个用于处理常见场景的插件。在本例中,我们希望从磁盘提供一些 HTML。 static 插件正是我们所需要的:

bun add @elysiajs/static

现在,运行 static 插件的 Elysia 服务器应该提供 iw-beh/public 目录中的所有内容。如果我们在其中放置一个简单的 HTML 文件并访问 localhost:3000/public,我们将看到它的内容。

HTMX 的魔力

接下来,让我们向 index.html 添加一个 HTMX 页面。这是 HTMX 主页上的一个简单示例:

<script src="https://unpkg.com/htmx.org@1.9.10"></script>

<button hx-post="/clicked"
    hx-trigger="click"
    hx-target="#parent-div"
    hx-swap="outerHTML">
    Click Me!
</button>

该页面显示一个按钮。单击时,该按钮将调用 /clicked 服务器,并且该按钮将替换为响应中的任何内容。那里还什么都没有,所以目前它什么也没做。

但请注意,所有这些仍然是 HTML。我们正在进行 API 调用并执行细粒度的 DOM 更改,而无需任何 JavaScript。这项工作是由我们刚刚导入的 htmx.org 库中的 JavaScript 完成的,但重点是我们不必担心它。

HTMX 提供了一种 HTML 语法,只需使用三个元素属性即可完成这些操作:

  • hx-post 在 AJAX 请求触发时提交帖子
  • hx-target 告诉 hx-post 哪些事件执行 AJAX 请求
  • hx-swap 表示 AJAX 事件发生时要做什么

Elysia 和 MongoDB

现在让我们在 Elysia 中创建一个端点,它将向 MongoDB 写入一些内容。首先我们将为 Bun 添加 MongoDB 驱动程序:bun add mongodb

接下来,像这样修改 src/index.ts

import { Elysia } from 'elysia'
import { staticPlugin } from '@elysiajs/static'
const { MongoClient } = require('mongodb')

const app = new Elysia()
  .get('/', () => 'Hello Elysia')
  .get('/db', async () => {
    const url =
      'mongodb://127.0.0.1:27017/quote?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.8.0'

    const client = new MongoClient(url, { useUnifiedTopology: true })
    try {
      await client.connect()

      const database = client.db('quote')
      const collection = database.collection('quotes')

      const stringData = 'Thought is the grandchild of ignorance.'

      const result = await collection.insertOne({ quote: stringData })
      console.log(`String inserted with ID: ${result.insertedId}`)
    } catch (error) {
      console.error(error)
    } finally {
      await client.close()
    }
    return 'OK'
  })
  .use(staticPlugin())
  .listen(3000)

console.log(
  `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`,
)

在这段代码中,我们添加了一个 /db 端点,它与 MongoDB 通信。现在它只是将一条引用写入到 quote 数据库中的 quotes 集合内。您可以直接通过访问 localhost:3000/db 来测试这一点。然后您可以验证数据是否已存储在 MongoDB 中:

$ mongosh

test> use quote
switched to db quote
quote> db.quotes.find()
[
  {
    _id: ObjectId("65ba936fd59e9c265cc8c092"),
    quote: 'Thought is the grandchild of ignorance.',
    author: 'Swami Venkatesananda'
  }
]

创建 HTMX 表格

现在我们从前端连接到数据库,让我们创建一个表来输出现有的报价。作为快速测试,我们将向服务器添加一个端点:

.get("/quotes", async () => {
  const data = [{ name: 'Alice' }, { name: 'Bob' }]
  let html = '<ul>'
  for (const item of data) {
    html += `<li>${item.name}</li>`
  }
  html += '</ul>'

  return html
})

然后在我们的 index.html 中使用它:

<ul id="data-list"></ul>
<button hx-get="/quotes" hx-target="#data-list">Load Data</button>

现在,当您加载 /public/index.html 并单击按钮时,就会显示从服务器发送的列表。从端点发出 HTML 与常见的 JSON 模式不同。我们在这里遵守 RESTful 原则,HTMX 有用于处理 JSON 端点的插件,但这更习惯使用。

在我们的端点中,我们只是手动创建 HTML。在真实的应用程序中,我们可能会使用某种 JavaScript 框架来使事情更易于管理。

现在,我们可以从数据库中检索数据:

.get("/quotes", async () => {
  const url =
    'mongodb://127.0.0.1:27017/quote?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.8.0'

  const client = new MongoClient(url, { useUnifiedTopology: true })
  try {
    await client.connect()

    const database = client.db('quote')
    const collection = database.collection('quotes')

    const quotes = await collection.find().toArray()

    // Build the HTML table structure
    let html = '<table border="1">'
    html += '<tr><th>Quote</th><th>Author</th></tr>'
    for (const quote of quotes) {
      html += `<tr><td>${quote.quote}</td><td>${quote.author}</td></tr>`
    }
    html += '</table>'

    return html
  } catch (error) {
    console.error(error)
    return 'Error fetching quotes'
  } finally {
    await client.close()
  }
})

在此端点中,我们检索数据库中所有现有的报价并将它们作为简单的 HTML 表返回。在实际应用程序中,我们会将数据库连接工作提取到一个中心位置。

如果您查看到目前为止应用程序的服务器和客户端,您会发现我们只做了最少的工作。HTMX 在这里简化的最重要的事情是提交表单。hx-post 属性取代了从表单中取出数据、将其编组为 JSON 并使用 fetch() 或类似内容提交的所有工作。

总结

随着事情变得越来越复杂,我们开始不得不依赖客户端中的 JavaScript,即使使用 HTMX。例如,内联行编辑。我们可能希望使用 JavaScript 执行的某些操作(例如将新行直接插入表中)可以通过 HTMX 交换来完成。HTMX 允许您使用简单的语法做很多事情,然后在必要时回退到 JavaScript。

最大的心理变化是从服务器生成 HTMX。您可以选择多种 HTML 或 JavaScript 模板引擎,使这一切变得更加容易。一旦我们习惯使用 HTMX,一切都会变得轻而易举。本质上我们已经从技术栈中消除了整个 JSON 转换层。

我们刚刚通过组合 Bun、Elysia、HTMX 和 MongoDB 进行了简单的演示模版,但您至少应该对这个技术栈有一个感觉,这些组件可以很好地协同工作。Bun、Elysia 和 MongoDB 安静地完成自己的工作,而如果您更习惯 JSON API,则 HTMX 需要多考虑一下。

  • 34
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 线性规划是一种常用于数学建模的方法,其主要目的是在给定约束条件下,寻求一组变量的最优解。线性规划的基本形式包括线性目标函数和线性约束条件,可以用数学公式表示如下: 最大化/最小化:c_1 x_1 + c_2 x_2 + ... + c_n x_n 约束条件: a_1 x_1 + a_2 x_2 + ... + a_n x_n <= b, 其中 x_1, x_2, ..., x_n 是未知变量,c_1, c_2, ..., c_n 和 a_1, a_2, ..., a_n 是给定的系数,b 是给定的常数。 线性规划的案例非常多,广泛应用于经济学、工程学、运输等多个领域。举个例子: 1. 生产规划:工厂生产两种产品,受到生产设备、原料和人力的限制,要使生产的总收益最大化。 2. 资源配置:公司有多个项目,需要分配资源(如人力、资金等),使得总投资回报率最大化。 3. 运输问题:把货物从多个工厂运往多个客户,要满足需求量和运输限制,使运输成本最小化。 线性规划的数学模型通过计算机软件 ### 回答2: 线性规划是一种常见的数学建模方法,广泛应用于优化问题的求解。其基本思想是通过建立目标函数和约束条件,寻找最优解。线性规划的数学模型通常由以下几个要素组成:决策变量、目标函数和约束条件。 首先,决策变量是指需要决策或优化的变量,例如生产数量、投资金额等。其次,目标函数定义了优化问题的目标,包括最大化利润、最小化成本等。最后,约束条件是问题的限制条件,例如资源约束、技术限制等。 线性规划的一个典型案例是生产计划问题。假设某公司生产两种产品A和B,产品A每个单位的利润为10元,产品B每个单位的利润为15元。公司资源有限,每天可用的工时为60小时,A和B产品的生产分别需要2小时和3小时。另外,每天需求量不同,产品A的需求为5个单位,产品B的需求为8个单位。问如何安排生产计划,使得利润最大化? 针对该问题,可以建立如下线性规划模型:设x为生产产品A的单位数量,y为生产产品B的单位数量。则目标函数为最大化10x + 15y,约束条件为2x + 3y ≤ 60和x ≤ 5、y ≤ 8。根据这个模型,可以使用线性规划方法求解最优解。 通过求解得到的最优解是x = 5,y = 8,即应生产5个单位的产品A和8个单位的产品B,此时利润最大化为10*5 + 15*8 = 170元。 这个案例说明了线性规划在实际问题中的应用。通过建立数学模型,可以将实际问题转化为线性规划问题,并通过求解得到最优解,从而得到最佳的决策结果。线性规划的使用方法及案例不仅限于生产计划问题,也适用于其他方面的优化问题,如资源分配、输送问题等。 ### 回答3: 线性规划是一种数学建模方法,可以用于求解具有线性约束的优化问题。它的基本思想是找到一组决策变量的取值,使得目标函数的值最大(或最小),同时满足一系列线性等式或不等式约束条件。 线性规划可以应用于各种实际问题中。例如,在生产调度问题中,线性规划可用于决定每个生产批次所需要的资源,以最大化产出或最小化成本。在运输问题中,线性规划可用于确定不同仓库和客户之间的最佳运输方案,以最小化总运输成本。在市场营销中,线性规划可用于为产品定价,以最大化销售利润。 使用线性规划进行数学建模时,首先需要明确目标函数和约束条件。然后,将目标函数和约束条件转化为数学表达式,并确定决策变量的取值范围。接下来,使用线性规划求解方法(如单纯形法或内点法)找到最优解。最后,根据最优解进行决策,并对结果进行解释和验证。 线性规划的优点之一是它的数学模型相对简单,求解方法也比较成熟。它可以方便地应用于各种实际问题中,并且结果易于理解和解释。然而,线性规划也有一些限制,例如,它只适用于具有线性约束的问题,无法处理非线性约束或目标函数。 总体来说,线性规划是数学建模中一种简洁、有效的方法。通过应用线性规划,可以帮助决策者在复杂的决策问题中寻找最优解,提高效率和经济性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值