الترجمة المصدرية هي تحويل الكود المصدري من لغة برمجة إلى أخرى على نفس مستوى التجريد. على عكس التجميع إلى كود آلي، تقوم الترجمة المصدرية بترجمة الكود بين لغات عالية المستوى: TypeScript إلى JavaScript، Kotlin إلى Java، Dart إلى JavaScript. وفقًا لـ Babel Documentation، فإن Babel هو المُترجم المصدر الأكثر شعبية مع أكثر من 35 مليون تنزيل أسبوعيًا ودعم لمئات الإضافات.
النقاط الرئيسية
الترجمة المصدرية (التجميع من مصدر إلى مصدر) هي عملية ترجمة برنامج من لغة برمجة إلى أخرى مع الحفاظ على نفس مستوى التجريد. يأخذ المُترجم المصدر كودًا بلغة A ويُنتج كودًا مكافئًا بلغة B يمكن تنفيذه في البيئة المستهدفة. أمثلة نموذجية: TypeScript إلى JavaScript، SASS إلى CSS، Haxe إلى عدة لغات مستهدفة.
تختلف الترجمة المصدرية عن التجميع في أن الكود الناتج يبقى على مستوى عالٍ ويمكن قراءته بواسطة البشر (وإن لم يكن مخصصًا لذلك). المُجمّع (GCC، LLVM، javac) يترجم الكود إلى كود آلي أو bytecode — تنسيق غير قابل للقراءة. يُنتج المُترجم المصدر كودًا يمكن تجميعه أو تصغيره لاحقًا.
لماذا نحتاج الترجمة المصدرية. السبب الرئيسي هو التوافق. يريد المطورون استخدام لغات حديثة (TypeScript مع الأنواع، Kotlin مع أمان القيم الخالية)، لكن المنصة المستهدفة تدعم فقط JavaScript أو Java. تتيح الترجمة المصدرية الكتابة بلغة حديثة مع نشر كود مفهوم للبيئة المستهدفة.
| المُترجم المصدر | المصدر → الهدف | الاستخدام |
|---|---|---|
| Babel | ES6+/TypeScript → ES5 | تطوير الويب، React، Vue |
| tsc (مترجم TypeScript) | TypeScript → JavaScript | أي تطبيق TypeScript |
| kotlinc-js | Kotlin → JavaScript | Kotlin/JS، React Kotlin Wrappers |
| dart2js | Dart → JavaScript | Flutter Web، AngularDart |
| SWC | TypeScript/JS → ES5 | Next.js، التجميع باستخدام Rust |
مستوى التجريد هو الفرق الرئيسي. يُترجم المُترجم المصدر الكود بين لغات من نفس المستوى (عالٍ ← عالٍ). يُترجم المُجمّع من مستوى عالٍ إلى مستوى منخفض (كود آلي، bytecode). LLVM IR هو تمثيل وسيط لكنه يظل أقل مستوى من C++ أو Rust الأصلي.
قابلية قراءة النتيجة هي الفرق الثاني. نتيجة الترجمة المصدرية (JavaScript من TypeScript) قابلة للقراءة ويمكن تصحيحها في المتصفح. نتيجة التجميع (كود آلي من C++) غير مخصصة للقراءة — تحليلها يتطلب مفككًا. تساعد خرائط المصدر (source maps) في تصحيح الكود المُترجم مصدريًا من خلال ربطه بالكود الأصلي.
في خطوط أنابيب CI/CD، يتم تنفيذ الترجمة المصدرية في مرحلة البناء. لمشاريع TypeScript، يعمل tsc أو Babel داخل حاوية Docker، ويُنتج JavaScript وخرائط مصدر، ثم يتم تصغيرها ونشرها على الخادم أو متجر التطبيقات. من المهم تكوين التخزين المؤقت لنتائج الترجمة المصدرية — tsc --incremental يحفظ رسم بياني للتبعيات بين مرات التشغيل، مما يقلل وقت البناء بنسبة 30-50%.
للمشاريع المحمولة (React Native)، يتم تنفيذ الترجمة المصدرية عبر Metro Bundler على خادم CI مع كل إصدار. تُستخدم أدلة التخزين المؤقت (tmp/metro-cache) والبناء المتوازي عبر --workers لتسريع العملية. يدعم GitHub Actions وGitLab CI التخزين المؤقت لدليل node_modules و.cache بين مرات التشغيل، وهو أمر بالغ الأهمية لتقليل وقت خط الأنابيب.
سرعة التنفيذ تختلف أيضًا. التجميع إلى كود آلي يُعطي أقصى أداء. تحافظ الترجمة المصدرية على عبء مستوى التجريد: JavaScript من TypeScript يعمل بنفس سرعة JavaScript العادية. تعمل التحسينات (TypeScript —strict) في مرحلة التحليل، وليس في وقت التشغيل.
السيناريو 1: TypeScript → JavaScript — السيناريو الأكثر شيوعًا. يكتب المطور TypeScript بأنواع، ويقوم المترجم tsc أو Babel بإزالة تعليقات الأنواع وإنشاء JavaScript نقي. جميع مشاريع Angular ومعظم مشاريع React (2026) تستخدم ترجمة TypeScript المصدرية. وفقًا لـ State of JS 2025، 79% من المطورين الذين شملهم الاستطلاع يستخدمون TypeScript في مشاريعهم الأساسية.
السيناريو 2: Kotlin → JavaScript — يُستخدم في Kotlin/JS للتطوير الكامل (Full-Stack). يتم تجميع كود Kotlin إلى JavaScript عبر مترجم Kotlin مع IR (Intermediate Representation). يدعم Kotlin/JS تعريفات TypeScript المكتوبة (.d.ts) للتكامل مع مكتبات JS الخارجية. تستخدم JetBrains Kotlin/JS في منتجاتها الخاصة لواجهات الويب.
السيناريو 3: SASS/SCSS → CSS — ترجمة مصدرية لمعالجات CSS الأولية. يقوم Dart Sass (التنفيذ الموصى به) بترجمة .scss إلى .css، مع توسيع mixins والمتغيرات والقواعد المتداخلة والوظائف. هذا ليس تجميعًا (CSS يبقى CSS)، بل ترجمة مصدرية مع توسيع نحوي.
| المعامل | الترجمة المصدرية | التجميع | التفسير |
|---|---|---|---|
| المدخل → المخرَج | عالٍ ← عالٍ | عالٍ ← كود آلي | كود ← تنفيذ فوري |
| مثال | TypeScript → JavaScript | C++ → ARM/x86 | Python ← CPython runtime |
| الكود المخرَج قابل للقراءة | نعم | لا | غير قابل للتطبيق |
| الأداء | مثل اللغة الهدف | أقصى | أقل من التجميع |
| يتطلب بيئة تشغيل | لا (كود هدف نقي) | لا | نعم |
Babel هو أشهر مترجم مصدر لـ JavaScript، يحول كود ES6+/ESNext إلى JavaScript متوافق مع ES5. يعمل Babel من خلال نظام من الإضافات والمجموعات (presets): كل إضافة مسؤولة عن تحويل واحد (دوال السهم، async/await، optional chaining). @babel/preset-env يحدد تلقائيًا الإضافات الضرورية بناءً على المتصفحات المستهدفة (browserslist).
تتكون بنية Babel من ثلاث مراحل: التحليل (parsing) → التحويل (transformation) → التوليد (generation). المُحلل (Babylon/@babel/parser) يحول الكود المصدري إلى AST (شجرة نحوية مجردة). المُحوّلات (الإضافات) تُعدّل AST. المُولّد (@babel/generator) يُنتج الكود المخرَج من AST المُعدّل.
// كود ES6+ الأصلي
const greet = (name = "World") => {
return `Hello, ${name}!`;
};
class User {
constructor(name) {
this.name = name;
}
}
const data = { user: { address: { city: "Moscow" } } };
const city = data?.user?.address?.city;// بعد Babel (target: > 0.25%, not dead)
"use strict";
var greet = function (name) {
if (name === void 0) { name = "World"; }
return "Hello, " + name + "!";
};
var User = function (name) {
this.name = name;
};
var data = { user: { address: { city: "Moscow" } } };
var city = data != null
? data.user != null
? data.user.address != null
? data.user.address.city
: void 0
: void 0
: void 0;Babel حوّل: دالة السهم إلى تعبير دالة، المعامل الافتراضي (name = "World") إلى فحص void 0، سلسلة القالب إلى تسلسل، الفئة إلى دالة إنشاء، والربط الاختياري (?.) إلى سلسلة من العوامل الثلاثية. تم استبدال const بـ var للتوافق مع ES5.
TypeScript هي لغة مكتوبة بشدة تُترجم مصدريًا إلى JavaScript. يقوم المترجم tsc (مترجم TypeScript) بمهمتين: التحقق من الأنواع (type checking) والترجمة المصدرية (emit). من المهم أن نفهم: التحقق من الأنواع والترجمة المصدرية مرحلتان مستقلتان. يمكن تنفيذ الترجمة المصدرية دون التحقق من الأنواع (--noEmitOnError false) أو التحقق من الأنواع دون توليد كود (--noEmit true).
الترجمة المصدرية لـ TypeScript تزيل جميع تعليقات الأنواع والواجهات وأسماء الأنواع المستعارة ومعاملات الأدوية — فهي غير موجودة في JavaScript. يتم تحويل Enum إلى كائنات، والديكورات إلى استدعاءات دالة، async/await إلى مولدات (إذا كان target أقل من ES2017). يدير tsconfig.json target (إصدار JavaScript)، module (نظام الوحدات)، strict (درجة التحقق من الأنواع) وoutDir (مجلد الإخراج).
{
"compilerOptions": {
"target": "es2015",
"module": "esnext",
"lib": ["es2015", "dom"],
"strict": true,
"outDir": "./dist",
"rootDir": "./src",
"esModuleInterop": true,
"sourceMap": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}target: "es2015" يُوجه tsc لتوليد JavaScript ببناء ES6 (دوال السهم، الفئات، let/const). module: "esnext" يحافظ على وحدات ES (import/export) للـ Tree Shaking اللاحق في Webpack. strict: true يُفعّل جميع عمليات التحقق من الأنواع (strictNullChecks، noImplicitAny، strictFunctionTypes). declaration: true يُنشئ ملفات .d.ts لمستهلكي TypeScript للمكتبة.
React Native يستخدم Babel وMetro لترجمة JavaScript/TypeScript إلى كود قابل للتنفيذ بواسطة JavaScriptCore (iOS) أو Hermes (Android). إضافات Babel تضيف تحويل JSX، وتعليقات Flow/TypeScript، وتحسينات خاصة بـ React Native. يقوم Metro Bundler أيضًا بتجميع الوحدات وتنفيذ الاستبدال السريع للوحدات (Hot Module Replacement) للتطوير.
Flutter يستخدم ترجمة Dart المصدرية. لـ Flutter Web، يقوم dart2js بترجمة Dart إلى JavaScript محسّن. لـ Flutter Mobile، يقوم dart2native بتجميع Dart إلى كود ARM أصلي. يدعم Flutter أيضًا Dart DevCompiler (dartdevc) للتطوير — يترجم Dart إلى JavaScript بشكل أسرع ولكن مع تحسين أقل.
// babel.config.js — ترجمة React Native المصدرية
module.exports = {
presets: [
["module:metro-react-native-babel-preset"],
],
plugins: [
["module-resolver", {
root: ["."],
alias: {
"@": "./src",
"@components": "./src/components",
},
}],
"react-native-reanimated/plugin",
],
env: {
production: {
plugins: ["transform-remove-console"],
},
},
};metro-react-native-babel-preset يتضمن جميع الإضافات الضرورية لـ React Native: JSX، Flow/TypeScript، نظام وحدات Metro، async/await، خصائص الفئة والديكورات. تضيف إضافة module-resolver أسماء مستعارة للاستيرادات القصيرة (@/components/Button بدلاً من ../../components/Button). في وضع الإنتاج، تقوم transform-remove-console بإزالة جميع console.log من الكود.
الأسئلة الشائعة
الترجمة المصدرية تنقل الكود من لغة إلى أخرى على نفس المستوى (مثل TypeScript → JavaScript). التجميع ينقل من مستوى عالٍ إلى مستوى منخفض (C++ → كود آلي). نتيجة الترجمة المصدرية قابلة للقراءة، ونتيجة التجميع غير قابلة للقراءة.
React Native يتطلب ترجمة مصدرية افتراضيًا — يستخدم Metro Bundler Babel لتحويل JSX وTypeScript وJavaScript الحديث إلى كود متوافق مع JavaScriptCore وHermes. بدون Babel، لن يتمكن React Native من تنفيذ بناء JSX للمكونات.
نعم: Babel مع @babel/preset-typescript وSWC يدعمان الترجمة المصدرية لـ TypeScript. هذا أسرع من tsc، لكن Babel لا يقوم بالتحقق من الأنواع — فقط يزيل تعليقات الأنواع. للتحقق من الأنواع، تحتاج إلى تشغيل tsc --noEmit بشكل منفصل أو عبر fork-ts-checker-webpack-plugin.
خرائط المصدر هي ملفات تربط الكود المُترجم مصدريًا بالمصدر الأصلي. تسمح بتصحيح TypeScript في المتصفح: تُوضع نقاط التوقف في ملفات .ts، وتظهر تتبعات الاستدعاء أسطر .ts بدلاً من .js. بدون خرائط المصدر، يكاد يكون من المستحيل تصحيح الكود المُترجم مصدريًا.
الترجمة المصدرية نفسها لا تؤثر على أداء التطبيق — يعمل الكود الناتج بنفس سرعة الكود المكتوب أصلاً باللغة الهدف. يحدث العبء فقط إذا كان المُترجم المصدر يُنتج كودًا غير أمثل (على سبيل المثال، قد يُنشئ Babel polyfills ضخمة لطرق المصفوفات).
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا