Skip to content

REPL

[مستقر: 2 - مستقر]

مستقر: 2 استقرار: 2 - مستقر

رمز المصدر: lib/repl.js

توفر وحدة node:repl تنفيذ حلقة القراءة والتقييم والطباعة (REPL) المتاحة كبرنامج مستقل أو قابلة للإدراج في تطبيقات أخرى. يمكن الوصول إليها باستخدام:

js
import repl from 'node:repl'
js
const repl = require('node:repl')

التصميم والميزات

تقوم وحدة node:repl بتصدير فئة repl.REPLServer. أثناء التشغيل، ستقبل مثيلات repl.REPLServer أسطرًا فردية من إدخال المستخدم، وتقييمها وفقًا لدالة تقييم محددة من قبل المستخدم، ثم إخراج النتيجة. قد يكون الإدخال والإخراج من stdin و stdout، على التوالي، أو قد يكون متصلاً بأي دفق Node.js stream.

تدعم مثيلات repl.REPLServer الإكمال التلقائي لإدخالات، ومعاينة الإكمال، وتحرير سطر بسيط على طراز Emacs، وإدخالات متعددة الأسطر، والبحث العكسي عن طريق i على غرار ZSH، والبحث في محفوظات قائم على السلاسل الفرعية على غرار ZSH، والإخراج ذي الأنماط ANSI، وحفظ واستعادة حالة جلسة REPL الحالية، واسترداد الأخطاء، ودوال تقييم قابلة للتخصيص. تعمل المحطات التي لا تدعم أنماط ANSI وتحرير السطر على طراز Emacs تلقائيًا على الرجوع إلى مجموعة ميزات محدودة.

الأوامر والمفاتيح الخاصة

تدعم جميع مثيلات REPL الأوامر الخاصة التالية:

  • .break: عند عملية إدخال تعبير متعدد الأسطر، أدخل الأمر .break (أو اضغط على +) لإلغاء المزيد من الإدخال أو معالجة هذا التعبير.
  • .clear: يعيد تعيين سياق REPL إلى كائن فارغ ويمسح أي تعبير متعدد الأسطر قيد الإدخال.
  • .exit: أغلق دفق الإدخال/الإخراج، مما يتسبب في خروج REPL.
  • .help: عرض هذه القائمة من الأوامر الخاصة.
  • .save: احفظ جلسة REPL الحالية في ملف: \> .save ./file/to/save.js
  • .load: تحميل ملف في جلسة REPL الحالية. \> .load ./file/to/load.js
  • .editor: أدخل وضع المحرر (+ لإنهاء، + لإلغاء).
bash
> .editor
// دخول وضع المحرر (^D لإنهاء، ^C لإلغاء)
function welcome(name) {
  return `Hello ${name}!`;
}

welcome('Node.js User');

// ^D
'Hello Node.js User!'
>

مجموعة المفاتيح التالية في REPL لها هذه التأثيرات الخاصة:

  • +: عند الضغط عليها مرة واحدة، يكون لها نفس تأثير الأمر .break. عند الضغط عليها مرتين على سطر فارغ، يكون لها نفس تأثير الأمر .exit.
  • +: لها نفس تأثير الأمر .exit.
  • : عند الضغط عليها على سطر فارغ، تعرض المتغيرات العالمية والمحلية (النطاق). عند الضغط عليها أثناء إدخال مدخلات أخرى، تعرض خيارات الإكمال ذات الصلة.

لروابط المفاتيح المتعلقة بالبحث العكسي عن طريق i، انظر reverse-i-search. لجميع روابط المفاتيح الأخرى، انظر روابط مفاتيح TTY.

تقييم افتراضي

بشكل افتراضي، تستخدم جميع مثيلات repl.REPLServer دالة تقييم تقيم تعبيرات JavaScript وتوفر الوصول إلى الوحدات المُدمجة في Node.js. يمكن تجاوز هذا السلوك الافتراضي عن طريق تمرير دالة تقييم بديلة عند إنشاء مثيل repl.REPLServer.

تعبيرات JavaScript

يدعم المُقيم الافتراضي التقييم المباشر لتعبيرات JavaScript:

bash
> 1 + 1
2
> const m = 2
undefined
> m + 1
3

