برنامه نویسی

اسناد چند چارچوبی با Astro Starlight

Summarize this content to 400 words in Persian Lang

Arcjet به توسعه دهندگان کمک می کند تا از برنامه های خود در برابر حملات رایج ربات ها، سوء استفاده از API، هرزنامه فرم ها و سایر نگرانی های امنیتی محافظت کنند. توسعه‌دهندگان معمولاً کارشناسان امنیتی نیستند، بنابراین اسناد ما اهمیت ویژه‌ای دارند.

اسناد ما به عنوان سنگ بنای ارتباط ما با آنها عمل می کنند Arcjet کاربران اینجاست که ما محصول را توضیح می دهیم و به مردم یاد می دهیم که چگونه Arcjet's را یکپارچه کنند امنیت به عنوان کد قابلیت هایی مانند تشخیص ربات، تشخیص PII و اعتبارسنجی ایمیل.

توسعه‌دهندگان ابتدا از اسناد بازدید می‌کنند و بر اساس احساسات اولیه‌ای که از وب‌سایت، وبلاگ، یک کنفرانس، برخی پوشش‌های اجتماعی یا هر جایی که در مورد ما شنیده‌اند، دریافت می‌کنند.

با توجه به اینکه محصول در هسته خود یک SDK امنیتی در دست توسعه دهندگان است، بسیار مهم است که مستندات آن قابل اعتماد، جامع، خشک و به نقطه، دسترسی آسان.

ما تیم کوچکی هستیم و به همین دلیل باید اولویت ها را به دقت در نظر بگیریم. با توجه به کیفیت محتوا که دغدغه اصلی ما است، اسناد ما عملکرد قوی و توسعه یافته ای را ارائه می دهند، اما همچنان از نظر بصری WIP هستند. نگران نباشید، به زودی به آن خواهیم رسید!

اسناد Devtools پیچیده است

زندگی پیچیده است، به خصوص در مراحل اولیه یک محصول امنیتی جاه طلبانه، جایی که همه چیز باید دیروز اتفاق بیفتد، در حالی که در کنار شرکت هایی با مقیاس x4-5-6 برابر قدم می زنید.

بنابراین بله، ما به اسناد درجه یک نیاز داشتیم، اما البته باید SDK، Cloud API را نیز توسعه می‌دادیم، درخواست‌های دریافتی را به زیرساختمان مدیریت می‌کردیم و همه این قابلیت‌ها را از طریق برنامه وب، وب‌سایت، وبلاگ و غیره نشان می‌دادیم.

راه اندازی اولیه

بهترین راه برای سریع چیست ایجاد کنید، خدمت کنید و حفظ کند یک منبع مستند با کوچکترین هزینه توسعه؟

ما در ابتدا با نکسترا، یک چارچوب اسناد برای Next.js، زیرا ما قبلاً از Next.js برای داشبورد برنامه و وب سایت خود استفاده می کنیم. با این حال، ما متوجه شدیم که آن را بسیار غیر قابل انعطاف و سفارشی کردن آن دشوار است.

پس از ارزیابی، به سراغ آن رفتیم نور ستاره: ارائه بدون نیاز، محتوا محور Astro چارچوب docs، که سریع و راحت است، با جستجوی داخلی.

این یک انتخاب بسیار منعطف و تقریباً بدون اصطکاک در پذیرش بوده است و تا همین اواخر به خوبی در خدمت ما بوده است. با این حال، هنگامی که SDK ما شروع به اضافه کردن پشتیبانی برای چارچوب‌های مختلف، توسعه عملکرد و افزایش ویژگی‌های آن کرد، متوجه شدیم که ساختار اسناد معیوب شده و کار کردن با آن دردناک است.

تلاش برای مستندسازی تمام چارچوب هایی که Arcjet پشتیبانی می کند.

مشکل

این ساختار معیوب به دلیل محدودیت های عملکرد پیش فرض Starlight همراه با آناتومی محصول ما بود.

ما خودمان را با صفحات جداگانه (به عنوان مثال: شروع سریع، مرجع و موارد دیگر) یافتیم که برای هر چارچوبی که پشتیبانی می‌کنیم، تنها با تفاوت‌های جزئی مربوط به ویژگی‌های چارچوب تکرار شده است.

نوار کناری اسناد Arcjet قدیمی.

این چندین نقطه درد را با اجرای اسناد ما ایجاد کرد:

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

ما همچنین متوجه شدیم که چند الزام خاص داریم که Starlight مانند اسناد نسخه‌شده که منعکس‌کننده نسخه SDK و توانایی تولید خودکار انواع قطعه کد بدون نیاز به نوشتن با دست هستند، ارائه نمی‌کند (به عنوان مثال: .ts > .js)

مستندات به عنوان محصول

ما به زودی متوجه شدیم که باید ساختار اسناد خود را سفارشی کنیم تا آنها را با نیازهای خاص محصول خود مطابقت دهیم. هدف این بود که منبع را از یک طرف کارآمد نگه داریم و از طرف دیگر هزینه های تعمیر و نگهداری را کنترل کنیم.

ما الزامات زیر را شناسایی کردیم:

بدون صفحات تکراری، بدون محتوای تکراری در صفحه – به طوری که تعمیر و نگهداری آسان تر است.

بدون ناوبری اضافی – بار شناختی کاربران را بهینه کنید و درک محصول را آسان تر کنید.

هر محتوا را بر اساس چارچوب تغییر دهید: متن، قطعه کد و غیره. – جریان طبیعی اسناد را بهبود می بخشد.

زمینه چارچوب انتخاب شده را حفظ کنید – آن را برای کاربران مرتبط تر می کند.

به راحتی همه جایگشت های چارچوب و کد را پیمایش کنید – اسناد با استفاده سریع

تکه های کد صحیح – باید بتوانیم کد را برای خطاها آزمایش کنیم.

برای دستیابی به نتایج فوق، مجبور شدیم تعدادی تغییرات را در معماری اسناد خود و نحوه ارائه آن اعمال کنیم.

محتوای صفحه

بخش عمده کار بازنگری در معماری محتوا بود. ما اساساً نیاز داشتیم که چندین گونه از صفحات یکسان را در حداقل دو بعد – چارچوب و زبان – مدیریت کنیم و عملکردی نرم برای پیمایش در آن ارائه دهیم.

یک مثال معمولی خواهد بود شروع سریع صفحه برای یکی از موارد اولیه ما، این می تواند یک منبع واحد در نظر گرفته شود، به عنوان مثال: ویژگی ها / محدود کردن نرخ / شروع سریع اما هنگام در نظر گرفتن چارچوب و زبان کد دارای 8 جایگشت مختلف است:

زبان

چارچوب
Node.js / TS
Node.js / JS

Next.js / TS
Next.js / JS

Bun / TS
Bun / JS

SvelteKit / TS
SvelteKit / JS

هدف این بود که به صورت مفهومی یک صفحه واحد ایجاد کنیم، که سپس می‌توانست انواع مختلفی را بر اساس ترجیح چارچوب، زبان و هر بعد دیگری که لازم است ارائه کند. ما باید خود را با انتخاب کاربر وفق می‌دادیم، بنابراین این باید شامل تعامل سمت مشتری باشد.

متأسفانه، استارلایت روش داخلی برای رسیدگی به این نوع سناریوها، که تا حدی مختص محصولات چند پلتفرمی مانند Arcjet است، ارائه نمی دهد.

با این حال Astro راهی برای اضافه کردن محتوای پویا به صفحات با استفاده از آن ارائه می دهد جزایر Astro. ما متوجه شدیم که می‌توانیم از این برای بازگشایی قدرت یک چارچوب پویا مانند React Surgically استفاده کنیم تا قسمت‌هایی از محتوای صفحه را در صورت تقاضا تغییر دهیم:

تعریف معماری جزایر:

ایده کلی معماری “جزایر” به طرز فریبنده ای ساده است: صفحات HTML را بر روی سرور رندر کنید و مکان های نگهدارنده یا اسلات ها را در اطراف مناطق بسیار پویا تزریق کنید. […] که سپس می‌تواند روی کلاینت به ویجت‌های کوچک مستقل تبدیل شود و از HTML اولیه ارائه‌شده توسط سرور خود استفاده مجدد کند.

بنابراین ما تعدادی از مؤلفه‌های کاربردی React ایجاد کردیم که می‌توانند این هیدراتاسیون مشروط را همراه با همتایان تعویض‌کننده UI خود کنترل کنند.

0:00/0:081×

سوئیچرها یک عنصر حیاتی برای پیمایش محتوا به این روش هستند و به همین دلیل باید به سرعت در دسترس باشند تا بتوانند به طور موثر مقرون به صرفه بودن صفحه را تعریف کنند. ما آنها را در چندین مکان اضافه کردیم:

دکمه های انتخاب چارچوب در اسناد Arcjet.

تعویض کننده چارچوب در نوار کناری اسناد Arcjet.

تغییر دهنده چارچوب در محتوا.

