۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

توسعه وب تمام پشته با HTMX و Bun، قسمت ۱: Elysia و MongoDB

HTMX را در قسمت جلویی و Bun را در پشت قرار دهید، سپس آن‌ها را با Elysia و MongoDB وصل کنید تا یک پشته فناوری چابک داشته باشید که توسعه برنامه‌های وب را آسان می‌کند.

HTMX را در قسمت جلویی و Bun را در پشت قرار دهید، سپس آن‌ها را با Elysia و MongoDB وصل کنید تا یک پشته فناوری چابک داشته باشید که توسعه برنامه‌های وب را آسان می‌کند.

Bun و HTMX دو مورد از جالب ترین چیزهایی هستند که در حال حاضر در نرم افزار اتفاق می افتد. Bun یک پلت فرم جاوا اسکریپت سمت سرور فوق العاده سریع و همه کاره است و HTMX یک پسوند HTML است که برای ایجاد رابط های ساده و قدرتمند استفاده می شود. در این مقاله، از این دو ابزار عالی با هم برای توسعه یک برنامه فول استک استفاده خواهیم کرد که از MongoDB برای ذخیره سازی داده و Elysia به عنوان سرور HTTP آن.

پشته فناوری

تمرکز ما در این مقاله این است که چگونه چهار جزء اصلی پشته فناوری ما با هم تعامل دارند. اجزای آن Bun، HTMX، Elysia و MongoDB هستند. این پشته یک راه‌اندازی سریع در اختیار شما می‌گذارد که پیکربندی آن آسان و برای تغییر چابک است.

  • Bun یک زمان اجرا جاوا اسکریپت، باندلر، مدیر بسته و اجرای آزمایشی است.
  • Elysia یک سرور HTTP با کارایی بالا است که شبیه Express است اما برای Bun ساخته شده است.
  • HTMX یک رویکرد جدید برای افزودن تعامل دقیق به HTML ارائه می‌دهد.
  • MongoDB گل سرسبد NoSQL ذخیره‌سازی اسناد مدار است.

توجه داشته باشید که این مقاله دارای دو بخش است. در نیمه دوم، Pug، موتور قالب‌بندی HTMX را به کار می‌گیریم، که از آن برای ایجاد چند تعامل فانتزی جلویی استفاده می‌کنیم.

نصب و راه اندازی

باید Bun.js را نصب کنید که انجام آن آسان است. ما همچنین می خواهیم MongoDB را به عنوان یک سرویس در کنار Bun در ماشین توسعه خود اجرا کنیم. می‌توانید درباره نصب و راه‌اندازی MongoDB در اینجا بخوانید. هنگامی که این بسته ها را نصب کردید، هر دو دستور bun -v و mongod -version باید از خط فرمان کار کنند.

بعد، اجازه دهید یک پروژه جدید را شروع کنیم:


$ bun create elysia iw-beh

این به bun می‌گوید که با استفاده از الگوی Elysia یک پروژه جدید ایجاد کند. یک قالب در Bun یک راه راحت برای شروع سریع پروژه ها با استفاده از دستور create است. Bun می تواند مانند Node، بدون هیچ گونه پیکربندی، کار کند، اما پیکربندی آن خوب است. (در اینجا درباره الگوهای Bun بیشتر بیاموزید.)

اکنون، به دایرکتوری جدید بروید: $ 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 را وارد می‌کنیم و از آن برای نمونه‌سازی یک سرور جدید استفاده می‌کنیم که به پورت ۳۰۰۰ گوش می‌دهد و یک نقطه پایانی GET در ریشه دارد. این نقطه پایانی یک رشته متن را برمی‌گرداند: “Hello Elysia”. نحوه عملکرد همه اینها از نظر روحی مشابه Express است.

بزرگترین گلوگاه در مدل های زبان بزرگ

اگر از localhost:3000 بازدید کنید، یک تبریک ساده دریافت خواهید کرد:

یک سلام ساده که می گوید:

اکنون که Elysia در حال اجرا است، اجازه دهید افزونه static را اضافه کنیم. Elysia چندین پلاگین برای مدیریت سناریوهای رایج دارد. در این مورد، ما می خواهیم مقداری HTML را از دیسک ارائه دهیم. افزونه static همان چیزی است که ما به آن نیاز داریم:


$ bun add @elysiajs/static

اکنون سرور Elysia که پلاگین static را اجرا می کند باید همه چیز را در فهرست iw-beh/public ارائه دهد. اگر یک فایل HTML ساده را در آنجا رها کنیم و از localhost:3000/ public بازدید کنیم، محتویات آن را خواهیم دید.

جادوی HTMX

بعد، بیایید یک صفحه HTMX به index.html اضافه کنیم. در اینجا یک مورد ساده از صفحه اصلی 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 دقیق بدون جاوا اسکریپت هستیم. (کار توسط جاوا اسکریپت در کتابخانه htmx.org که ما به تازگی وارد کردیم انجام می شود، اما نکته اینجاست که ما نباید نگران آن باشیم.)

HTMX یک نحو HTML ارائه می کند که این کارها را فقط با استفاده از سه ویژگی عنصر انجام می دهد:

  • hx-post هنگامی که برای درخواست AJAX فعال می شود، پستی را ارسال می کند.
  • hx-target به hx-post می گوید که کدام رویدادها یک درخواست AJAX را اجرا می کنند.
  • hx-swap می‌گوید وقتی یک رویداد AJAX رخ می‌دهد چه باید کرد. در این مورد، عنصر حاضر را با پاسخ جایگزین کنید.

این خیلی ساده است!

Elysia و MongoDB

حالا اجازه دهید یک نقطه پایانی در Elysia ایجاد کنیم که چیزی در MongoDB بنویسد. ابتدا درایور MongoDB را برای Bun اضافه می کنیم:


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 صحبت می‌کند. در حال حاضر، فقط یک نقل قول در پایگاه داده نقل قول، در داخل مجموعه نقل قول می نویسد. می‌توانید مستقیماً با رفتن به localhost:3000/db آن را آزمایش کنید. سپس، می توانید تأیید کنید که داده ها در MongoDB:

اکثر CVE های گزارش شده برای تصاویر Docker Hub بی ضرر هستند

هستند


$ 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' },
    ];
    // Build the HTML list structure
  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 را ایجاد می کنیم. در یک برنامه واقعی، احتمالاً از نوعی چارچوب قالب جاوا اسکریپت-HTML استفاده می‌کنیم تا همه چیز را قابل مدیریت‌تر کنیم.

اکنون، می‌توانیم داده‌ها را از پایگاه داده بازیابی کنیم:


.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 با یک ردیف و متن.

این اسکرین شات ردیفی را نشان می‌دهد که ما با ضربه زدن به نقطه پایانی /db قبلاً درج کردیم.

7 روپیه نوسازی اپلیکیشن ابری

اکنون، اجازه دهید توانایی ایجاد یک نقل قول جدید را اضافه کنیم. این کد پشتیبان (src/index.ts):

است


app.post("/add-quote", async (req) => {
    const url = "mongodb://127.0.0.1:27017/quote?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.8.0";

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

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

        const quote = req.body.quote;
        const author = req.body.author;

        await collection.insertOne({ quote, author });

        return "Quote added successfully";
    } catch (error) {
        console.error(error);
        return "Error adding quote";
    } finally {
        await client.close();
    }
})

و قسمت جلویی اینجاست (public/index.html):


<form hx-post="/add-quote">
    <input type="text" name="quote" placeholder="Enter quote">
    <input type="text" name="author" placeholder="Enter author">
<button type="submit">Add Quote</button>

وقتی نویسنده و نقل قول را وارد می‌کنید و افزودن نقل قول را فشار می‌دهید، به پایگاه داده اضافه می‌شود. اگر روی بارگیری داده ها کلیک کنید، به روز رسانی خود را در لیست خواهید دید. باید چیزی شبیه این باشد:

جدول HTMX با دو ردیف و متن.

اگر به سرور و سرویس گیرنده برنامه تا کنون نگاه کنید، می بینید که ما حداقل کار را انجام می دهیم. بزرگترین چیزی که HTMX در اینجا ساده کرده است، ارسال فرم است. ویژگی hx-post جایگزین تمام کارهای مربوط به برداشتن داده‌ها از فرم، ترکیب آن در JSON و ارسال آن با fetch() یا چیزی مشابه می‌شود.

نتیجه گیری

با پیچیده‌تر شدن همه چیز، حتی با HTMX مجبور می‌شوید به جاوا اسکریپت در کلاینت تکیه کنید. برای مثال، ویرایش ردیف درون خطی. برخی از مواردی که ممکن است انتظار داشته باشید از جاوا اسکریپت برای آنها استفاده کنید، مانند درج ردیف های جدید به طور مستقیم در جدول، می توانند با HTMX انجام شوند. مبادله. HTMX به شما این امکان را می دهد تا با نحو ساده خود کارهای زیادی انجام دهید و در صورت لزوم دوباره به جاوا اسکریپت برگردید.

بزرگترین تغییر ذهنی در تولید HTMX از سرور است. شما می توانید از بین چند موتور قالب HTML یا جاوا اسکریپت سطح بالا انتخاب کنید. بسیار ساده تر. زمانی که به کار با HTMX عادت کردید، خیلی خوب است. در اصل، شما کل لایه تبدیل JSON را از پشته حذف کرده اید.

ما به‌تازگی از ترکیب bun، Elysia، HTMX، و MongoDB سریع‌ترین کار را انجام داده‌ایم، اما شما حداقل باید احساسی نسبت به این پشته داشته باشید. اجزاء بدون هیچ گونه اصطکاک غیر ضروری به خوبی با هم کار می کنند. Bun، Elysia و MongoDB بی سر و صدا وظایف خود را انجام می دهند، در حالی که HTMX اگر به API های JSON عادت دارید کمی بیشتر فکر کنید. کد این مقاله را در مخزن GitHub من پیدا کنید. در مقاله بعدی با این مثال بیشتر کار خواهیم کرد، جایی که از Pug برای افزودن برخی تعاملات فانتزی به ترکیب استفاده خواهیم کرد.