ما لم يتم تحديد نطاقها بشكل مختلف ضمن الكتل أو الدوال، يتم إعلان المتغيرات التي تم إعلانها ضمنيًا أو باستخدام كلمات المفتاح const أو let أو var على مستوى النطاق العام.

النطاق العام والمحلي

يوفر المُقيم الافتراضي الوصول إلى أي متغيرات موجودة في النطاق العام. من الممكن عرض متغير على REPL بشكل صريح عن طريق تعيينه إلى كائن context المرتبط بكل REPLServer:

js
import repl from 'node:repl'
const msg = 'message'

repl.start('> ').context.m = msg
js
const repl = require('node:repl')
const msg = 'message'

repl.start('> ').context.m = msg

تظهر خصائص كائن context كمحلية داخل REPL:

bash
$ node repl_test.js
> m
'message'

خصائص السياق ليست للقراءة فقط بشكل افتراضي. لتحديد العناصر العالمية للقراءة فقط، يجب تعريف خصائص السياق باستخدام Object.defineProperty():

js
import repl from 'node:repl'
const msg = 'message'

const r = repl.start('> ')
Object.defineProperty(r.context, 'm', {
  configurable: false,
  enumerable: true,
  value: msg,
})
js
const repl = require('node:repl')
const msg = 'message'

const r = repl.start('> ')
Object.defineProperty(r.context, 'm', {
  configurable: false,
  enumerable: true,
  value: msg,
})

الوصول إلى وحدات Node.js الأساسية

سيقوم المُقيم الافتراضي تلقائيًا بتحميل وحدات Node.js الأساسية إلى بيئة REPL عند استخدامها. على سبيل المثال، ما لم يتم إعلانها بشكل مختلف كمتغير عام أو ذي نطاق محدد، سيتم تقييم الإدخال fs عند الطلب كـ global.fs = require('node:fs').

bash
> fs.createReadStream('./some/file');

الاستثناءات غير المعالجة عالميًا

[السجل]

الإصدارالتغييرات
v12.3.0حدث 'uncaughtException' يُثار الآن إذا تم استخدام repl كبرنامج مستقل.

يستخدم REPL وحدة domain لالتقاط جميع الاستثناءات غير المعالجة لجلسة REPL هذه.

يستخدم domain في REPL له هذه الآثار الجانبية:

تعيين متغير _ (شرطة سفلية)

[السجل]

الإصدارالتغييرات
v9.8.0تمت إضافة دعم _error.

سيقوم المُقيم الافتراضي، بشكل افتراضي، بتعيين نتيجة أحدث تعبير تم تقييمه إلى المتغير الخاص _ (شرطة سفلية). سيؤدي تعيين _ صراحةً إلى قيمة إلى تعطيل هذا السلوك.

bash
> [ 'a', 'b', 'c' ]
[ 'a', 'b', 'c' ]
> _.length
3
> _ += 1
تم تعطيل تعيين التعبير إلى _ الآن.
4
> 1 + 1
2
> _
4

وبالمثل، سيشير _error إلى آخر خطأ تم رؤيته، إذا كان هناك أي خطأ. سيؤدي تعيين _error صراحةً إلى قيمة إلى تعطيل هذا السلوك.

bash
> throw new Error('foo');
خطأ غير معالج: foo
> _error.message
'foo'

كلمة مفتاح await

تم تمكين دعم كلمة المفتاح await على أعلى مستوى.

bash
> await Promise.resolve(123)
123
> await Promise.reject(new Error('REPL await'))
خطأ غير معالج: REPL await
    at REPL2:1:54
> const timeout = util.promisify(setTimeout);
undefined
> const old = Date.now(); await timeout(1000); console.log(Date.now() - old);
1002
undefined

يوجد قيد معروف واحد لاستخدام كلمة المفتاح await في REPL وهو أنه سيؤدي إلى إبطال النطاق اللغوي لكلمات المفتاح const و let.

مثال:

bash
> const m = await Promise.resolve(123)
undefined
> m
123
> const m = await Promise.resolve(234)
undefined
> m
234

--no-experimental-repl-await سيؤدي إلى تعطيل await على مستوى أعلى في REPL.

