Codoloper

آموزش برنامه‌نویسی به فارسی

یاد بگیر، پیشرفت کن، بساز.

منبع آموزشی برنامه‌نویسی به زبان فارسی - مستندات، دوره‌ها و مطالب کاربردی برای همه سطوح.

داکیومنت ها:

JavascriptHTMLCSSReact JSبیشتر
1// برنامه‌نویسی به فارسی
2import { learn } from 'codoloper'
3
4const developer = learn({
5"lang": "فارسی"
6"level": "همه سطوح"
7free: true
8})
بلاگ

مطالب جدید

تازه‌ترین مطالب آموزشی و خبرهای مرتبط.

پکیج @cloudflare/ci: موتور CI/CD کلادفلر که برای دوران agent ها ساخته شده نوشته شده توسط عرفان دهقانی

پکیج @cloudflare/ci: موتور CI/CD کلادفلر که برای دوران agent ها ساخته شده

کلادفلر چهارم آگوست، به‌عنوان بخشی از یه اعلامیه‌ی بزرگ‌تر به اسم «Agent Development Lifecycle» (ADLC)، یه ابزار CI/CD جدید و بومی خودشون رو معرفی کرد: @cloudflare/ci. این ابزار رو Cloudflare Workflows و Sandbox می‌سازن، و هدفش اجرای pipeline های CI/CD در مقیاس میلیون‌ها ریپازیتوریه؛ با یه ویژگی خاص که کمتر ابزار CI/CD دیگه‌ای داره: توانایی self-heal کردن و spawn کردن agent برای کارهای پیچیده‌تر.

چرا کلادفلر این ابزار رو ساخته

استدلال کلادفلر پشت این انتشار جالبه. طبق پست رسمی وبلاگشون، مدل قدیمی «چرخه‌ی توسعه‌ی نرم‌افزار» (SDLC) که از دهه‌ی ۱۹۷۰ باهاش کار می‌کنیم، فرض می‌کنه سرعت پیاده‌سازی (implement) کندترین و گرون‌ترین مرحله‌ست. ولی هوش مصنوعی دقیقاً همین مرحله رو ارزون و سریع کرده، و همین باعث شده بقیه‌ی مراحل (تست، دیپلوی، نگهداری) زیر فشار قرار بگیرن؛ چیزی که کلادفلر ازش با عنوان «slop» (سیل کد بی‌کیفیت) یاد می‌کنه.

راه‌حل پیشنهادی کلادفلر اینه که به‌جای این‌که فقط agent ها رو برای نوشتن کد به کار بگیریم و بقیه‌ی مراحل رو همچنان دستی نگه داریم، باید کل چرخه رو برای اجرا توسط agent بازطراحی کنیم؛ چیزی که بهش می‌گن ADLC (Agent Development Lifecycle). @cloudflare/ci اولین قطعه‌ی این پازله.

چطور کار می‌کنه

@cloudflare/ci رو Cloudflare Workers ساخته شده و pipeline های CI/CD رو به‌صورت یه Workflow تعریف می‌کنه، نه یه فایل YAML خطی. این یعنی pipeline می‌تونه به‌صورت پویا (dynamic) تعریف بشه، مراحل رو موازی اجرا کنه، و حتی خودش agent یا Workflow دیگه‌ای رو spawn کنه:

import { CIWorkflow } from '@cloudflare/ci'

const deps = await ci.runner({
  name: 'install',
  command: 'bun install --frozen-lockfile',
  cache: { inputs: ['package.json', 'bun.lock'] },
});

await Promise.all([
  deps.runner({ name: 'lint', command: 'bun run lint' }),
  deps.runner({ name: 'test', command: 'bun run test' }),
  deps.runner({ name: 'typecheck', command: 'bun run typecheck' }),
  deps.runner({ name: 'build', command: 'bun run build' }),
]);

await deps.runner({
  name: 'deploy',
  command: 'bun wrangler deploy',
  cloudflareCredentials: {
    accountId: this.env.CLOUDFLARE_DEPLOY_ACCOUNT_ID,
  },
});

چون این پکیج مستقیم رو Cloudflare Workers اجرا می‌شه، نکته‌ی فنی مهمی داره: @cloudflare/ci یه پکیج معمولی Node.js نیست و مستقیم قابل اجرا نیست؛ باید با یه bundler آگاه به Workers (مثل Wrangler) استفاده بشه، و اگه از @cloudflare/ci/worker استفاده می‌کنی، باید فلگ سازگاری nodejs_compat رو فعال کنی.

بخشی از یه اکوسیستم بزرگ‌تر

@cloudflare/ci به‌تنهایی منتشر نشده؛ بخشی از یه دسته کامل از ابزارهای جدیده که کلادفلر هم‌زمان معرفی کرده تا کل چرخه‌ی SDLC (برنامه‌ریزی، طراحی، پیاده‌سازی، تست، دیپلوی، نگهداری، بازنشستگی) رو برای agent ها قابل مدیریت کنه:

  • OpenTelemetry traces تو dev محلی؛ که یعنی agent همون سطح observability که تو production داره رو موقع توسعه‌ی محلی هم داره؛ مستقیم تو Wrangler و Vite plugin کلادفلر.
  • Cloudflare Agents و Agent Traces؛ یه فضای جدید برای مشاهده، نگهداری، و بهبود agent ها، بر پایه‌ی trace های OpenTelemetry.
  • تجربه‌ی داخلی کلادفلر از اجرای استانداردهای مهندسی با هوش مصنوعی رو تمام ریپازیتوری‌ها و specification هاشون.
  • تجربه‌ی ساخت یه «کارخانه‌ی نرم‌افزار» که تعداد issue های باز پروژه‌ی Astro رو به صفر رسونده؛ یه سیستم خودکار برای triage، بازتولید، تأیید، و رفع مشکلات.

نکته‌ی معماری: Workflow به‌جای YAML خطی

استدلال فنی کلادفلر اینه که یه pipeline CI/CD کلاسیک، صرفاً یه مورد خاص از یه Workflow عمومیه؛ ولی خود Workflow می‌تونه خیلی فراتر از این بره. تو مثال دیگه‌ای که تو پست رسمی اومده، یه Workflow می‌تونه یافته‌های روزانه رو جمع کنه، یه agent رو با اون context صدا بزنه، منتظر جوابش بمونه، و بر اساس نتیجه تصمیم بگیره — همه‌چیز تحت کنترل کامل خود Workflow، نه یه اسکریپت خطی که فقط دستورات رو پشت سر هم اجرا می‌کنه.

جدول کامل: کدوم ابزار کلادفلر کدوم مرحله رو پوشش می‌ده

طبق جدولی که خود کلادفلر منتشر کرده، مراحل مختلف SDLC حالا این‌طور روی ابزارهای کلادفلر map می‌شن:

  • برنامه‌ریزی/طراحی/پیاده‌سازی: Vite، Rolldown، و Oxc (زنجیره‌ابزار سریع)، dev محلی که دقیقاً همون runtime production رو شبیه‌سازی می‌کنه، Local Explorer و Local Traces، remote bindings، و Preview URL برای هر pull request.
  • تست: Browser Run (مرورگرهای headless قابل‌برنامه‌ریزی تو کلاود) و پشتیبانی از Vitest مستقیم تو runtime خود Workers.
  • دیپلوی: Flagship (فیچر فلگ خودکار برای هر تغییر) و Gradual Deployments (رول‌اوت تدریجی).
  • نگهداری/بازنشستگی: Workers Logs (برای این‌که agent بتونه لاگ زنده رو دنبال کنه)، Agent Traces، Cloudflare MCP Server، و Analytics Engine.

این برای توسعه‌دهنده‌ها چه معنایی داره

اگه از قبل رو Cloudflare Workers کار می‌کنی، @cloudflare/ci یه راه بومی برای ساختن pipeline هایی می‌ده که فراتر از یه سری دستور خطی هستن؛ می‌تونن خودشون رو self-heal کنن و در صورت نیاز، کارهای پیچیده‌تر رو به یه agent جدا بسپرن. ولی نکته‌ی مهم اینه که این ابزار، مثل خیلی از قابلیت‌های جدید کلادفلر، عمیقاً به اکوسیستم خودشون (Workers، Workflows، Wrangler) وابسته‌ست؛ یعنی اگه رو یه پلتفرم دیگه host می‌کنی، این ابزار برات مستقیماً قابل استفاده نیست.

کلادفلر خودش هم اعتراف می‌کنه که این فقط شروع کاره؛ به قول خودشون «primitive» های لازم الان در دسترسن، ولی کار زیادی برای اتصال کامل این قطعات به هم و یادگیری از تجربه‌ی واقعی هنوز باقی مونده.

NET. 11 Preview 7 منتشر شد: چی جدیده نوشته شده توسط عرفان دهقانی

NET. 11 Preview 7 منتشر شد: چی جدیده

مایکروسافت یازدهم آگوست، هفتمین preview از .NET 11 رو منتشر کرد؛ آخرین ایستگاه‌های preview قبل از نسخه‌ی نهایی که قراره نوامبر ۲۰۲۶ به‌عنوان یه نسخه‌ی Standard Term Support (STS) عرضه بشه. این preview تغییرات قابل‌توجهی تو کتابخونه‌ها، runtime، SDK، سی‌شارپ، ASP.NET Core، MAUI، Entity Framework Core، اف‌شارپ، و Windows Forms داره.

کتابخونه‌ها

چند تا اضافه‌ی جالب تو این بخش هست: پشتیبانی از نوع‌های اعشاری IEEE 754 و یه نوع generic برای اعداد مختلط (Complex<T>)، که برای کارهای علمی و محاسباتی مفیده. علاوه بر این، فشرده‌سازی HTTP request (نه فقط response که قبلاً بود) و کنترل قابل‌تنظیم برای eviction اتصالات HTTP هم اضافه شده. تو حوزه‌ی شبکه، API های جدیدی برای resolve کردن رکوردهای DNS اومده، و تو حوزه‌ی فایل، پشتیبانی از رمز عبور برای فایل‌های ZIP و چند تا API جدید برای ساخت، استخراج، و متادیتای ZIP هم اضافه شده.

Runtime

تمرکز اصلی رو بهبود Runtime Async بوده؛ با بهینه‌سازی‌های جدید تو tiering و tail-await که مستقیم به سرعت اجرای متدهای async کمک می‌کنه. یه نکته‌ی فنی جالب دیگه اینه که CoreCLR روی WebAssembly حالا کل test suite کتابخونه‌ها رو پاس می‌کنه؛ یعنی بلوغ اجرای .NET رو خود Wasm داره جدی‌تر می‌شه. بهبودهایی هم تو JIT، code generation، NativeAOT، و ابزارهای diagnostic اومده.

SDK

اینجا چند تا تغییر عملی برای کار روزمره هست:

  • NativeAOT حالا به‌صورت پیش‌فرض تو دستور dotnet فعاله؛ یه قدم بزرگ به سمت این‌که compile کردن به native code استاندارد بشه، نه یه گزینه‌ی جانبی.
  • MSBuild server به‌صورت پیش‌فرض فعاله؛ که یعنی build های بعدی معمولاً سریع‌تر انجام می‌شن چون از یه پروسه‌ی از قبل بالا استفاده می‌کنن.
  • dotnet test چند تا قابلیت جدید گرفته: فلگ‌های سطح-اجرا مثل --timeout و --maximum-failed-tests، پشتیبانی از پروژه‌های Microsoft.Build.Traversal، بهبود گزارش‌گیری رو Microsoft.Testing.Platform، و پشتیبانی از دستگاه و محیط MAUI.
  • اپ‌های file-based (همون قابلیت جدید اجرای مستقیم فایل‌های .cs بدون پروژه) حالا دستور dotnet reference و رفع چند باگ up-to-date-check رو هم دارن.
  • publish کردن container حالا runtime های native پلتفرم رو ترجیح می‌ده.

سی‌شارپ

از نظر زبانی، چهار تا ویژگی مهم اضافه شده:

  • break و continue با برچسب (labeled)؛ یعنی می‌شه مشخص کرد کدوم حلقه از چند تا حلقه‌ی تودرتو باید break یا continue بشه، بدون نیاز به flag های دستی.
  • الگوهای union (union pattern) حالا هم خود union و هم مقدار داخلیش رو match می‌کنن.
  • بهبود exhaustiveness checking برای type parameter هایی که به یه closed type محدود شدن.
  • تغییراتی تو «Unsafe Evolution»؛ شامل یه حالت سازگاری (compat mode) و رفتار nameof تو کد unsafe.

ASP.NET Core

بخش Blazor بیشترین تغییرات رو گرفته:

  • توقف خودکار circuit های Blazor موقع بی‌فعالیتی؛ که مصرف منابع سرور رو برای سشن‌های رهاشده کاهش می‌ده.
  • یه ویژگی جدید به اسم CacheView برای کش کردن خروجی Blazor SSR.
  • چند تا analyzer جدید برای Blazor که مشکلات رایج رو زودتر گزارش می‌کنن.
  • QuickGrid حالا InitialItemIndex و ScrollToItemAsync رو پشتیبانی می‌کنه؛ یعنی کنترل بهتری رو موقعیت اسکرول و آیتم اولیه‌ی grid داری.
  • ابزار wasm-tools به Emscripten 6 آپدیت شده.

علاوه بر این، Razor حالا attribute های literal رو برای پارامترهای کامپوننت از نوع union قبول می‌کنه، validation localization به‌صورت built-in اضافه شده، کلاینت SignalR .NET حالا بعد از redirect هم می‌تونه auth رو refresh کنه، و OpenAPI پشتیبانی از Server-Sent Events تو نسخه‌ی OpenAPI 3.2 رو گرفته.

.NET MAUI

چند تا قابلیت جدید و کاربردی:

  • احراز هویت با passkey به‌صورت cross-platform؛ یعنی دیگه لازم نیست پیاده‌سازی جدا برای هر پلتفرم بنویسی.
  • XAML Incremental Hot Reload؛ که سرعت دیدن تغییرات UI موقع توسعه رو بهبود می‌ده.
  • الگوهای route جدید برای Shell.
  • binding های RelativeSource که با AOT سازگارن.
  • پشتیبانی از backend های platform-specific شخص ثالث.
  • TabbedPage حالا رو پلتفرم‌های اپل از همون معماری handler استفاده می‌کنه که بقیه‌ی کنترل‌ها استفاده می‌کنن.

Entity Framework Core

بهبودهایی تو ترجمه‌ی کوئری LINQ، بهبود provider مربوط به Azure Cosmos DB، بهبود migration ها، و پشتیبانی از نوع Half رو SQLite اضافه شده.

اف‌شارپ

چهار تا بهبود کوچیک‌تر ولی مفید: binding های computation expression حالا داخل یه let ساده هم کار می‌کنن، attribute ها داخل ماژول‌ها و namespace های recursive درست resolve می‌شن، پیام تشخیصی واضح‌تری برای type abbreviation های generic اضافه شده، و یه باگ مربوط به محاسبه‌ی سایز StructLayout برای union های struct بدون داده رفع شده.

Windows Forms

تمرکز این بخش رو Dark Mode بوده؛ پنج تا pull request مستقیم به بهبود ظاهر تو حالت تاریک اختصاص داشته (شامل ToolTip، HelpProvider، LinkLabel، TabControl تودرتو، و آیکون‌های چک تو ToolStrip). علاوه بر این:

  • یه حالت اختیاری جدید به اسم VisualStylesMode برای شخصی‌سازی بیشتر ظاهر کنترل‌ها.
  • جلوگیری از فلاش سفید موقع باز شدن فرم‌ها تو dark mode، با تأخیر انداختن نمایش فرم تا زمانی که استایل‌ها اعمال بشن.
  • توقف رندر موقع تغییرات دسته‌ای (bulk) رو کنترل‌ها، مثل تغییر هم‌زمان موقعیت و سایز.
  • ظاهر toggle-switch برای CheckBox و RadioButton.
  • رفع چند باگ پایداری، شامل یه کرش GDI+ تو SplitContainer و یه exception تو اسکرول ToolStrip.

این preview تو چه فضایی منتشر شده

نکته‌ی جالب اینه که واکنش جامعه‌ی توسعه‌دهنده‌ها به کل چرخه‌ی .NET 11 (نه فقط این preview) صرفاً مثبت نبوده. بعضی توسعه‌دهنده‌ها نسبت به افزایش پیچیدگی زبان سی‌شارپ و سرعت انتشار نسخه‌های بزرگ ابراز نگرانی کردن. همچنین، نقشه‌ی راه ASP.NET Core تو .NET 11 تمرکز زیادی رو «Agentic AI» گذاشته (از جمله پشتیبانی از Model Context Protocol تا اپلیکیشن‌های .NET بتونن به‌عنوان ابزار برای agent های هوش مصنوعی عمل کنن)؛ جهتی که بعضی توسعه‌دهنده‌ها معتقدن داره روی نیازهای اصلی و پایه‌ای framework سایه می‌ندازه.

چطور امتحانش کنیم

برای شروع، کافیه SDK نسخه‌ی .NET 11 رو نصب کنی. اگه رو ویندوز با Visual Studio کار می‌کنی، مایکروسافت توصیه می‌کنه از آخرین نسخه‌ی Visual Studio 2026 Insiders استفاده کنی؛ از Visual Studio Code هم با extension مربوط به C# Dev Kit می‌شه استفاده کرد. یادت باشه این هنوز preview است، نه نسخه‌ی نهایی، پس برای production حتماً صبر کن تا نسخه‌ی پایدار نوامبر منتشر بشه؛ ولی برای آشنایی زودهنگام با تغییرات و کاهش ریسک آپدیت آینده، امتحانش کردنش الان ارزش داره.

اومنی‌روت (OmniRoute): گیت‌وی متن‌باز برای ۳۳۹ مدل زبانی نوشته شده توسط عرفان دهقانی

اومنی‌روت (OmniRoute): گیت‌وی متن‌باز برای ۳۳۹ مدل زبانی

اگه از چند تا ابزار agentic (Claude Code، Cursor، Codex، Cline) هم‌زمان استفاده می‌کنی و خسته شدی از این‌که هر کدوم rate limit جدا داره، یا هر وقت quota یکی تموم می‌شه مجبوری دستی سوییچ کنی، OmniRoute دقیقاً برای همین مشکل ساخته شده. این یه AI gateway متن‌باز و local-first است که همه‌ی provider های مختلف (اوپن‌ای‌آی، آنتروپیک، گوگل، دیپ‌سیک و خیلی‌های دیگه) رو پشت یه endpoint واحد و سازگار با API اوپن‌ای‌آی جمع می‌کنه.

چیه دقیقاً و چطور کار می‌کنه

به‌جای این‌که هر ابزار کدنویسیت رو جدا به هر provider وصل کنی، فقط یه بار base URL ابزارت (مثلاً Claude Code یا Cursor) رو به یه آدرس local (پیش‌فرض localhost:20128/v1) اشاره می‌دی. OmniRoute پشت این آدرس، درخواست رو می‌گیره، بر اساس قوانین routing که خودت تعریف کردی (یا حالت auto) تصمیم می‌گیره کدوم provider جواب بده، و پاسخ رو به فرمتی که ابزارت انتظار داره (چه فرمت OpenAI، چه Claude، چه Gemini) برمی‌گردونه.

نصبش هم ساده‌ست:

npm install -g omniroute
omniroute

بعد از اجرا، هم API و هم یه داشبورد وب رو همون پورت ۲۰۱۲۸ بالا میان.

عدد و رقم‌های پروژه

طبق آمار رسمی خود پروژه، OmniRoute از ۱۳ فوریه‌ی ۲۰۲۶ (کمتر از چهار ماه پیش) شروع به کار کرده و در همین مدت کوتاه به بیش از ۲۰ هزار ستاره‌ی گیت‌هاب، حدود ۲۸۰۰ فورک، و مشارکت بیش از ۳۵۰ توسعه‌دهنده رسیده؛ با ۲۷۱ نسخه‌ی منتشرشده و بیش از ۴۰۰۰ pull request مرج‌شده. کل پروژه زیر لایسنس MIT هست، یعنی کاملاً متن‌باز و بدون محدودیت استفاده‌ی تجاری.

قابلیت‌های اصلی

Auto-fallback چندلایه: اگه یه provider به rate limit بخوره یا quota ش تموم بشه، OmniRoute تو چند میلی‌ثانیه، بدون این‌که کارت متوقف بشه، به provider بعدی سوییچ می‌کنه. این fallback سه‌لایه‌ست (سطح provider، سطح connection/کلید، سطح مدل)، یعنی یه کلید API خراب کل provider رو از کار نمی‌ندازه.

۱۷ استراتژی routing: از «اول رایگان‌ها رو مصرف کن» گرفته تا «همیشه ارزون‌ترین گزینه» یا «بار رو بین چند کلید پخش کن»، می‌شه دقیقاً مشخص کرد اولویت routing بر چه اساسی باشه.

فشرده‌سازی توکن: با ترکیب چند تا موتور فشرده‌سازی (که خودشون بهش می‌گن RTK و Caveman)، خروجی ابزارها و context تکراری رو قبل از رسیدن به مدل فشرده می‌کنه؛ طبق ادعای پروژه، بین ۱۵ تا ۹۵ درصد صرفه‌جویی تو مصرف توکن، بسته به نوع کار.

استفاده از quota رایگان: پروژه ادعا می‌کنه بیش از ۹۰ provider با پلن رایگان رو ردیابی می‌کنه و مصرف رایگان رو به‌صورت pool-deduped (بدون شمارش تکراری) جمع می‌زنه؛ رقمی که خودشون حدود ۱.۵ میلیارد توکن رایگان در ماه اعلام می‌کنن.

پشتیبانی از MCP و A2A: خود gateway به‌عنوان یه سرور MCP هم عمل می‌کنه (بیش از ۱۰۰ ابزار در قالب چند ده scope)، و از پروتکل A2A هم پشتیبانی می‌کنه؛ یعنی یه agent می‌تونه مستقیم خود OmniRoute رو به‌عنوان یه ابزار کنترل کنه، نه فقط ازش عبور کنه.

نکته‌ی مهم قبل از استفاده‌ی جدی

قبل از این‌که این ابزار رو رو یه workflow حساس یا production تکیه بدی، چند تا نکته رو باید در نظر بگیری. اول، مسیر کردن ترافیک از طریق gateway خودت، پردازش، شرایط استفاده، یا نگه‌داری داده‌ی provider اصلی رو حذف نمی‌کنه؛ داده‌ت هنوز به همون provider (مثلاً OpenAI یا آنتروپیک) می‌رسه، فقط از یه لایه‌ی اضافه عبور کرده. دوم، این ابزار خودش یه نقطه‌ی حیاتی تو مسیر درخواست‌هات می‌شه؛ اگه down بشه، تنظیماتش خراب بشه، یا دیتابیس local ش (SQLite) کرش کنه، همه‌ی ابزارهایی که ازش عبور می‌کنن تحت تأثیر قرار می‌گیرن. برای همین، برای استفاده‌ی جدی، حتماً باید persistence، بک‌آپ، و کنترل دسترسی مناسب رو خودت تنظیم کنی.

یه نکته‌ی دیگه هم اینه که چون این پروژه خیلی تازه و به‌شدت پرتغییره (۲۷۱ نسخه تو کمتر از چهار ماه)، بهتره قبل از هر آپدیت، یه نسخه‌ی مشخص رو pin کنی و رفتار ابزارهای کدنویسیت رو (streaming، tool call، context طولانی) بعد از هر آپدیت جدا تست کنی، نه این‌که فقط بر اساس لیست مدل‌ها قضاوت کنی که همه‌چیز درست کار می‌کنه.

جمع‌بندی

اگه خسته شدی از مدیریت دستی چند تا کلید API و برخورد مکرر با rate limit وسط کار، OmniRoute یه راه‌حل عملی و رایگانه که با یه دستور نصب می‌شه و تقریباً با هر ابزار agentic معروفی (Claude Code، Cursor، Codex، Cline، Copilot) سازگاره. ولی برای پروژه‌های production یا تیمی، بهتره اول یه دوره‌ی ارزیابی جدی (تست کیفیت پاسخ، latency، failover واقعی) قبل از تکیه‌ی کامل روش انجام بدی؛ چون production-ready بودن این ابزار، بیشتر به تنظیمات و تست‌های خودت بستگی داره تا صرفاً نصب و راه‌اندازیش.

وب اسمبلی (WebAssembly) چیه و چرا این‌قدر سروصدا کرده نوشته شده توسط عرفان دهقانی

وب اسمبلی (WebAssembly) چیه و چرا این‌قدر سروصدا کرده

اگه اسم WebAssembly (یا به اختصار Wasm) رو شنیدی و کنجکاو شدی دقیقاً چیه، جواب کوتاهش اینه: یه فرمت باینری برای اجرای کد با سرعت نزدیک به native، مستقیم تو مرورگر (و جاهای دیگه). ولی این جواب کوتاه نمی‌گه چرا این تکنولوژی این‌قدر مهمه. برای فهمیدنش بهتره از مشکلی شروع کنیم که Wasm حلش می‌کنه.

مشکلی که جاوااسکریپت نمی‌تونست حلش کنه

جاوااسکریپت تنها زبونیه که مرورگرها به‌صورت native اجرا می‌کنن. برای دهه‌ها، اگه می‌خواستی چیزی تو مرورگر اجرا بشه، مجبور بودی یا مستقیم جاوااسکریپت بنویسی، یا زبون دیگه‌ت رو به جاوااسکریپت compile کنی (مثل TypeScript). مشکل اینجاست که جاوااسکریپت یه زبون dynamically-typed و interpreted هست؛ حتی با موتورهای JIT فوق‌پیشرفته‌ای مثل V8، برای کارهای سنگین محاسباتی (پردازش تصویر، فیزیک بازی، رمزنگاری، پردازش صوت و ویدیو) هنوز به سقف عملکرد زبون‌های کامپایل‌شده مثل C++ یا Rust نمی‌رسه.

WebAssembly این محدودیت رو برمی‌داره. به‌جای این‌که مجبور باشی کد C++ یا Rust ت رو به جاوااسکریپت ترجمه کنی (که هم کند و هم ناقصه)، می‌تونی مستقیم به یه فرمت باینری فشرده و بهینه compile‌ش کنی که مرورگر می‌تونه تقریباً به همون سرعت کد native اجراش کنه.

چند تا ویژگی کلیدی

فرمت باینری، نه متنی: برخلاف جاوااسکریپت که یه متن قابل‌خوندنه، Wasm یه فرمت باینری فشرده‌ست. این یعنی هم فایلش کوچیک‌تره (دانلود سریع‌تر)، هم parse کردنش برای مرورگر سریع‌تره؛ چون نیازی به تحلیل سینتکس متنی نیست.

Sandboxed و امن: کد Wasm دقیقاً مثل جاوااسکریپت، تو یه محیط ایزوله (sandbox) اجرا می‌شه. نمی‌تونه مستقیم به فایل‌سیستم یا شبکه دسترسی پیدا کنه، مگه از طریق API هایی که خود جاوااسکریپت در اختیارش می‌ذاره. یعنی امنیتش مستقل از این‌که کد اصلی با چه زبونی نوشته شده، حفظ می‌شه.

مستقل از زبان مبدأ: Wasm خودش یه زبون برنامه‌نویسی نیست که مستقیم باهاش کد بنویسی (هرچند می‌شه). بیشتر یه target compilation است؛ یعنی زبون‌هایی مثل C، C++، Rust، Go، و حتی بخش‌هایی از پایتون می‌تونن بهش compile بشن.

نزدیک به سرعت native: چون فرمتش از قبل به یه ساختار شبیه assembly نزدیکه (برای همین اسمش Wasm است)، مرورگر نیازی به تفسیر خط‌به‌خط نداره و می‌تونه خیلی سریع‌تر از جاوااسکریپت معمولی اجراش کنه.

یه مثال ساده

فرض کن یه تابع محاسباتی سنگین به Rust داری:

