Kotlin/JS هو مترجم من Kotlin إلى JavaScript يتيح إنشاء تطبيقات الواجهة الأمامية وواجهات الويب بلغة Kotlin. على عكس TypeScript، يوفر Kotlin/JS كتابة ثابتة صارمة، ودعم coroutines، وتكاملاً سلساً مع Kotlin Multiplatform. منذ Kotlin 1.8، يستخدم المترجم واجهة خلفية قائمة على IR لتوليد كود JavaScript محسّن. وفقاً لـ JetBrains، 2025، يدعم Kotlin/JS التكامل مع نظام NPM و TypeScript من خلال التوليد التلقائي لملفات .d.ts.
الملخص
Kotlin/JS هو واحد من ثلاث واجهات خلفية لمترجم Kotlin (إلى جانب JVM و Native)، مصمم لترجمة كود Kotlin إلى JavaScript. طورته JetBrains، يتيح Kotlin/JS كتابة تطبيقات ويب بلغة ذات كتابة ثابتة صارمة، مع الاحتفاظ بالوصول إلى النظام البيئي الواسع لمكتبات JavaScript من خلال التصريحات الخارجية. منذ أول إصدار مستقر في Kotlin 1.3، تطور المترجم من واجهة خلفية تجريبية إلى أداة جاهزة للإنتاج تُستخدم في المشاريع الصناعية.
الغرض الرئيسي من Kotlin/JS هو تطوير الواجهة الأمامية باستخدام Kotlin بدلاً من JavaScript أو TypeScript. يحصل المطورون على جميع ميزات لغة Kotlin: الأمان من القيم الخالية (null safety)، دوال الامتداد، فئات البيانات، coroutines، والفئات المختومة. يمكن تنفيذ كود JavaScript المُنشأ في أي متصفح حديث أو في بيئة Node.js. يعتبر Kotlin/JS ذا قيمة خاصة في مشاريع Kotlin Multiplatform، حيث تكون الوحدة المشتركة (commonMain) متاحة لكل من تطبيقات الجوال والويب.
يشمل النظام البيئي لـ Kotlin/JS أطر عمل لبناء واجهات المستخدم. Compose Multiplatform للويب يستخدم Kotlin/JS كواجهة خلفية مستهدفة، مما يتيح إنشاء مكونات واجهة توضيحية تعمل في المتصفح. تشمل الحلول البديلة أغلفة لـ React — Kotlin Wrappers، التي توفر واجهة برمجة تطبيقات آمنة من حيث الأنواع لـ React و React Router و Redux.
الترجمة في Kotlin/JS تمر بعدة مراحل تحويل. يتم أولاً ترجمة كود Kotlin المصدر إلى تمثيل وسيط (IR)، ثم تحسينه، وأخيراً توليد كود JavaScript. منذ Kotlin 1.8، تم استبدال الواجهة الخلفية القديمة (JsBackend القائمة على AST) بالكامل بالواجهة الخلفية IR، التي توفر تحسيناً أفضل، وحجماً أصغر لكود المخرجات، وتوافقاً مع TypeScript.
سابقاً، كان Kotlin/JS يستخدم JsBackend، الذي يعمل مباشرة مع AST (شجرة البنية المجردة). كان لهذا النهج قيود: صعوبة دعم تحسينات المنصة، وغياب IR موحد لجميع الواجهات الخلفية، وعدم القدرة على توليد تصريحات TypeScript. حل الانتقال إلى الواجهة الخلفية IR هذه المشاكل، مما وحد الترجمة عبر جميع الواجهات الخلفية الثلاث لـ Kotlin وفتح الطريق لتحسينات مشتركة بين الواجهات الخلفية.
Kotlin/JS يدعم وضعين للبناء يحددان تنسيق كود المخرجات وتحسينه. يستخدم وضع الإنتاج Webpack للتجميع والتصغير وإزالة الشفرة الميتة. يدعم وضع التطوير Hot Module Replacement للتكرار السريع أثناء التطوير. يتم تحديد الوضع في build.gradle.kts من خلال إعداد js.target.
kotlin {
js {
browser {
webpackTask {
outputFileName = "app.js"
}
}
binaries.executable()
}
}
التكامل بين Kotlin/JS والنظام البيئي NPM يتم من خلال DSL خاص في build.gradle.kts. يصرّح المطور بتبعيات npm في إعداد kotlin، مع تحديد اسم الحزمة والإصدار. يقوم Kotlin/JS تلقائياً بجلب الحزم عبر مدير الحزم npm أو yarn. لضمان الوصول الآمن من حيث الأنواع إلى مكتبات JavaScript، تُستخدم التصريحات الخارجية التي تصف أنواع ووظائف المكتبة لمترجم Kotlin.
التصريحات الخارجية هي تصريحات Kotlin موسومة بالكلمة المفتاحية external. تُخبر المترجم أن تنفيذ الدالة أو الفئة موجود في كود JavaScript، وليس في Kotlin. توفر JetBrains مجموعات أغلفة جاهزة للمكتبات الشائعة ضمن Kotlin Wrappers، بما في ذلك React و React Router و Redux و Emotion و MUI. للمكتبات التي ليس لها أغلفة جاهزة، يمكن للمطور كتابة تصريحات خارجية يدوياً أو استخدام مولد ربط TypeScript Dukat.
kotlin {
js {
browser { }
npm {
dependency("react", "18.3.1")
dependency("react-dom", "18.3.1")
devDependency("webpack", "5.92.0")
}
}
}
// إعلان خارجي لمكتبة JavaScript
@JsModule("date-fns")
external fun formatDistance(
date: Date, baseDate: Date
): String
TypeScript جزء لا يتجزأ من الويب الحديث، ويضمن Kotlin/JS التوافق معه من خلال توليد ملفات .d.ts. عند تعيين js.generateTsDeclarations = true، يقوم المترجم بإنشاء تصريحات TypeScript لجميع دوال وفئات Kotlin العامة. يتيح ذلك لمشاريع TypeScript استيراد وحدات Kotlin بدعم كامل للأنواع. يعمل توليد تصريحات TypeScript فقط مع الواجهة الخلفية IR وهو أحد الأسباب الرئيسية للترحيل من الواجهة الخلفية القديمة.
الواجهة الخلفية IR (Intermediate Representation) هي واجهة خلفية موحدة لمنصات Kotlin الثلاث: JVM و JS و Native. تستخدم تمثيلاً وسيطاً مشتركاً يمر بعدة مراحل تحسين قبل توليد الكود المستهدف. بالنسبة لـ Kotlin/JS، أصبحت الواجهة الخلفية IR إلزامية بدءاً من Kotlin 1.8.0، لتحل محل الواجهة الخلفية القديمة القائمة على AST التي تم وضع علامة عليها كمهملة.
تشمل مزايا الواجهة الخلفية IR لـ Kotlin/JS تحسيناً أفضل للكود على مستوى IR، وتقليل حجم الحزمة من خلال إزالة الشفرة الميتة وتحسينات التضمين، بالإضافة إلى دعم تصريحات TypeScript. تضمن الواجهة الخلفية IR أيضاً معالجة صحيحة للدوال المضمنة والأنواع العامة reified ودوال suspend عند الترجمة إلى JavaScript، وهو ما كان إشكالياً في الواجهة الخلفية القديمة.
| الميزة | الواجهة الخلفية القديمة (AST) | الواجهة الخلفية IR |
|---|---|---|
| تصريحات TypeScript | غير مدعومة | تُنشأ تلقائياً |
| إزالة الشفرة الميتة | محدودة | كاملة، على مستوى IR |
| الدوال المضمنة | مشاكل في الصحة | معالجة صحيحة |
| الأنواع العامة reified | غير مدعومة | مدعومة |
| حجم الحزمة | أساسي | أصغر بنسبة 20–30% |
يبدأ مشروع Kotlin/JS كامل بتكوين build.gradle.kts. يتيح إضافة kotlin multiplugin إعداد Kotlin/JS كواحدة من المنصات المستهدفة. لنلقِ نظرة على مثال إعداد لتطبيق ويب مع React.
plugins {
kotlin("multiplatform") version "2.0.21"
id("org.jetbrains.kotlin-wrappers") version "1.0.0-pre.775"
}
kotlin {
js {
browser { }
binaries.executable()
generateTsDeclarations = true
}
}
dependencies {
implementation(enwraps(react, reactDom))
}
بعد الإعداد، يمكن كتابة مكونات React بلغة Kotlin. توفر Kotlin Wrappers واجهة برمجة تطبيقات آمنة من حيث الأنواع لـ React، بما في ذلك المكونات الوظيفية و hooks وبناء جملة يشبه JSX من خلال منشئات DSL. يوضح مثال مكون Counter العمل مع useState ومعالجات الأحداث.
@OptIn(ExperimentalWrapperApi::class)
val Counter = FC<Props> {
var count = useState(0)
div {
+"Counter value: ${count.component1()}"
button {
onClick = { count.component2()(count.component1() + 1) }
+"Increment"
}
}
}
fun main() {
createRoot(document.getElementById("root")!!).render(
createElement(Counter)
)
}
يتم بناء مشروع Kotlin/JS من خلال مهام Gradle. jsDevelopmentRun يشغل خادم تطوير Webpack مع HMR للتطوير. jsProductionExecutableCompileSync يُنشئ حزمة إنتاج مع التصغير وإزالة الشفرة الميتة. يتم إنشاء ملف HTML النهائي الذي يتضمن JavaScript المُجمّع بواسطة إضافة webpack ويوضع في build/dist.
// بدء خادم التطوير مع HMR
./gradlew jsDevelopmentRun
// بناء الإنتاج مع التصغير
./gradlew jsProductionExecutableCompileSync
// المخرجات في build/dist/productionExecutable/
TypeScript هو المنافس الرئيسي لـ Kotlin/JS في مجال JavaScript المكتوب. يتم ترجمة كلا اللغتين إلى JavaScript ويضيفان كتابة ثابتة فوق JS الديناميكي. ومع ذلك، يقدم Kotlin/JS عدة مزايا: الأمان من القيم الخالية افتراضياً، والفئات المختومة، و coroutines، والتكامل السلس مع Kotlin Multiplatform. في المقابل، يمتلك TypeScript مجتمعاً أكبر، والمزيد من المكتبات الجاهزة مع الأنواع، ونظاماً بيئياً أكثر نضجاً.
قد تكون إنتاجية التطوير باستخدام Kotlin/JS أعلى للفرق التي تستخدم Kotlin بالفعل في أجزاء أخرى من المشروع، حيث لا يتطلب التبديل بين اللغات. يظل TypeScript الخيار الأكثر شيوعاً لمشاريع الويب الخالصة حيث لا يُستخدم Kotlin Multiplatform. ومع ذلك، مع تزايد شعبية Compose Multiplatform للويب، يكتسب Kotlin/JS مكانة كبديل لـ React و Angular.
| الميزة | Kotlin/JS | TypeScript |
|---|---|---|
| الأمان من القيم الخالية | افتراضياً | strictNullChecks اختياري |
| الفئات المختومة | مدعومة | عبر union types |
| Coroutines | أصلياً | عبر async/await |
| تكامل KMM | كامل | لا يوجد |
| حجم المجتمع | صغير | ضخم |
| أنواع جاهزة للمكتبات | محدودة (DefinitelyTyped عبر Dukat) | DefinitelyTyped (آلاف المكتبات) |
يعتمد الاختيار بين Kotlin/JS و TypeScript على سياق المشروع. إذا كان الفريق يستخدم بالفعل Kotlin Multiplatform أو يخطط للبدء، فإن Kotlin/JS هو الخيار المنطقي لجزء الواجهة الأمامية. بالنسبة لمشروع ويب منعزل، يظل TypeScript حلاً أكثر عملية بسبب توفر الأنواع الجاهزة لمكتبات JavaScript وعدد أكبر من المطورين في السوق.
الأسئلة الشائعة
نعم، توفر JetBrains Kotlin Wrappers — أغلفة Kotlin آمنة من حيث الأنواع لـ React و React Router و Redux. تسمح بكتابة مكونات React بلغة Kotlin مع دعم كامل لـ hooks و DSL شبيه بـ JSX.
عند تفعيل generateTsDeclarations = true، يُنشئ Kotlin/JS ملفات .d.ts لجميع واجهات برمجة التطبيقات العامة. يمكن لمشاريع TypeScript استيراد وحدات Kotlin مع كتابة كاملة كحزم npm عادية.
يعتمد حجم الحزمة على المكتبات المستخدمة. تطبيق Hello World الأدنى يستهلك حوالي 300 كيلوبايت بما في ذلك stdlib الخاصة بـ Kotlin. مع React و Kotlin Wrappers، يزداد الحجم إلى 400–600 كيلوبايت.
نعم، يمكن استخدام Kotlin/JS لتطوير دوال serverless وأدوات وحدة التحكم في Node.js. للقيام بذلك، يجب تحديد js.nodejs بدلاً من js.browser في الإعدادات.
Kotlin/Wasm هي واجهة خلفية تجريبية لـ WebAssembly، بينما يُنشئ Kotlin/JS كود JavaScript. يوفر Wasm أداءً أعلى ولكن لديه وصول محدود إلى DOM الخاص بالمتصفح.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.