مضاف في: v13.6.0، v12.17.0

يدعم REPL البحث العكسي ثنائي الاتجاه المشابه لـ ZSH. يتم تشغيله باستخدام + للبحث للخلف و + للبحث للأمام.

سيتم تخطي مدخلات التاريخ المكررة.

يتم قبول الإدخالات بمجرد الضغط على أي مفتاح لا يتوافق مع البحث العكسي. إلغاء البحث ممكن بالضغط على أو +.

يؤدي تغيير الاتجاه على الفور إلى البحث عن الإدخال التالي في الاتجاه المتوقع من الموضع الحالي.

دوال التقييم المخصصة

عند إنشاء repl.REPLServer جديد، يمكن توفير دالة تقييم مخصصة. يمكن استخدام هذا، على سبيل المثال، لتنفيذ تطبيقات REPL مخصصة بالكامل.

يوضح ما يلي مثالاً على REPL يربع رقمًا معينًا:

js
import repl from 'node:repl'

function byThePowerOfTwo(number) {
  return number * number
}

function myEval(cmd, context, filename, callback) {
  callback(null, byThePowerOfTwo(cmd))
}

repl.start({ prompt: 'Enter a number: ', eval: myEval })
js
const repl = require('node:repl')

function byThePowerOfTwo(number) {
  return number * number
}

function myEval(cmd, context, filename, callback) {
  callback(null, byThePowerOfTwo(cmd))
}

repl.start({ prompt: 'Enter a number: ', eval: myEval })

الأخطاء القابلة للاسترداد

في موجه REPL، يؤدي الضغط على إرسال سطر الإدخال الحالي إلى دالة eval. لدعم إدخال متعدد الأسطر، يمكن لدالة eval إرجاع مثيل من repl.Recoverable إلى دالة callback المقدمة:

js
function myEval(cmd, context, filename, callback) {
  let result
  try {
    result = vm.runInThisContext(cmd)
  } catch (e) {
    if (isRecoverableError(e)) {
      return callback(new repl.Recoverable(e))
    }
  }
  callback(null, result)
}

function isRecoverableError(error) {
  if (error.name === 'SyntaxError') {
    return /^(Unexpected end of input|Unexpected token)/.test(error.message)
  }
  return false
}

تخصيص مخرجات REPL

بشكل افتراضي، تقوم مثيلات repl.REPLServer بتنسيق المخرجات باستخدام طريقة util.inspect() قبل كتابة المخرجات إلى دفق Writable المُقدم ( process.stdout بشكل افتراضي). يتم تعيين خيار الفحص showProxy على true بشكل افتراضي، ويتم تعيين خيار colors على true بناءً على خيار useColors لـ REPL.

يمكن تحديد الخيار المنطقي useColors عند الإنشاء لإرشاد الكاتب الافتراضي إلى استخدام رموز أنماط ANSI لتلوين المخرجات من طريقة util.inspect().

إذا تم تشغيل REPL كبرنامج مستقل، فمن الممكن أيضًا تغيير إعدادات الفحص الافتراضية لـ REPL من داخل REPL باستخدام خاصية inspect.replDefaults التي تعكس defaultOptions من util.inspect().

bash
> util.inspect.replDefaults.compact = false;
false
> [1]
[
  1
]
>

لتخصيص مخرجات مثيل repl.REPLServer بالكامل، قم بتمرير دالة جديدة لخيار writer عند الإنشاء. على سبيل المثال، يقوم المثال التالي بتحويل أي نص إدخال إلى أحرف كبيرة:

js
import repl from 'node:repl'

const r = repl.start({ prompt: '> ', eval: myEval, writer: myWriter })

function myEval(cmd, context, filename, callback) {
  callback(null, cmd)
}

function myWriter(output) {
  return output.toUpperCase()
}
js
const repl = require('node:repl')

const r = repl.start({ prompt: '> ', eval: myEval, writer: myWriter })

function myEval(cmd, context, filename, callback) {
  callback(null, cmd)
}

function myWriter(output) {
  return output.toUpperCase()
}

Class: REPLServer

مضاف في: v0.1.91

يتم إنشاء مثيلات repl.REPLServer باستخدام طريقة repl.start() أو مباشرةً باستخدام الكلمة المفتاحية new في JavaScript.