در زیر کاپوت، سوئیچرها از طریق صفحه MDX frontmatter مطلع می شوند که توضیح می دهد کدام چارچوب ها را در دسترس قرار دهند:


title: “Get started with Arcjet”
description: “Getting started with Arcjet. Quick start guide to protect your app from attacks, apply a rate limit, and prevent bots from accessing your NestJS, Next.js, Node.js, Bun, or SvelteKit app.”
frameworks:
– bun
– bun-hono
– deno
– nest-js
– next-js
– node-js
– node-js-express
– node-js-hono
– remix
– sveltekit

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

mdx frontmatter سفارشی که چارچوب های موجود را برای این صفحه تعریف می کند.

فقط با یک اضافه کوچک به طرح مجموعه اسناد Starlight:

import type { FrameworkKey } from “@/lib/prefs”;
import { docsSchema } from “@astrojs/starlight/schema”;
import { defineCollection, z } from “astro:content”;

export const collections = {
docs: defineCollection({
schema: docsSchema({
extend: z.object({
frameworks: z.custom().optional(), // Our addition
pageTitle: z.custom<{ [key in FrameworkKey]: string }>().optional(),
}),
}),
}),
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این به ما این امکان را می‌دهد که یک لفاف در اطراف چارچوب خاص ارائه کنیم .mdx یا .astro اجزایی که سوئیچینگ محتوا را اجرا می کنند.

### 3. Add a rate limit to a route

The example below applies a token bucket rate limit rule to a route where we
identify the user based on their ID e.g. if they are logged in. The bucket is
configured with a maximum capacity of 10 tokens and refills by 5 tokens every
10 seconds. Each request consumes 5 tokens.

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

جزء چارچوب سفارشی ما.

سپس برای هر فریم ورک بر اساس زبان و/یا ابعاد دیگر به پایین‌تر درخت می‌رسیم:

import Step3TS from “./Step3.ts?raw”;
import Step3JS from “./Step3.js?raw”;
import { Code } from “@astrojs/starlight/components”;
import SelectableContent from “@/components/SelectableContent”;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

انتخاب کد بر اساس زبان

این به ما اجازه می دهد تا بدون نیاز به ایجاد صفحات دستی برای هر جایگشت فردی – که به راحتی از کنترل خارج می شود – ابعاد N داشته باشیم، اما فقط با تکه هایی که لزوماً متفاوت هستند سروکار داریم.

مطمئناً در جزئیات وجود دارد، بنابراین تعدادی از موارد اضافی برای تکمیل وجود دارد، مانند پیش‌فرض‌های ماندگار در فضای ذخیره‌سازی محلی برای کاربران بازگشتی، ایجاد انواع صفحات به‌صورت جداگانه از طریق پارامترهای URL و غیره.

وضعیت اشتراک گذاری

این نکته جالب‌تری بود – باعث می‌شد هر (و همه) جزیره‌ها از یک به‌روزرسانی ترجیحی آگاه شوند (و نسبت به آن واکنش نشان دهند). اینجاست که ما کشف کردیم که ارائه دهندگان زمینه با هیدراتاسیون جزئی ارائه شده توسط Astro کار نمی کنند client:* بخشنامه ها

مورد استفاده برای مدیریت دولتی در اینجا بسیار ساده است، بنابراین یک شیرجه سریع در آن است فروشگاه های نانو راه حل را ارائه کرد.

فروشگاه را تعریف کنید:

import { atom } from “nanostores”;

import type { Framework, FrameworkKey } from “./lib/prefs”;
import { defaultSelectedFramework, frameworks } from “./lib/prefs”;

export const displayedFramework = atom(defaultSelectedFramework);
export const queryParamFramework = atom();
export const availableFrameworks = atom>(frameworks);

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

store.ts

مدیریت آن در اجزای:

import Select from “@/components/Select”;
import {
availableFrameworks,
displayedFramework,
queryParamFramework,
} from “@/store”;
import { useStore } from “@nanostores/react”;
import { useEffect } from “react”;

const FrameworkSwitcher = (…) => {

const $availableFrameworks = useStore(availableFrameworks);
const $displayedFramework = useStore(displayedFramework);
const $queryParamFramework = useStore(queryParamFramework);

const onChange = (e: ChangeEvent) => {

displayedFramework.set(val);
};

useEffect(() => {

availableFrameworks.set(val);
}, []);

return ;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

FrameworkSwitcher.tsx

import type { FrameworkKey } from “@/lib/prefs”;
import { displayedFramework } from “@/store”;
import { useStore } from “@nanostores/react”;
import { useEffect, useState } from “react”;

const SlotByFramework = (…) => {

const $displayedFramework = useStore(displayedFramework);
const [selectedFramework, setSelectedFramework] = useState();

useEffect(() => {
setSelectedFramework($displayedFramework);
}, [$displayedFramework]);

// return Slot for selectedFramework
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

SlotByFramework.tsx

سازماندهی پرونده

ما پیکربندی محتوای قبلی را تغییر ندادیم، بنابراین همچنان از آن استفاده می‌کنیم مجموعه های محتوا مطابق با تم پیش فرض Starlight.

Astro 4 معرفی شد یک API لایه محتوای آزمایشی جدید که هست تثبیت در Astro 5 بنابراین می توانیم محتوا را به یک CMS یا سیستم دیگری منتقل کنیم.

با این حال، چیزی زیبا در مورد داشتن محتوا در MDX وجود دارد که در همان مخزن GitHub قرار دارد. اسناد ما منبع باز هستند و می‌توانیم از ابزار گردش کار GitHub مانند تفاوت‌ها، نظرات، درخواست‌های کششی و غیره استفاده کنیم.

برای نمونه کد، ما یک سفارشی را حفظ می کنیم snippets/ پوشه داخل سایت src/ که سطل تمام نمونه کدهای فردی است.

ساختار پوشه Arcjet Docs.

هر نمونه کد یک فایل زبان واقعی است که توسط – وارد شده در – پیچیده شده است .mdx که توسط جزایر آگاه چارچوب ارائه می شود. این مزیت این است که به ما امکان می دهد آنها را به عنوان کد واقعی در نظر بگیریم.

یکی از آزاردهنده‌ترین چیزها هنگام خواندن اسناد، نمونه‌های کدی است که کار نمی‌کنند، بنابراین این به ما کمک می‌کند مطمئن شویم که کد حداقل از نظر نحوی صحیح است و با همه انواعی که وارد می‌کنیم مطابقت دارد. توانایی استفاده از ویژگی های LSP ویرایشگر ما واقعا کمک می کند!

نوار کناری سفارشی Astro Starlight

تطبیق نوار کناری سایت با معماری محتوای جدید گام طبیعی بعدی بود. این به طرح اولیه ساختار اسناد ما تبدیل می شود – قطب نمای کاربران. ما مجبور شدیم از تودرتو چند منظوره عمومی ارائه شده توسط Starlight دور شویم:

_سطح 1 > سطح 2 > … > صفحه _

و یک سلسله مراتب سفارشی، ساختارمندتر را نشان دهید:

بخش > موضوع > صفحه

دستیابی به این امر با استفاده از قابلیت Starlight داخلی به اندازه کافی آسان بود. یک را ایجاد کردیم نادیده گرفتن کامپوننت برای مولفه نوار کناری تم پیش‌فرض برای فضای نامی همه چیز .aj-sidebar.


import SidebarLinks from “@/components/SidebarLinks.astro”;
import Default from “@astrojs/starlight/components/Sidebar.astro”;
import type { Props } from “@astrojs/starlight/props”;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

components/overrides/Sidebar.astro

سپس یک تعریف نوار کناری سفارشی با ویژگی‌های اضافی ایجاد کرده‌ایم که به تخصصی کردن ظاهر سطوح مختلف نوار کناری کمک می‌کند.

export const main = [

{
label: “Integrations”,
collapsed: false,
items: [
{
label: “Auth.js”,
link: “/integrations/authjs”,
},
{
label: “Clerk”,
link: “/integrations/clerk”,
},
{
label: “Fly.io”,
link: “https://fly.io/docs/reference/arcjet/”,
attrs: { target: “_blank”, class: “external-link” },
},

],
},

];

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نوار کناری اصلی ما در مقابل نوار جدید – خداحافظ افزونگی!

نوار کناری اسناد Arcjet جدید.

نوار کناری صفحه Astro Starlight سفارشی

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

با این حال، تغییر محتوا بر روی مشتری اتفاق می‌افتد، در حالی که TOC استاندارد موضوع Starlight در زمان ساخت ایجاد می‌شود، به این معنی که در هر انتخاب فریم ورک از همگام‌سازی خارج می‌شود.

برای رفع موارد بالا و داشتن یک نوار کناری همگام‌سازی حالت، باید یک سفارشی ایجاد می‌کردیم نادیده گرفتن کامپوننت، تکرار همه عملکردهای TOC.

از آنجایی که Starlight TOC هیچ اطلاعی از عناوین مختلف موجود در آن ندارد .mdx محتوا و هیدراته شده توسط جزایر مختلف، ما طرح مجموعه اسناد را با یک تعریف شی TOC سفارشی گسترش دادیم. این را می توان در قسمت اول هر صفحه استفاده کرد:

import type { FrameworkKey } from “@/lib/prefs”;
import { docsSchema } from “@astrojs/starlight/schema”;
import { defineCollection, z } from “astro:content”;

export type TocNode = {
text: string;
anchor: string;
framework: FrameworkKey | FrameworkKey[];
children: TocNode[];
};

export const collections = {
docs: defineCollection({
schema: docsSchema({
extend: z.object({
ajToc: z.custom(), // Our addition
frameworks: z.custom().optional(),
pageTitle: z.custom<{ [key in FrameworkKey]: string }>().optional(),
}),
}),
}),
};


title: “Rate limiting”
description: “Quick start guide for adding Arcjet rate limiting to your Next.js, Node.js, Bun, or SvelteKit app.”
frameworks:
– bun
– next-js
– node-js
– sveltekit
ajToc:
– text: “Video quick start”
anchor: “video-quick-start”
framework: “next-js”
– text: “Quick start”
anchor: “quick-start”
children:
– text: 1. Install Arcjet
anchor: “1-install-arcjet”
– text: 2. Set your key
anchor: “2-set-your-key”
– text: 3. Add a rate limit to a route
anchor: “3-add-a-rate-limit-to-a-route”
– text: 4. Start server
anchor: “4-start-server”
framework: [“bun”, “node-js”] – text: 4. Start app
anchor: “4-start-app”
framework: [“next-js”, “sveltekit”] – text: “FAQs”
anchor: “faqs”
– text: “What next?”
anchor: “what-next”
– text: “Get help”
anchor: “get-help”

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

با این رویکرد می‌توانیم عناوین خاص چارچوب را توصیف کنیم تا TOC بتواند تغییر کند و با محتوا سازگار بماند.

زندگی جدید

ما تغییرات را چند هفته پیش ارسال کردیم و این زندگی جدید چگونه است؟

کاربران می توانند کاملاً در چارچوب انتخابی خود پیمایش کنند:

0:00/0:121×

پیمایش اسناد Arcjet بر اساس چارچوب.

MDX مرتب به نظر می رسد، بار تعمیر و نگهداری کمتر == اشتباهات کمتر: صفحه زیر همه انواع چارچوب و کد (!!!) را برای صفحه “شروع به کار” ما شرح می دهد: https://raw.githubusercontent.com/arcjet/arcjet-docs/refs/heads/main/src/content/docs/ get-started.mdx

مزایای کسب و کار ، ما شاهد افزایش ترافیک جستجو هستیم، اکنون فقط یک نسخه از هر صفحه سند داریم.

نتایج جستجوی Google برای اسناد Arcjet.

اسناد ما را به صورت زنده ببینید و عملکرد آنها را بررسی کنید.

تیم Arcjet در حال مرور اسناد جدید است.

بعدش چی

نسخه سازی

یکی از الزامات تغییر ساختار اسناد این بود که نسخه‌سازی را به اسناد خود وارد کنیم تا با نسخه SDK مطابقت داشته باشد.

هیچ راه ساده ای برای پیاده سازی نسخه های اسناد در Starlight وجود ندارد. اولین تلاش های ما مبتنی بر فایل بود، چه با کد سفارشی و چه با افزونه هایی مانند نسخه های Starlight، اما به این نتیجه رسیدیم که نسخه سازی شعبه احتمالاً رویکردی قوی تر و نگهداری آسان تر را نشان خواهد داد.

طراحی

ما داریم تعدادی به روز رسانی در فروشگاه برای ظاهر و احساس اسناد هدف این است که از یک طرف UX را صاف کنیم و از طرف دیگر کاربران را به داخل و خارج از اسناد و از طریق دیگر منابع آنلاین Arcjet هدایت کنیم.

ما اسناد Arcjet را بخشی از محصول می‌دانیم، بنابراین همیشه کارهای بیشتری برای انجام دادن وجود دارد!

اسناد چند چارچوبی با Astro Starlight

Arcjet به توسعه دهندگان کمک می کند تا از برنامه های خود در برابر حملات رایج ربات ها، سوء استفاده از API، هرزنامه فرم ها و سایر نگرانی های امنیتی محافظت کنند. توسعه‌دهندگان معمولاً کارشناسان امنیتی نیستند، بنابراین اسناد ما اهمیت ویژه‌ای دارند.

اسناد ما به عنوان سنگ بنای ارتباط ما با آنها عمل می کنند Arcjet کاربران اینجاست که ما محصول را توضیح می دهیم و به مردم یاد می دهیم که چگونه Arcjet's را یکپارچه کنند امنیت به عنوان کد قابلیت هایی مانند تشخیص ربات، تشخیص PII و اعتبارسنجی ایمیل.

توسعه‌دهندگان ابتدا از اسناد بازدید می‌کنند و بر اساس احساسات اولیه‌ای که از وب‌سایت، وبلاگ، یک کنفرانس، برخی پوشش‌های اجتماعی یا هر جایی که در مورد ما شنیده‌اند، دریافت می‌کنند.

با توجه به اینکه محصول در هسته خود یک SDK امنیتی در دست توسعه دهندگان است، بسیار مهم است که مستندات آن قابل اعتماد، جامع، خشک و به نقطه، دسترسی آسان.

ما تیم کوچکی هستیم و به همین دلیل باید اولویت ها را به دقت در نظر بگیریم. با توجه به کیفیت محتوا که دغدغه اصلی ما است، اسناد ما عملکرد قوی و توسعه یافته ای را ارائه می دهند، اما همچنان از نظر بصری WIP هستند. نگران نباشید، به زودی به آن خواهیم رسید!

اسناد Devtools پیچیده است

زندگی پیچیده است، به خصوص در مراحل اولیه یک محصول امنیتی جاه طلبانه، جایی که همه چیز باید دیروز اتفاق بیفتد، در حالی که در کنار شرکت هایی با مقیاس x4-5-6 برابر قدم می زنید.

بنابراین بله، ما به اسناد درجه یک نیاز داشتیم، اما البته باید SDK، Cloud API را نیز توسعه می‌دادیم، درخواست‌های دریافتی را به زیرساختمان مدیریت می‌کردیم و همه این قابلیت‌ها را از طریق برنامه وب، وب‌سایت، وبلاگ و غیره نشان می‌دادیم.

راه اندازی اولیه

بهترین راه برای سریع چیست ایجاد کنید، خدمت کنید و حفظ کند یک منبع مستند با کوچکترین هزینه توسعه؟

ما در ابتدا با نکسترا، یک چارچوب اسناد برای Next.js، زیرا ما قبلاً از Next.js برای داشبورد برنامه و وب سایت خود استفاده می کنیم. با این حال، ما متوجه شدیم که آن را بسیار غیر قابل انعطاف و سفارشی کردن آن دشوار است.

پس از ارزیابی، به سراغ آن رفتیم نور ستاره: ارائه بدون نیاز، محتوا محور Astro چارچوب docs، که سریع و راحت است، با جستجوی داخلی.

این یک انتخاب بسیار منعطف و تقریباً بدون اصطکاک در پذیرش بوده است و تا همین اواخر به خوبی در خدمت ما بوده است. با این حال، هنگامی که SDK ما شروع به اضافه کردن پشتیبانی برای چارچوب‌های مختلف، توسعه عملکرد و افزایش ویژگی‌های آن کرد، متوجه شدیم که ساختار اسناد معیوب شده و کار کردن با آن دردناک است.

اسناد چند چارچوبی با Astro Starlight
تلاش برای مستندسازی تمام چارچوب هایی که Arcjet پشتیبانی می کند.

مشکل

این ساختار معیوب به دلیل محدودیت های عملکرد پیش فرض Starlight همراه با آناتومی محصول ما بود.

ما خودمان را با صفحات جداگانه (به عنوان مثال: شروع سریع، مرجع و موارد دیگر) یافتیم که برای هر چارچوبی که پشتیبانی می‌کنیم، تنها با تفاوت‌های جزئی مربوط به ویژگی‌های چارچوب تکرار شده است.

اسناد چند چارچوبی با Astro Starlight
نوار کناری اسناد Arcjet قدیمی.

این چندین نقطه درد را با اجرای اسناد ما ایجاد کرد:

  • هیچ مسیر مشخصی برای کاربر متمرکز بر پشته فناوری خاص خود وجود نداشت.
  • ما بار تعمیر و نگهداری، ویرایش صفحات تکراری و همگام نگه داشتن محتوای آنها را داشتیم.
  • آسیب به سئو، زیرا خزنده ها مطلقاً منابع تکراری را دوست ندارند.

ما همچنین متوجه شدیم که چند الزام خاص داریم که Starlight مانند اسناد نسخه‌شده که منعکس‌کننده نسخه SDK و توانایی تولید خودکار انواع قطعه کد بدون نیاز به نوشتن با دست هستند، ارائه نمی‌کند (به عنوان مثال: .ts > .js)

مستندات به عنوان محصول

ما به زودی متوجه شدیم که باید ساختار اسناد خود را سفارشی کنیم تا آنها را با نیازهای خاص محصول خود مطابقت دهیم. هدف این بود که منبع را از یک طرف کارآمد نگه داریم و از طرف دیگر هزینه های تعمیر و نگهداری را کنترل کنیم.

ما الزامات زیر را شناسایی کردیم:

  • بدون صفحات تکراری، بدون محتوای تکراری در صفحه – به طوری که تعمیر و نگهداری آسان تر است.
  • بدون ناوبری اضافی – بار شناختی کاربران را بهینه کنید و درک محصول را آسان تر کنید.
  • هر محتوا را بر اساس چارچوب تغییر دهید: متن، قطعه کد و غیره. – جریان طبیعی اسناد را بهبود می بخشد.
  • زمینه چارچوب انتخاب شده را حفظ کنید – آن را برای کاربران مرتبط تر می کند.
  • به راحتی همه جایگشت های چارچوب و کد را پیمایش کنید – اسناد با استفاده سریع
  • تکه های کد صحیح – باید بتوانیم کد را برای خطاها آزمایش کنیم.

برای دستیابی به نتایج فوق، مجبور شدیم تعدادی تغییرات را در معماری اسناد خود و نحوه ارائه آن اعمال کنیم.

محتوای صفحه

بخش عمده کار بازنگری در معماری محتوا بود. ما اساساً نیاز داشتیم که چندین گونه از صفحات یکسان را در حداقل دو بعد – چارچوب و زبان – مدیریت کنیم و عملکردی نرم برای پیمایش در آن ارائه دهیم.

یک مثال معمولی خواهد بود شروع سریع صفحه برای یکی از موارد اولیه ما، این می تواند یک منبع واحد در نظر گرفته شود، به عنوان مثال: ویژگی ها / محدود کردن نرخ / شروع سریع اما هنگام در نظر گرفتن چارچوب و زبان کد دارای 8 جایگشت مختلف است:

زبان
چارچوب Node.js / TS Node.js / JS
Next.js / TS Next.js / JS
Bun / TS Bun / JS
SvelteKit / TS SvelteKit / JS

هدف این بود که به صورت مفهومی یک صفحه واحد ایجاد کنیم، که سپس می‌توانست انواع مختلفی را بر اساس ترجیح چارچوب، زبان و هر بعد دیگری که لازم است ارائه کند. ما باید خود را با انتخاب کاربر وفق می‌دادیم، بنابراین این باید شامل تعامل سمت مشتری باشد.

متأسفانه، استارلایت روش داخلی برای رسیدگی به این نوع سناریوها، که تا حدی مختص محصولات چند پلتفرمی مانند Arcjet است، ارائه نمی دهد.

با این حال Astro راهی برای اضافه کردن محتوای پویا به صفحات با استفاده از آن ارائه می دهد جزایر Astro. ما متوجه شدیم که می‌توانیم از این برای بازگشایی قدرت یک چارچوب پویا مانند React Surgically استفاده کنیم تا قسمت‌هایی از محتوای صفحه را در صورت تقاضا تغییر دهیم:

تعریف معماری جزایر:

ایده کلی معماری “جزایر” به طرز فریبنده ای ساده است: صفحات HTML را بر روی سرور رندر کنید و مکان های نگهدارنده یا اسلات ها را در اطراف مناطق بسیار پویا تزریق کنید. […] که سپس می‌تواند روی کلاینت به ویجت‌های کوچک مستقل تبدیل شود و از HTML اولیه ارائه‌شده توسط سرور خود استفاده مجدد کند.

بنابراین ما تعدادی از مؤلفه‌های کاربردی React ایجاد کردیم که می‌توانند این هیدراتاسیون مشروط را همراه با همتایان تعویض‌کننده UI خود کنترل کنند.

0:00
/0:08

سوئیچرها یک عنصر حیاتی برای پیمایش محتوا به این روش هستند و به همین دلیل باید به سرعت در دسترس باشند تا بتوانند به طور موثر مقرون به صرفه بودن صفحه را تعریف کنند. ما آنها را در چندین مکان اضافه کردیم:

اسناد چند چارچوبی با Astro Starlight
دکمه های انتخاب چارچوب در اسناد Arcjet.

اسناد چند چارچوبی با Astro Starlight
تعویض کننده چارچوب در نوار کناری اسناد Arcjet.

اسناد چند چارچوبی با Astro Starlight
تغییر دهنده چارچوب در محتوا.

در زیر کاپوت، سوئیچرها از طریق صفحه MDX frontmatter مطلع می شوند که توضیح می دهد کدام چارچوب ها را در دسترس قرار دهند:

---
title: "Get started with Arcjet"
description: "Getting started with Arcjet. Quick start guide to protect your app from attacks, apply a rate limit, and prevent bots from accessing your NestJS, Next.js, Node.js, Bun, or SvelteKit app."
frameworks:
  - bun
  - bun-hono
  - deno
  - nest-js
  - next-js
  - node-js
  - node-js-express
  - node-js-hono
  - remix
  - sveltekit
---
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

mdx frontmatter سفارشی که چارچوب های موجود را برای این صفحه تعریف می کند.

فقط با یک اضافه کوچک به طرح مجموعه اسناد Starlight:

import type { FrameworkKey } from "@/lib/prefs";
import { docsSchema } from "@astrojs/starlight/schema";
import { defineCollection, z } from "astro:content";

export const collections = {
  docs: defineCollection({
    schema: docsSchema({
      extend: z.object({
        frameworks: z.custom().optional(), // Our addition
        pageTitle: z.custom<{ [key in FrameworkKey]: string }>().optional(),
      }),
    }),
  }),
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این به ما این امکان را می‌دهد که یک لفاف در اطراف چارچوب خاص ارائه کنیم .mdx یا .astro اجزایی که سوئیچینگ محتوا را اجرا می کنند.

### 3. Add a rate limit to a route

The example below applies a token bucket rate limit rule to a route where we
identify the user based on their ID e.g. if they are logged in. The bucket is
configured with a maximum capacity of 10 tokens and refills by 5 tokens every
10 seconds. Each request consumes 5 tokens.


  
  
  
  



  
  
  
  

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

جزء چارچوب سفارشی ما.

سپس برای هر فریم ورک بر اساس زبان و/یا ابعاد دیگر به پایین‌تر درخت می‌رسیم:

import Step3TS from "./Step3.ts?raw";
import Step3JS from "./Step3.js?raw";
import { Code } from "@astrojs/starlight/components";
import SelectableContent from "@/components/SelectableContent";


  
  

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

انتخاب کد بر اساس زبان

این به ما اجازه می دهد تا بدون نیاز به ایجاد صفحات دستی برای هر جایگشت فردی – که به راحتی از کنترل خارج می شود – ابعاد N داشته باشیم، اما فقط با تکه هایی که لزوماً متفاوت هستند سروکار داریم.

مطمئناً در جزئیات وجود دارد، بنابراین تعدادی از موارد اضافی برای تکمیل وجود دارد، مانند پیش‌فرض‌های ماندگار در فضای ذخیره‌سازی محلی برای کاربران بازگشتی، ایجاد انواع صفحات به‌صورت جداگانه از طریق پارامترهای URL و غیره.

وضعیت اشتراک گذاری

این نکته جالب‌تری بود – باعث می‌شد هر (و همه) جزیره‌ها از یک به‌روزرسانی ترجیحی آگاه شوند (و نسبت به آن واکنش نشان دهند). اینجاست که ما کشف کردیم که ارائه دهندگان زمینه با هیدراتاسیون جزئی ارائه شده توسط Astro کار نمی کنند client:* بخشنامه ها

مورد استفاده برای مدیریت دولتی در اینجا بسیار ساده است، بنابراین یک شیرجه سریع در آن است فروشگاه های نانو راه حل را ارائه کرد.

فروشگاه را تعریف کنید:

import { atom } from "nanostores";

import type { Framework, FrameworkKey } from "./lib/prefs";
import { defaultSelectedFramework, frameworks } from "./lib/prefs";

export const displayedFramework = atom(defaultSelectedFramework);
export const queryParamFramework = atom();
export const availableFrameworks = atom>(frameworks);
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

store.ts

مدیریت آن در اجزای:

import Select from "@/components/Select";
import {
  availableFrameworks,
  displayedFramework,
  queryParamFramework,
} from "@/store";
import { useStore } from "@nanostores/react";
import { useEffect } from "react";

const FrameworkSwitcher = (...) => {
  ...

  const $availableFrameworks = useStore(availableFrameworks);
  const $displayedFramework = useStore(displayedFramework);
  const $queryParamFramework = useStore(queryParamFramework);

  const onChange = (e: ChangeEvent) => {
    ...

    displayedFramework.set(val);
  };

  useEffect(() => {
    ...

    availableFrameworks.set(val);
  }, []);

  return 
								

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا