~13 دقیقه مطالعه • بروزرسانی ۵ دی ۱۴۰۴
1. ویژگیهای Node-API
- تمام فراخوانیهای Node-API یک وضعیت از نوع
napi_statusبازمیگردانند. - مقادیر جاوااسکریپت پشت نوع انتزاعی
napi_valueپنهان میشوند. - در صورت خطا، اطلاعات بیشتر با
napi_get_last_error_infoقابل دسترسی است.
2. نوشتن Addonها با زبانهای مختلف
Node-API یک API مبتنی بر C است که پایداری ABI را تضمین میکند. بنابراین میتوان Addonها را با زبانهای دیگر نیز نوشت. کتابخانهٔ node-addon-api یک wrapper رسمی C++ است که کدنویسی را سادهتر میکند.
// node-addon-api Object obj = Object::New(env); obj["foo"] = String::New(env, "bar");
3. پایداری ABI
برای حفظ سازگاری ABI، Addon باید فقط از #include <node_api.h> استفاده کند. APIهای دیگر مانند V8 یا libuv چنین تضمینی ندارند.
4. Enumها در Node-API
تمام enumها بهصورت int32_t در نظر گرفته میشوند. مقادیر جدید میتوانند بدون حذف یا تغییر اضافه شوند، بنابراین کد باید همیشه حالت پیشفرض را در switchها مدیریت کند.
5. ابزارهای ساخت (Build Tools)
- node-gyp: ابزار سنتی مبتنی بر GYP که با npm همراه است.
- CMake.js: جایگزین مبتنی بر CMake برای پروژههایی که از CMake استفاده میکنند.
6. بارگذاری باینریهای از پیش کامپایلشده
- node-pre-gyp: بارگذاری روی سرورهای مختلف، مخصوصاً Amazon S3.
- prebuild: بارگذاری روی GitHub Releases.
- prebuildify: باینریها را همراه با ماژول در npm منتشر میکند.
7. نسخههای Node-API
از نسخهٔ ۹ به بعد، Node-API بهصورت افزایشی نسخهگذاری میشود. نسخهٔ پیشفرض ۸ است مگر اینکه #define NAPI_VERSION مشخص شود.
| Node-API Version | Supported In |
|---|---|
| 10 | v22.14.0+, v23.6.0+ |
| 9 | v18.17.0+, v20.3.0+, v21.0.0+ |
| 8 | v12.22.0+, v14.17.0+, v15.12.0+, v16.0.0+ |
| 7 | v10.23.0+, v12.19.0+, v14.12.0+, v15.0.0+ |
8. جداسازی کد Node.js-specific
میتوان بخشهای خاص Node.js را از کد اصلی جدا کرد تا Addon بتواند با پیادهسازیهای دیگر Node-API نیز کامپایل شود.
// addon.h #includenapi_value create_addon(napi_env env);
نتیجهگیری
Node-API یک لایهٔ پایدار و مستقل برای توسعهٔ Addonهای بومی در Node.js فراهم میکند. با استفاده از آن، توسعهدهندگان میتوانند ماژولهایی بسازند که در نسخههای مختلف Node.js بدون نیاز به کامپایل مجدد کار کنند. این ویژگی، توسعهٔ بلندمدت و پایدار Addonها را تضمین میکند.
1. مدیریت دادههای محیط
napi_set_instance_data: دادهای را به محیط جاری متصل میکند و چرخهٔ عمر آن را با محیط هماهنگ میسازد.napi_get_instance_data: دادهٔ متصلشده به محیط را بازیابی میکند.
// نمونه napi_set_instance_data(env, data, finalize_cb, NULL); napi_get_instance_data(env, &retrievedData);
2. انواع دادههای پایه در Node-API
napi_status: وضعیت موفقیت یا شکست فراخوانی API.napi_extended_error_info: اطلاعات خطای توسعهیافته شامل پیام و کد خطا.napi_env: نمایندهٔ محیط Node.js برای مدیریت وضعیت VM.napi_value: اشارهگر انتزاعی برای نمایش مقادیر جاوااسکریپت.
3. مدیریت Thread-safe Function
napi_threadsafe_function امکان فراخوانی امن توابع جاوااسکریپت از چندین Thread را فراهم میکند.
napi_tsfn_releaseوnapi_tsfn_abort: حالتهای آزادسازی یا بستن تابع.napi_tsfn_nonblockingوnapi_tsfn_blocking: حالتهای فراخوانی با یا بدون بلاک شدن.
4. مدیریت چرخهٔ عمر اشیاء
napi_handle_scope: کنترل محدودهٔ عمر اشیاء ایجادشده.napi_escapable_handle_scope: امکان بازگرداندن مقادیر به محدودهٔ والد.napi_ref: مدیریت ارجاعها و طول عمر مقادیر جاوااسکریپت.napi_type_tag: برچسبگذاری اشیاء برای اطمینان از نوع صحیح.
5. Hookهای پاکسازی
napi_async_cleanup_hook_handle برای مدیریت رویدادهای پاکسازی ناهمزمان استفاده میشود و باید با napi_remove_async_cleanup_hook آزاد شود.
6. Callbackها
napi_callback_info: اطلاعات زمینهای هنگام فراخوانی تابع.napi_callback: امضای استاندارد توابع بومی که به جاوااسکریپت صادر میشوند.
typedef napi_value (*napi_callback)(napi_env, napi_callback_info);
نتیجهگیری
Environment Life Cycle APIs در Node.js امکان مدیریت ایمن دادهها، اشیاء و توابع را در محیطهای مختلف فراهم میکنند. این ابزارها برای توسعهٔ Addonهای بومی که نیاز به تعامل با چندین محیط و Thread دارند حیاتیاند و تضمین میکنند که چرخهٔ عمر دادهها و اشیاء بهدرستی کنترل شود.
1. Finalizers در Node-API
node_api_basic_finalize: تابعی که هنگام جمعآوری اشیاء با دادههای خارجی فراخوانی میشود. تنها APIهایی کهnode_api_basic_envمیپذیرند در اینجا مجازند.napi_finalize: برای زمانبندی فراخوانیهای Node-API پس از پایان چرخهٔ GC استفاده میشود.
2. Callbackهای ناهمزمان
napi_async_execute_callback: برای اجرای عملیات ناهمزمان بدون تعامل مستقیم با جاوااسکریپت.napi_async_complete_callback: برای تکمیل عملیات ناهمزمان و تعامل با جاوااسکریپت.napi_threadsafe_function_call_js: برای فراخوانی امن توابع جاوااسکریپت از Threadهای ثانویه.
3. Hookهای پاکسازی
napi_cleanup_hook: هنگام نابودی محیط فراخوانی میشود.napi_async_cleanup_hook: برای پاکسازی ناهمزمان هنگام نابودی محیط استفاده میشود.
1. ایجاد خطاها در Node-API
napi_create_range_error: ایجاد یکRangeErrorبا پیام مشخص.node_api_create_syntax_error: ایجاد یکSyntaxErrorبا پیام مشخص.
// نمونه napi_value error; napi_create_range_error(env, NULL, msg, &error);
2. مدیریت استثناها
napi_get_and_clear_last_exception: دریافت و پاکسازی آخرین استثناء.napi_is_exception_pending: بررسی وجود استثناء در حال انتظار.napi_fatal_exception: پرتاب استثناء غیرقابل بازیابی.napi_fatal_error: خاتمهٔ فوری فرآیند در صورت خطای بحرانی.
3. مدیریت چرخهٔ عمر اشیاء
هندلها در Node-API به اشیاء جاوااسکریپت اشاره میکنند و باید طول عمرشان بهدرستی مدیریت شود.
napi_open_handle_scope/napi_close_handle_scope: باز و بسته کردن محدودهٔ عمر هندلها.napi_open_escapable_handle_scope: ایجاد محدودهای که اجازهٔ ارتقاء یک هندل به محدودهٔ والد را میدهد.napi_escape_handle: ارتقاء یک هندل به محدودهٔ والد.
4. ارجاعات پایدار (Persistent References)
napi_create_reference: ایجاد ارجاع پایدار با شمارندهٔ اولیه.napi_delete_reference: حذف ارجاع و آزادسازی حافظه.napi_reference_ref: افزایش شمارندهٔ ارجاع.
ارجاعات پایدار برای نگهداشتن اشیاء زنده در طول عمر طولانیتر از یک فراخوانی بومی استفاده میشوند. مدیریت صحیح آنها از نشت حافظه جلوگیری میکند.
نتیجهگیری
با استفاده از napi_create_range_error و سایر توابع مدیریت خطا، توسعهدهندگان میتوانند خطاهای جاوااسکریپت را بهطور ایمن در Addonهای بومی ایجاد کنند. همچنین ابزارهای مدیریت چرخهٔ عمر اشیاء و ارجاعات پایدار تضمین میکنند که حافظه بهدرستی مدیریت شود و از نشت منابع جلوگیری گردد.
1. مدیریت ارجاعات
napi_reference_unref: شمارندهٔ ارجاع یکnapi_refرا کاهش داده و مقدار جدید را بازمیگرداند.napi_get_reference_value: مقدار جاوااسکریپت مرتبط با یکnapi_refرا بازمیگرداند، یا در صورت نامعتبر بودنNULL.
2. Cleanup Hooks
برای آزادسازی منابع هنگام خروج از محیط Node.js، میتوان از Hookها استفاده کرد:
napi_add_env_cleanup_hook: ثبت تابعی برای پاکسازی هنگام خروج محیط.napi_remove_env_cleanup_hook: حذف Hook ثبتشده.napi_add_async_cleanup_hook: ثبت Hook ناهمزمان برای پاکسازی.napi_remove_async_cleanup_hook: حذف Hook ناهمزمان.
3. Finalization هنگام خروج محیط
هنگام نابودی محیط، تمام napi_finalizeهای ثبتشده برای اشیاء و دادهها فراخوانی میشوند. برای جلوگیری از use-after-free، توصیه میشود منابع ابتدا با Cleanup Hooks آزاد شوند.
4. ثبت ماژولها
ماژولهای Node-API با ماکروهای زیر ثبت میشوند:
NAPI_MODULE: ثبت تابع Init بهعنوان نقطهٔ ورود.NAPI_MODULE_INIT: میانبری برای تعریف Init.
// نمونه Init
napi_value Init(napi_env env, napi_value exports) {
napi_value answer;
napi_create_int64(env, 42, &answer);
napi_set_named_property(env, exports, "answer", answer);
return exports;
}
5. کار با مقادیر جاوااسکریپت
Node-API مجموعهای از توابع برای ایجاد انواع مقادیر جاوااسکریپت فراهم میکند:
napi_create_array: ایجاد آرایه.napi_create_buffer: ایجاد Buffer.napi_create_date: ایجاد شیء Date.
نتیجهگیری
با استفاده از napi_reference_unref و Cleanup Hooks، توسعهدهندگان میتوانند منابع را بهطور ایمن مدیریت کرده و از نشت حافظه جلوگیری کنند. این ابزارها همراه با APIهای ایجاد اشیاء، چارچوبی قدرتمند برای توسعهٔ Addonهای پایدار در Node.js فراهم میکنند.
1. External Values
napi_create_external: ایجاد یک مقدار جاوااسکریپت با دادهٔ خارجی متصل. این مقدار نوعیnapi_externalاست و ویژگیهای اضافی ندارد.napi_create_external_arraybuffer: ایجاد یکArrayBufferبا دادهٔ خارجی مدیریتشده.napi_create_external_buffer: ایجاد یکBufferبا دادهٔ خارجی.
در همهٔ این موارد، یک finalize_cb اختیاری میتواند ثبت شود تا هنگام جمعآوری زباله، دادهٔ خارجی آزاد گردد.
2. Object Creation
napi_create_object: ایجاد یک شیء جاوااسکریپت پیشفرض (معادلnew Object()).napi_create_object_with_properties: ایجاد شیء با prototype و ویژگیهای مشخص، بهصورت اتمیک و کارآمد.
3. Symbols
napi_create_symbol: ایجاد یک Symbol با توضیح اختیاری.node_api_symbol_for: جستجو یا ایجاد Symbol در رجیستری جهانی.
4. Typed Arrays و DataView
napi_create_typedarray: ایجاد TypedArray روی یک ArrayBuffer موجود.napi_create_dataview: ایجاد DataView برای دسترسی انعطافپذیر به دادههای باینری.
5. Buffer از ArrayBuffer
node_api_create_buffer_from_arraybuffer امکان ایجاد یک Buffer جاوااسکریپت از روی ArrayBuffer موجود را فراهم میکند.
6. تبدیل انواع C به جاوااسکریپت
napi_create_int32: تبدیلint32_tبه عدد جاوااسکریپت.napi_create_uint32: تبدیلuint32_tبه عدد جاوااسکریپت.napi_create_int64: تبدیلint64_tبه عدد جاوااسکریپت (با محدودیت دقت).napi_create_double: تبدیلdoubleبه عدد جاوااسکریپت.
نتیجهگیری
APIهای ساخت اشیاء در Node-API ابزارهای قدرتمندی برای تعامل مستقیم بین دادههای بومی و جاوااسکریپت فراهم میکنند. با استفاده از napi_create_external و سایر توابع مرتبط، توسعهدهندگان میتوانند دادههای خارجی را بهطور ایمن در محیط جاوااسکریپت مدیریت کرده و Addonهایی پایدار و کارآمد بسازند.
4. مدیریت خطا با Node-API
تمام توابع Node-API مقدار بازگشتی از نوع napi_status دارند:
napi_ok: موفقیت.napi_pending_exception: استثنای جاوااسکریپت در حال انتظار.- سایر مقادیر نشاندهندهٔ خطاهای مختلف هستند.
برای جزئیات بیشتر از napi_get_last_error_info استفاده میشود که ساختار napi_extended_error_info را بازمیگرداند.
5. مدیریت استثناها
napi_throw: پرتاب یک مقدار جاوااسکریپت بهعنوان استثناء.napi_throw_error: ایجاد و پرتاب یکErrorبا پیام مشخص.napi_throw_type_error: پرتابTypeError.napi_throw_range_error: پرتابRangeError.node_api_throw_syntax_error: پرتابSyntaxError.
همچنین توابعی مانند napi_create_error و napi_create_type_error برای ایجاد اشیاء خطا وجود دارند.
نتیجهگیری
Finalizers و Error Handling در Node-API ابزارهای حیاتی برای مدیریت چرخهٔ عمر دادهها و اشیاء در Addonهای بومی هستند. با استفادهٔ صحیح از این APIها، توسعهدهندگان میتوانند کدهایی پایدار، ایمن و سازگار با نسخههای مختلف Node.js بنویسند.
1. BigInt Creation
napi_create_bigint_int64: تبدیلint64_tبه BigInt جاوااسکریپت.napi_create_bigint_uint64: تبدیلuint64_tبه BigInt جاوااسکریپت.napi_create_bigint_words: ایجاد BigInt از آرایهای از کلمات ۶۴ بیتی.
2. String Creation
napi_create_string_latin1: ایجاد رشته از buffer با encoding Latin1.napi_create_string_utf16: ایجاد رشته از buffer با encoding UTF-16.napi_create_string_utf8: ایجاد رشته از buffer با encoding UTF-8.node_api_create_external_string_latin1/node_api_create_external_string_utf16: ایجاد رشتههای خارجی که حافظهشان توسط کد بومی مدیریت میشود.
3. Optimized Property Keys
node_api_create_property_key_latin1: ایجاد کلید property بهینه با encoding Latin1.node_api_create_property_key_utf16: ایجاد کلید property بهینه با encoding UTF-16.node_api_create_property_key_utf8: ایجاد کلید property بهینه با encoding UTF-8.
این کلیدها برای استفاده بهعنوان property در اشیاء جاوااسکریپت بهینهسازی شدهاند و عملکرد بهتری در موتورهای جاوااسکریپت دارند.
4. Array و Buffer Info
napi_get_array_length: دریافت طول آرایه.napi_get_arraybuffer_info: دریافت اطلاعات buffer زیرین یک ArrayBuffer.napi_get_buffer_info: دریافت اطلاعات buffer زیرین یک Node.js Buffer یا Uint8Array.
5. TypedArray و DataView Info
napi_get_typedarray_info: دریافت نوع، طول و buffer زیرین یک TypedArray.napi_get_dataview_info: دریافت طول و buffer زیرین یک DataView.
نتیجهگیری
توابع napi_create_bigint و napi_create_string همراه با APIهای مدیریت buffer و property keys، ابزارهای قدرتمندی برای تعامل بین دادههای بومی و جاوااسکریپت فراهم میکنند. این قابلیتها توسعهدهندگان را قادر میسازند Addonهایی پایدار، کارآمد و بهینه بسازند.
1. اطلاعات TypedArray و DataView
napi_get_typedarray_info: دریافت نوع، طول، buffer و offset یک TypedArray.napi_get_dataview_info: دریافت طول، buffer و offset یک DataView.
2. Date و مقادیر اولیه
napi_get_date_value: بازگرداندن مقدار زمان یک Date جاوااسکریپت بهصورت double در C.napi_get_value_bool: تبدیل Boolean جاوااسکریپت به bool در C.napi_get_value_double: تبدیل Number جاوااسکریپت به double در C.napi_get_value_int32،napi_get_value_int64،napi_get_value_uint32: تبدیل Number جاوااسکریپت به انواع عددی C.
3. مقادیر BigInt
napi_get_value_bigint_int64: تبدیل BigInt به int64_t در C، همراه با پرچم lossless.napi_get_value_bigint_uint64: تبدیل BigInt به uint64_t در C، همراه با پرچم lossless.napi_get_value_bigint_words: تبدیل BigInt به sign bit و آرایهای از کلمات ۶۴ بیتی.
4. رشتهها و مقادیر خارجی
napi_get_value_string_latin1: دریافت رشته با encoding Latin1.napi_get_value_string_utf8: دریافت رشته با encoding UTF-8.napi_get_value_string_utf16: دریافت رشته با encoding UTF-16.napi_get_value_external: دریافت اشارهگر دادهٔ خارجی از یک مقدار جاوااسکریپت external.
5. نمونههای سراسری
napi_get_boolean: بازگرداندن singleton Boolean جاوااسکریپت.napi_get_global: بازگرداندن شیء global.napi_get_null: بازگرداندن مقدار null.napi_get_undefined: بازگرداندن مقدار undefined.
6. عملیات انتزاعی
napi_coerce_to_bool: تبدیل مقدار به Boolean.napi_coerce_to_number: تبدیل مقدار به Number.napi_coerce_to_object: تبدیل مقدار به Object.napi_coerce_to_string: تبدیل مقدار به String.
7. بررسی نوع و برابری
napi_typeof: بازگرداندن نوع یک مقدار جاوااسکریپت.napi_instanceof: بررسی اینکه آیا یک شیء نمونهای از سازندهٔ مشخص است.napi_is_array،napi_is_arraybuffer،napi_is_buffer،napi_is_date،napi_is_error،napi_is_typedarray،napi_is_dataview: بررسی نوع اشیاء جاوااسکریپت.napi_strict_equals: اجرای مقایسهٔ برابری سختگیرانه.
8. مدیریت ArrayBuffer
napi_detach_arraybuffer: جدا کردن یک ArrayBuffer.napi_is_detached_arraybuffer: بررسی اینکه آیا ArrayBuffer جدا شده است.node_api_is_sharedarraybuffer: بررسی اینکه آیا مقدار یک SharedArrayBuffer است.
نتیجهگیری
توابعی مانند napi_get_typedarray_info، napi_get_value_string_utf8 و napi_get_value_bigint_int64 دسترسی ایمن و کارآمد به مقادیر جاوااسکریپت را برای افزونههای بومی فراهم میکنند. با ترکیب بررسی نوع، توابع تبدیل و مدیریت buffer، Node-API تضمین میکند که کد بومی میتواند بهطور سازگار، ایمن و مطابق با استاندارد ECMAScript با اشیاء جاوااسکریپت تعامل کند.
1. SharedArrayBuffer Creation
node_api_create_sharedarraybuffer: ایجاد یک SharedArrayBuffer با طول مشخص. این buffer میتواند بین چندین Worker به اشتراک گذاشته شود.- دادهٔ زیرین بهصورت اختیاری به کد بومی بازگردانده میشود تا بتوان آن را مستقیماً مدیریت کرد.
2. Property Management
Node-API امکان مدیریت Propertyها را مشابه جاوااسکریپت فراهم میکند:
napi_set_property/napi_get_property: تنظیم یا دریافت یک Property با کلید دلخواه.napi_set_named_property/napi_get_named_property: مدیریت Propertyها با نام رشتهای.napi_set_element/napi_get_element: مدیریت Propertyها با ایندکس عددی (مانند آرایهها).napi_define_properties: تعریف چندین Property بهصورت کارآمد با استفاده ازnapi_property_descriptor.
3. Property Attributes
napi_writable: قابل نوشتن.napi_enumerable: قابل شمارش.napi_configurable: قابل پیکربندی.napi_static: ویژگیهای استاتیک در کلاسها.
4. Object Freezing and Sealing
napi_object_freeze: جلوگیری از افزودن یا تغییر Propertyها.napi_object_seal: جلوگیری از افزودن Propertyهای جدید و غیرقابلپیکربندی کردن ویژگیهای موجود.
5. JavaScript Functions
napi_create_function: ایجاد تابع جاوااسکریپت از کد بومی.napi_call_function: فراخوانی تابع جاوااسکریپت از کد بومی.napi_get_cb_info: دریافت اطلاعات مربوط به فراخوانی تابع (آرگومانها، this).napi_get_new_target: دریافت new.target در فراخوانی سازنده.napi_new_instance: ایجاد نمونهٔ جدید از یک سازندهٔ جاوااسکریپت.
نتیجهگیری
با استفاده از node_api_create_sharedarraybuffer و مجموعهٔ APIهای مدیریت Property و Function، توسعهدهندگان میتوانند افزونههای بومی قدرتمند و کارآمدی بسازند که دادهها را بین Workerها به اشتراک میگذارند و تعامل کامل با اشیاء و توابع جاوااسکریپت دارند.
1. Post Finalizer
node_api_post_finalizer: زمانبندی فراخوانیnapi_finalizeبهصورت ناهمزمان در حلقهٔ رویداد.- این روش اجازه میدهد عملیات پاکسازی که نیازمند Node-API هستند خارج از چرخهٔ GC اجرا شوند.
2. Simple Asynchronous Work
napi_create_async_work: ایجاد یک کار ناهمزمان با callbacks برای اجرا و تکمیل.napi_queue_async_work: صفبندی کار برای اجرا.napi_cancel_async_work: لغو کار قبل از شروع اجرا.napi_delete_async_work: آزادسازی منابع کار ناهمزمان.
3. Custom Asynchronous Operations
napi_async_init: ایجاد context ناهمزمان برای پیگیری عملیات.napi_async_destroy: آزادسازی context ناهمزمان.napi_make_callback: فراخوانی تابع جاوااسکریپت پس از عملیات ناهمزمان.napi_open_callback_scope/napi_close_callback_scope: مدیریت scope برای فراخوانیهای callback.
4. Version and Memory Management
napi_get_node_version: دریافت نسخهٔ Node.js.napi_get_version: دریافت بالاترین نسخهٔ پشتیبانیشدهٔ Node-API.napi_adjust_external_memory: تنظیم میزان حافظهٔ خارجی مدیریتشده توسط اشیاء جاوااسکریپت.
5. Promises
napi_create_promise: ایجاد Promise و deferred مرتبط.napi_resolve_deferred: حل Promise با مقدار مشخص.napi_reject_deferred: رد Promise با مقدار مشخص.napi_is_promise: بررسی اینکه آیا یک مقدار Promise است.
6. Script Execution
napi_run_script: اجرای کد جاوااسکریپت از رشتهٔ متنی.
7. Event Loop Access
napi_get_uv_event_loop: دریافت حلقهٔ libuv مرتبط با محیط.
8. Thread-Safe Function Calls
napi_create_threadsafe_function: ایجاد تابع ایمن برای فراخوانی از چندین Thread.napi_call_threadsafe_function: صفبندی داده برای فراخوانی تابع جاوااسکریپت.napi_release_threadsafe_function: آزادسازی منابع تابع ایمن.
نتیجهگیری
node_api_post_finalizer و مجموعهٔ APIهای ناهمزمان Node-API ابزارهای حیاتی برای مدیریت عملیات پیچیده در افزونههای بومی هستند. این قابلیتها امکان تعامل ایمن با جاوااسکریپت، مدیریت حافظه، و اجرای عملیات در چندین Thread را فراهم میکنند و پایهای برای توسعهٔ افزونههای پایدار و کارآمد محسوب میشوند.
نوشته و پژوهش شده توسط دکتر شاهین صیامی