js
import repl from 'node:repl'

const options = { useColors: true }

const firstInstance = repl.start(options)
const secondInstance = new repl.REPLServer(options)
js
const repl = require('node:repl')

const options = { useColors: true }

const firstInstance = repl.start(options)
const secondInstance = new repl.REPLServer(options)

حدث: 'exit'

مضاف في: v0.7.7

يُصدر حدث 'exit' عند الخروج من REPL إما باستقبال الأمر .exit كمدخل، أو ضغط المستخدم على + مرتين للإشارة إلى SIGINT، أو بالضغط على + للإشارة إلى 'end' في دفق الإدخال. يتم استدعاء دالة الاستدعاء الخاصة بالمستمع بدون أي وسيطات.

js
replServer.on('exit', () => {
  console.log('Received "exit" event from repl!')
  process.exit()
})

حدث: 'reset'

مضاف في: v0.11.0

يُصدر حدث 'reset' عند إعادة تعيين سياق REPL. يحدث هذا كلما تم استقبال الأمر .clear كمدخل إلا إذا كان REPL يستخدم مُقيّم الإفتراضي وتم إنشاء مثيل repl.REPLServer مع تعيين خيار useGlobal إلى true. سيتم استدعاء دالة الاستدعاء الخاصة بالمستمع مع مرجع لكائن context كوسيط وحيد.

يمكن استخدام هذا بشكل أساسي لإعادة تهيئة سياق REPL إلى حالة مُحددة مسبقًا:

js
import repl from 'node:repl'

function initializeContext(context) {
  context.m = 'test'
}

const r = repl.start({ prompt: '> ' })
initializeContext(r.context)

r.on('reset', initializeContext)
js
const repl = require('node:repl')

function initializeContext(context) {
  context.m = 'test'
}

const r = repl.start({ prompt: '> ' })
initializeContext(r.context)

r.on('reset', initializeContext)

عند تنفيذ هذه الكود، يمكن تعديل المتغير العام 'm' ثم إعادة تعيينه إلى قيمته الأولية باستخدام الأمر .clear:

bash
$ ./node example.js
> m
'test'
> m = 1
1
> m
1
> .clear
Clearing context...
> m
'test'
>

replServer.defineCommand(keyword, cmd)

مضاف في: v0.3.0

  • keyword <string> كلمة الأمر (بدون حرف . رائد).
  • cmd <Object> | <Function> الدالة التي سيتم استدعائها عند معالجة الأمر.

تُستخدم طريقة replServer.defineCommand() لإضافة أوامر جديدة مُقدمة بـ . إلى مثيل REPL. يتم استدعاء هذه الأوامر عن طريق كتابة . متبوعًا بـ keyword. cmd إما دالة Function أو كائن Object مع الخصائص التالية:

  • help <string> نص المساعدة الذي سيتم عرضه عند إدخال .help (اختياري).
  • action <Function> الدالة التي سيتم تنفيذها، مع إمكانية قبول وسيطة سلسلة واحدة اختيارياً.

يُظهر المثال التالي أمرين جديدين تمت إضافتهما إلى مثيل REPL:

js
import repl from 'node:repl'

const replServer = repl.start({ prompt: '> ' })
replServer.defineCommand('sayhello', {
  help: 'Say hello',
  action(name) {
    this.clearBufferedCommand()
    console.log(`Hello, ${name}!`)
    this.displayPrompt()
  },
})
replServer.defineCommand('saybye', function saybye() {
  console.log('Goodbye!')
  this.close()
})
js
const repl = require('node:repl')

const replServer = repl.start({ prompt: '> ' })
replServer.defineCommand('sayhello', {
  help: 'Say hello',
  action(name) {
    this.clearBufferedCommand()
    console.log(`Hello, ${name}!`)
    this.displayPrompt()
  },
})
replServer.defineCommand('saybye', function saybye() {
  console.log('Goodbye!')
  this.close()
})

يمكن بعد ذلك استخدام الأوامر الجديدة من داخل مثيل REPL:

bash
> .sayhello Node.js User
Hello, Node.js User!
> .saybye
Goodbye!

replServer.displayPrompt([preserveCursor])

