افزونه C# Dev Kit بدون نیاز به Python!
خلاصهٔ کاملتر
تیم C# Dev Kit که یه افزونه VS Code برای توسعهدهندههای داتنت هست، با یه مشکل جالب دست و پنجه نرم میکرد: فرانتاند این افزونه با TypeScript و Node.js نوشته شده، اما برای بعضی کارهای پلتفرممحور مثل خوندن Windows Registry، مجبور بودن از افزونههای native نوشتهشده با C++ استفاده کنن.
این افزونههای native با ابزار node-gyp کامپایل میشن و node-gyp هم برای کار کردن، به یه نسخه قدیمی Python نیاز داره. یعنی هر توسعهدهندهای که میخواست روی پروژه کار کنه، باید Python نصب میکرد — ابزاری که هیچوقت مستقیماً باهاش کار نمیکرد. بهعلاوه، CI/CD پایپلاینها هم باید این وابستگی رو مدیریت میکردن که سرعت بیلدها رو پایین میآورد.
راهحل تیم خیلی هوشمندانهست: چون اصلاً C# Dev Kit یه پروژه داتنته و SDK مربوطه همیشه روی ماشینها نصبه، چرا از همون C# و Native AOT استفاده نکنن؟ Native AOT میتونه shared library بسازه (مثل .dll در ویندوز یا .so در لینوکس) که دقیقاً همون چیزیه که Node.js برای افزونههای native نیاز داره.
ماجرا اینه که Node.js برای بارگذاری یه افزونه native، فقط لازمه که اون کتابخونه یه entry point مشخص به اسم napi_register_module_v1 رو export کنه. این رابط که N-API نام داره، یه C API پایدار و ABI-سازگار هست و اصلاً براش مهم نیست که کتابخونه با چه زبانی نوشته شده — فقط باید سیمبلهای درستی رو export کنه.
در داتنت، با استفاده از ویژگی [UnmanagedCallersOnly] میشه یه متد C# رو با یه entry point دلخواه به native code export کرد. این یعنی میشه مستقیماً همون تابعی که Node.js انتظار داره رو از C# بیرون داد. بقیه توابع هم از طریق N-API ثبت میشن تا از JavaScript قابل فراخوانی باشن.
ارتباط با توابع N-API هم از طریق P/Invoke مدیریت میشه. چون توابع N-API داخل خود node.exe هستن، با یه resolver سفارشی، داتنت رو هدایت میکنن تا این توابع رو از همون پروسه اصلی پیدا کنه — بدون نیاز به لینک کردن به یه کتابخونه جداگانه. انتقال دادهها (مثل رشتهها) بین JavaScript و داتنت هم با استفاده از Span، stackalloc و ArrayPool بهینهسازی شده تا کمترین میزان تخصیص حافظه روی heap اتفاق بیفته.
نتیجه نهایی یه افزونه native هست که با C# و Native AOT نوشته شده، بدون هیچ نیازی به Python یا node-gyp کامپایل میشه و دقیقاً مثل هر افزونه C++ دیگهای در Node.js کار میکنه. برای تیمهایی که از داتنت استفاده میکنن، این رویکرد هم ابزارها رو یکپارچهتر میکنه و هم پیچیدگیهای غیرضروری رو از بین میبره.
نکات کلیدی:
- تیم C# Dev Kit با Native AOT، وابستگی به Python و node-gyp رو حذف کرد
- Node.js از طریق N-API فقط نیاز به export یه entry point مشخص داره — مهم نیست زبان چیه
- در C#، ویژگی [UnmanagedCallersOnly] اجازه میده متدها رو مستقیماً به native code export کرد
- توابع N-API از طریق P/Invoke و یک resolver سفارشی از پروسه اصلی Node.js فراخوانی میشن
- مدیریت رشتهها با Span و ArrayPool بهینه شده تا از تخصیص حافظه اضافه جلوگیری بشه
- این روش برای هر تیم داتنتی که نیاز به افزونه native در Node.js داره، قابل استفادهست