#[no_mangle]
pub fn fibonacci(n: u32) -> u64 {
    if n <= 1 {
        return n as u64;
    }
    let mut a = 0u64;
    let mut b = 1u64;
    for _ in 2..=n {
        let temp = a + b;
        a = b;
        b = temp;
    }
    b
}

با ابزاری مثل wasm-pack، این کد به یه فایل .wasm compile می‌شه که می‌شه مستقیم تو جاوااسکریپت import و صداش زد:

import init, { fibonacci } from './pkg/my_wasm_module.js';

async function run() {
    await init();
    console.log(fibonacci(50)); // اجرا با سرعت نزدیک به native
}

run();

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

کجاها واقعاً استفاده می‌شه

ابزارهای سنگین که به مرورگر آوردن: Figma بخش زیادی از موتور رندرش رو با WebAssembly پیاده کرده تا بتونه performance شبیه یه اپلیکیشن دسکتاپ رو تو مرورگر ارائه بده. AutoCAD نسخه‌ی وب خودش رو با پورت کردن دهه‌ها کد C++ به Wasm ساخته.

بازی‌ها و موتورهای گرافیکی: موتورهایی مثل Unity و Unreal Engine امکان export کردن بازی به WebAssembly رو دارن، که یعنی بازی‌های نسبتاً سنگین می‌تونن مستقیم تو مرورگر، بدون نصب هیچ پلاگینی، اجرا بشن.

پردازش تصویر و ویدیو: ابزارهایی مثل ffmpeg.wasm امکان encode/decode کردن ویدیو مستقیم تو مرورگر رو می‌دن، بدون این‌که فایل به سرور آپلود بشه؛ هم سریع‌تره، هم حریم خصوصی کاربر حفظ می‌شه.

اجرای زبون‌های دیگه تو مرورگر: پروژه‌هایی مثل Pyodide، پایتون رو کامل به WebAssembly compile کردن، یعنی می‌تونی کد پایتون واقعی رو مستقیم تو مرورگر، بدون سرور، اجرا کنی.

فراتر از مرورگر: WebAssembly دیگه محدود به مرورگر نیست. با استانداردی به اسم WASI (WebAssembly System Interface)، می‌شه Wasm رو مستقل از مرورگر، رو سرور یا edge computing هم اجرا کرد. کلادفلر Workers و Fastly Compute دقیقاً از همین قابلیت استفاده می‌کنن تا کد رو تو صدها دیتاسنتر مختلف، با startup time خیلی کمتر از یه کانتینر معمولی، اجرا کنن.

چیزی که WebAssembly نیست

یه سوءتفاهم رایج اینه که فکر کنیم Wasm قراره جای جاوااسکریپت رو بگیره. این‌طور نیست؛ Wasm نمی‌تونه مستقیم به DOM دسترسی داشته باشه یا event handler ثبت کنه. برای هر تعامل با صفحه (کلیک، تغییر استایل، دستکاری DOM)، هنوز باید از جاوااسکریپت به‌عنوان واسط استفاده کنی. Wasm بیشتر مکمل جاوااسکریپته تا جایگزینش؛ جاهایی که محاسبات سنگین لازمه، کار رو به Wasm می‌سپاری و بقیه‌ی تعامل با کاربر همچنان با جاوااسکریپت انجام می‌شه.

کِی واقعاً بهش نیاز داری

اگه داری یه اپلیکیشن وب معمولی می‌سازی (فرم، داشبورد، فروشگاه آنلاین)، به احتمال زیاد هیچ‌وقت مستقیم با WebAssembly سروکار پیدا نمی‌کنی؛ جاوااسکریپت (یا فریمورک‌های روش) کاملاً کافیه. Wasm زمانی وارد بازی می‌شه که یه بخش خاص از اپلیکیشنت واقعاً محاسبات سنگین داره (پردازش تصویر/صوت/ویدیو، رمزنگاری، فیزیک، parsing فایل‌های حجیم) و همون بخش داره performance اپ رو محسوس کند می‌کنه. تو اون حالت، می‌تونی فقط همون بخش خاص رو به Rust یا C++ بنویسی و به Wasm compile کنی، بدون این‌که مجبور بشی کل اپلیکیشن رو از جاوااسکریپت خارج کنی.