مضاف في: v0.1.91

تهيئ طريقة replServer.displayPrompt() مثيل REPL لإدخال من المستخدم، وطبع prompt المُهيأ في سطر جديد في output، واستئناف input لقبول إدخال جديد.

عند إدخال مدخلات متعددة الأسطر، يتم طباعة نقاط تعليق بدلاً من "prompt".

عندما تكون قيمة preserveCursor هي true، لن يتم إعادة تعيين موضع المؤشر إلى 0.

تُقصد طريقة replServer.displayPrompt في المقام الأول للاستدعاء من داخل دالة الإجراء للأوامر المسجلة باستخدام طريقة replServer.defineCommand().

replServer.clearBufferedCommand()

مضاف في: v9.0.0

تقوم طريقة replServer.clearBufferedCommand() بمسح أي أمر تم تخزينه مؤقتًا ولكن لم يتم تنفيذه بعد. تُقصد هذه الطريقة في المقام الأول للاستدعاء من داخل دالة الإجراء للأوامر المسجلة باستخدام طريقة replServer.defineCommand().

replServer.setupHistory(historyPath, callback)

مضاف في: v11.10.0

  • historyPath <string> المسار إلى ملف السجل.
  • callback <Function> يتم استدعاؤها عندما تكون كتابات السجل جاهزة أو عند حدوث خطأ

يقوم بتهيئة ملف سجل التاريخ لمثيل REPL. عند تنفيذ ملف Node.js الثنائي واستخدام REPL سطر الأوامر، يتم تهيئة ملف السجل افتراضيًا. ومع ذلك، هذا ليس هو الحال عند إنشاء REPL برمجيًا. استخدم هذه الطريقة لتهيئة ملف سجل التاريخ عند العمل مع مثيلات REPL برمجيًا.

repl.builtinModules

مضاف في: v14.5.0

قائمة بأسماء جميع وحدات Node.js، مثل 'http'.

repl.start([options])

[History]

الإصدارالتغييرات
v13.4.0، v12.17.0أصبح خيار preview متاحًا الآن.
v12.0.0يتبع خيار terminal الآن الوصف الافتراضي في جميع الحالات، وuseColors يتحقق من hasColors() إذا كان متاحًا.
v10.0.0تمت إزالة وضع REPL_MAGIC_MODE replMode.
v6.3.0أصبح خيار breakEvalOnSigint مدعومًا الآن.
v5.8.0أصبحت معلمة options اختيارية الآن.
v0.1.91تمت الإضافة في: v0.1.91
  • options <Object> | <string>

    • prompt <string> موجه الإدخال المراد عرضه. الافتراضي: '\> ' (مع مسافة في النهاية).

    • input <stream.Readable> تدفق Readable الذي سيتم قراءة إدخال REPL منه. الافتراضي: process.stdin.

    • output <stream.Writable> التدفق Writable الذي سيتم كتابة مخرجات REPL إليه. الافتراضي: process.stdout.

    • terminal <boolean> إذا كانت true، فإنها تحدد أن output يجب التعامل معها كمحطة طرفية TTY. الافتراضي: التحقق من قيمة خاصية isTTY على تدفق output عند إنشاء مثيل.

    • eval <Function> الدالة التي سيتم استخدامها عند تقييم كل سطر معين من الإدخال. الافتراضي: غلاف غير متزامن لدالة JavaScript eval() . يمكن أن تُحدث دالة eval خطأً باستخدام repl.Recoverable للإشارة إلى أن الإدخال كان غير مكتمل وطلب أسطر إضافية.

    • useColors <boolean> إذا كانت true، فإنها تحدد أن دالة writer الافتراضية يجب أن تتضمن أسلوب ألوان ANSI إلى مخرجات REPL. إذا تم توفير دالة writer مخصصة، فلن يكون لهذا أي تأثير. الافتراضي: التحقق من دعم الألوان على تدفق output إذا كانت قيمة terminal لمثيل REPL هي true.

    • useGlobal <boolean> إذا كانت true، فإنها تحدد أن دالة التقييم الافتراضية ستستخدم JavaScript global كسياق بدلاً من إنشاء سياق منفصل جديد لمثيل REPL. يقوم REPL الخاص بواجهة سطر أوامر العقدة بتعيين هذه القيمة على true. الافتراضي: false.

    • ignoreUndefined <boolean> إذا كانت true، فإنها تحدد أن الكاتب الافتراضي لن يُخرج قيمة الإرجاع لأمر ما إذا كان يُقيم على undefined. الافتراضي: false.

    • writer <Function> الدالة التي سيتم استدعاءها لتنسيق مخرجات كل أمر قبل الكتابة إلى output. الافتراضي: util.inspect().

    • completer <Function> دالة اختيارية تُستخدم لإكمال علامة التبويب التلقائي المخصص. راجع readline.InterfaceCompleter للحصول على مثال.

    • replMode <symbol> علم يُحدد ما إذا كانت وحدة التقييم الافتراضية تُنفذ جميع أوامر JavaScript في الوضع الصارم أم الوضع الافتراضي (الرخو). القيم المقبولة هي:

    • repl.REPL_MODE_SLOPPY لتقييم التعبيرات في الوضع الرخو.

    • repl.REPL_MODE_STRICT لتقييم التعبيرات في الوضع الصارم. هذا ما يعادل إضافة 'use strict' قبل كل بيان repl.

    • breakEvalOnSigint <boolean> إيقاف تقييم قطعة التعليمات البرمجية الحالية عند تلقي SIGINT، مثل عند الضغط على +. لا يمكن استخدام هذا مع دالة eval مخصصة. الافتراضي: false.

    • preview <boolean> يُحدد ما إذا كان repl يطبع معاينات الإكمال التلقائي والمخرجات أم لا. الافتراضي: true مع دالة التقييم الافتراضية وfalse في حالة استخدام دالة تقييم مخصصة. إذا كانت terminal خاطئة، فلا توجد معاينات وقيمة preview ليس لها أي تأثير.

  • الإرجاع: <repl.REPLServer>

إن طريقة repl.start() تُنشئ وتُشغل مثيلًا من repl.REPLServer.

إذا كانت options سلسلة، فإنها تحدد موجه الإدخال:

js
import repl from 'node:repl'

// موجه نمط يونكس
repl.start('$ ')
js
const repl = require('node:repl')

// موجه نمط يونكس
repl.start('$ ')

واجهة REPL في Node.js

تستخدم Node.js نفسها الوحدة النمطية node:repl لتوفير واجهة تفاعلية خاصة بها لتنفيذ JavaScript. يمكن استخدام هذا عن طريق تنفيذ ثنائي Node.js دون تمرير أي وسيطات (أو عن طريق تمرير الوسيط -i):

bash
$ node
> const a = [1, 2, 3];
undefined
> a
[ 1, 2, 3 ]
> a.forEach((v) => {
...   console.log(v);
...   });
1
2
3

خيارات متغيرات البيئة

يمكن تخصيص سلوكيات مختلفة لواجهة REPL في Node.js باستخدام متغيرات البيئة التالية:

  • NODE_REPL_HISTORY: عند تقديم مسار صالح، سيتم حفظ سجل REPL الدائم إلى الملف المحدد بدلاً من .node_repl_history في دليل المستخدم الرئيسي. سيؤدي تعيين هذه القيمة إلى '' (سلسلة فارغة) إلى تعطيل سجل REPL الدائم. سيتم اقتصاص المسافات البيضاء من القيمة. على أنظمة Windows، تكون متغيرات البيئة ذات القيم الفارغة غير صالحة، لذلك قم بتعيين هذا المتغير إلى مسافة واحدة أو أكثر لتعطيل سجل REPL الدائم.
  • NODE_REPL_HISTORY_SIZE: يتحكم في عدد أسطر السجل التي سيتم الاحتفاظ بها إذا كان السجل متاحًا. يجب أن يكون رقمًا موجبًا. الافتراضي: 1000.
  • NODE_REPL_MODE: يمكن أن يكون إما 'sloppy' أو 'strict'. الافتراضي: 'sloppy', والذي يسمح بتشغيل التعليمات البرمجية غير الصارمة.

السجل الدائم

بشكل افتراضي، ستحتفظ واجهة REPL في Node.js بالسجل بين جلسات REPL node عن طريق حفظ المدخلات في ملف .node_repl_history الموجود في دليل المستخدم الرئيسي. يمكن تعطيل هذا عن طريق تعيين متغير البيئة NODE_REPL_HISTORY=''.

استخدام واجهة REPL في Node.js مع محررات الأسطر المتقدمة

بالنسبة لمحررات الأسطر المتقدمة، قم بتشغيل Node.js باستخدام متغير البيئة NODE_NO_READLINE=1. سيؤدي هذا إلى بدء REPL الرئيسي و REPL الخاص بالمصحح في إعدادات طرفية قياسية، مما يسمح بالاستخدام مع rlwrap.

على سبيل المثال، يمكن إضافة ما يلي إلى ملف .bashrc:

bash
alias node="env NODE_NO_READLINE=1 rlwrap node"

بدء مثيلات REPL متعددة مقابل مثيل واحد قيد التشغيل

من الممكن إنشاء وتشغيل مثيلات REPL متعددة مقابل مثيل واحد قيد التشغيل من Node.js والتي تشترك في كائن global واحد ولكن لها واجهات I/O منفصلة.

يوفر المثال التالي، على سبيل المثال، REPLs منفصلة على stdin، ومقبس Unix، ومقبس TCP:

js
import net from 'node:net'
import repl from 'node:repl'
import process from 'node:process'

let connections = 0

repl.start({
  prompt: 'Node.js via stdin> ',
  input: process.stdin,
  output: process.stdout,
})

net
  .createServer(socket => {
    connections += 1
    repl
      .start({
        prompt: 'Node.js via Unix socket> ',
        input: socket,
        output: socket,
      })
      .on('exit', () => {
        socket.end()
      })
  })
  .listen('/tmp/node-repl-sock')

net
  .createServer(socket => {
    connections += 1
    repl
      .start({
        prompt: 'Node.js via TCP socket> ',
        input: socket,
        output: socket,
      })
      .on('exit', () => {
        socket.end()
      })
  })
  .listen(5001)
js
const net = require('node:net')
const repl = require('node:repl')
let connections = 0

repl.start({
  prompt: 'Node.js via stdin> ',
  input: process.stdin,
  output: process.stdout,
})

net
  .createServer(socket => {
    connections += 1
    repl
      .start({
        prompt: 'Node.js via Unix socket> ',
        input: socket,
        output: socket,
      })
      .on('exit', () => {
        socket.end()
      })
  })
  .listen('/tmp/node-repl-sock')

net
  .createServer(socket => {
    connections += 1
    repl
      .start({
        prompt: 'Node.js via TCP socket> ',
        input: socket,
        output: socket,
      })
      .on('exit', () => {
        socket.end()
      })
  })
  .listen(5001)

سيؤدي تشغيل هذا التطبيق من سطر الأوامر إلى بدء REPL على stdin. قد تتصل عملاء REPL أخرى من خلال مقبس Unix أو مقبس TCP. telnet، على سبيل المثال، مفيد للاتصال بمقابس TCP، بينما يمكن استخدام socat للاتصال بمقابس Unix و TCP على حد سواء.

من خلال بدء REPL من خادم قائم على مقبس Unix بدلاً من stdin، من الممكن الاتصال بعملية Node.js طويلة التشغيل دون إعادة تشغيلها.

لمعرفة مثال على تشغيل REPL "كاملة الميزات" (terminal) عبر مثيل net.Server و net.Socket، راجع: https://gist.github.com/TooTallNate/2209310.

لمعرفة مثال على تشغيل مثيل REPL عبر curl(1)، راجع: https://gist.github.com/TooTallNate/2053342.

يهدف هذا المثال لأغراض تعليمية بحتة لإظهار كيفية بدء REPLs في Node.js باستخدام تدفقات I/O مختلفة. يجب عدم استخدامه في بيئات الإنتاج أو أي سياق يكون فيه الأمن مصدر قلق دون اتخاذ تدابير وقائية إضافية. إذا كنت بحاجة إلى تنفيذ REPLs في تطبيق في العالم الحقيقي، ففكر في نهج بديلة تخفف من هذه المخاطر، مثل استخدام آليات إدخال آمنة وتجنب واجهات الشبكة المفتوحة.