Bagaimana cara memuat skrip saya ke dalam node.js REPL?

137

Saya memiliki skrip foo.jsyang berisi beberapa fungsi yang ingin saya mainkan di REPL.

Apakah ada cara agar simpul mengeksekusi skrip saya dan kemudian melompat ke REPL dengan semua global yang dinyatakan, seperti saya dapat dengan python -i foo.pyatau ghci foo.hs?

hugomg
sumber

Jawaban:

179

Masih belum ada built-in untuk memberikan fungsionalitas tepat yang Anda gambarkan. Namun, alternatif untuk menggunakannya requireuntuk menggunakan .loadperintah dalam REPL, seperti:

.load foo.js

Itu memuat file sejalan dengan baris sama seperti jika Anda mengetiknya di REPL. Tidak seperti requireini mencemari riwayat REPL dengan perintah yang Anda muat. Namun, ini memiliki keuntungan karena dapat diulang karena tidak di-cache seperti require.

Mana yang lebih baik untuk Anda akan tergantung pada use case Anda.


Sunting: Ini memiliki penerapan terbatas karena tidak bekerja dalam mode ketat, tetapi tiga tahun kemudian saya telah belajar bahwa jika skrip Anda tidak memiliki 'use strict', Anda dapat menggunakan evaluntuk memuat skrip Anda tanpa mencemari riwayat REPL:

var fs = require('fs');
eval(fs.readFileSync('foo.js').toString())
vossad01
sumber
Bagaimana jika saya ingin memasukkan callback async ke dalam balasan?
Chet
2
@Mari Anda menulis pertanyaan StackOverflow baru jika pertanyaan Anda tidak cocok dengan yang sudah ada :-)
vossad01
@Chet Anda dapat .load file lain dengan (async () => {lebih banyak kode}) (); dan itu akan berbagi global yang sama.
nurettin
Kiat jika Anda menggunakan MacOS (mungkin orang lain juga). Anda dapat mengetik ".load" (perhatikan spasi) ke dalam REPL dan seret / jatuhkan file ke Terminal dari Finder untuk menambahkan jalur yang benar ke perintah Anda. Ini berguna jika file yang sedang Anda kerjakan beberapa tingkat turun.
jamesnotjim
35

saya selalu menggunakan perintah ini

node -i -e "$(< yourScript.js)"

bekerja persis seperti di Python tanpa paket apa pun.

George Shalvashvili
sumber
1
apakah ada yang tahu cara membuatnya bekerja di windows cmd? Saya membuatnya bekerja di bash, tetapi tidak windows.
Sharpiro
@Sharpiro: Jika Anda menginstal Git maka Anda memiliki opsi untuk menginstal mini-UNIX ke PC Windows Anda. Maksudku distribusi normal Git untuk Windows.
Juan Lanus
Satu hal yang mengganggu tentang ini adalah Node.js akan mencetak prompt prompt dan kemudian menjalankan skrip Anda, sehingga setiap output macet setelah prompt. stackoverflow.com/a/45893494/3538165 tidak memiliki masalah ini tetapi untuk itu fungsi solusi harus ditugaskan secara eksplisit ke variabel untuk berakhir di namespace repl, jadi tidak terlalu bagus juga.
Radon Rosborough
10

Saya membuat Vorpal.js , yang menangani masalah ini dengan mengubah simpul Anda menjadi CLI interaktif. Ini mendukung ekstensi REPL, yang menjatuhkan Anda ke dalam REPL dalam konteks aplikasi Anda yang sedang berjalan.

var vorpal = require('vorpal')();
var repl = require('vorpal-repl');

vorpal
  .delimiter('myapp>')
  .use(repl)
  .show()
  .parse(process.argv); 

Kemudian Anda dapat menjalankan aplikasi dan itu akan jatuh ke dalam REPL.

$ node myapp.js repl
myapp> repl: 
dthree
sumber
8

Cara lain adalah mendefinisikan fungsi-fungsi tersebut sebagai global.

global.helloWorld = function() { console.log("Hello World"); }

Kemudian pramuat file dalam REPL sebagai:

node -r ./file.js

Maka fungsi tersebut helloWorlddapat diakses langsung di REPL.

Ashish Chaudhary
sumber
8

Saya membuat replpad karena saya bosan memuat ulang skrip berulang kali.

Cukup instal melalui: npm install -g replpad

Kemudian gunakan dengan menjalankan: replpad

Jika Anda ingin menonton semua file di subdirektori saat ini dan semua dan pipa ke repl ketika mereka berubah lakukan: replpad .

Lihat video di situs untuk mendapatkan ide yang lebih baik tentang cara kerjanya dan pelajari beberapa fitur bagus lainnya seperti ini:

  • mengakses modul inti dokumen dalam repl melalui dox()fungsi yang ditambahkan ke setiap fungsi inti, yaitufs.readdir.dox()
  • akses readmes modul pengguna di repl melalui dox()fungsi yang ditambahkan ke setiap modul yang diinstal melalui npm, yaitumarked.dox()
  • kode sumber yang disorot fungsi akses , info di mana fungsi didefinisikan (file, linenumber) dan komentar fungsi dan / atau jsdocs jika memungkinkan melalui srcproperti yang ditambahkan ke setiap fungsi, yaituexpress.logger.src
  • dukungan scriptie-talkie (lihat.talkperintah)
  • menambahkan perintah dan pintasan keyboard
  • binding kunci vim
  • dukungan peta kunci
  • pencocokan parens melalui plugin token pertandingan
  • menambahkan kode yang dimasukkan sebagai balasan kembali ke file melalui pintasan atau .appendperintah keyboard

Lihat: https://github.com/thlorenz/replpad

Thorsten Lorenz
sumber
Saya harus CXX=clang++ npm install replpadmengatasi kesalahang++: error: unrecognized command line option '-stdlib=libc++'
ShadSterling
Tapi kemudian ketika saya menjalankannya gagal dengan# # Fatal error in ../deps/v8/src/api.cc, line 1248 # Check failed: !value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(). # Illegal instruction: 4
ShadSterling
5

Mengapa tidak memuat file ke repl node interaktif?

node -h
-e, --eval script          evaluate script
-i, --interactive          always enter the REPL even if stdin

node -e 'var client = require("./build/main/index.js"); console.log("Use `client` in repl")' -i

Kemudian Anda bisa menambahkan ke script package.json

"repl": "node -e 'var client = require(\"./build/main/index.js\"); console.log(\"Use `client` in repl\")' -i",

diuji menggunakan simpul v8.1.2

lfender6445
sumber
2
kenapa tidak adil node -i -r "./build/main/index.js"?
Z. Khullah
4

Saat ini Anda tidak bisa melakukan itu secara langsung, tetapi Anda bisa mylib = require('./foo.js')di REPL. Ingat metode diekspor, tidak dinyatakan sebagai global.

Ricardo Tomasi
sumber
Saya menemukan ini lebih disukai .load my_work.js, meskipun memerlukan beberapa exports.working_var = ...deklarasi tambahan , karena REPL muntah pada beberapa jenis javascript yang benar-benar valid, seperti komentar multiline (setidaknya dengan readlinekonfigurasi saya ).
chbrown
4

replpad itu keren, tetapi untuk cara cepat dan mudah memuat file ke dalam simpul, mengimpor variabel-variabelnya dan memulai repl, Anda dapat menambahkan kode berikut ke akhir file .js Anda

if (require.main === module){
    (function() {
        var _context = require('repl').start({prompt: '$> '}).context;
        var scope = require('lexical-scope')(require('fs').readFileSync(__filename));
        for (var name in scope.locals[''] )
            _context[scope.locals[''][name]] = eval(scope.locals[''][name]);
        for (name in scope.globals.exported)
            _context[scope.globals.exported[name]] = eval(scope.globals.exported[name]);
    })();
}

Sekarang jika file Anda src.js, menjalankan node src.jsakan memulai node, memuat file, memulai REPL, dan menyalin semua objek yang dinyatakan sebagai vardi tingkat atas serta semua global yang diekspor. The if (require.main === module)memastikan bahwa kode ini tidak akan dieksekusi jika src.jsdisertakan melalui requirepernyataan. Sebenarnya, Anda dapat menambahkan kode apa pun yang ingin dikecualikan saat menjalankan src.jsmandiri untuk keperluan debugging di dalam ifpernyataan.

pengguna1936097
sumber
4

Inilah versi fungsi bash dari jawaban George :

noderepl() {
    FILE_CONTENTS="$(< $1 )"
    node -i -e "$FILE_CONTENTS"
}

Jika Anda memasukkan ini ke dalam Anda, ~/.bash_profileAnda dapat menggunakannya seperti alias, yaitu:

noderepl foo.js
Eliot
sumber
2
Saya telah menggunakan ini selama berbulan-bulan sekarang, dan dalam transisi ke lingkungan shell baru saya kehilangan beberapa pengaturan saya dan harus melacak ini kembali. Jadi sejak saya di sini, saya pikir saya akan berterima kasih atas fungsi yang sangat berguna ini.
Xaekai
3

Saran lain yang tidak saya lihat di sini: coba sedikit kode ini

#!/usr/bin/env node
'use strict';

const repl = require('repl');
const cli = repl.start({ replMode: repl.REPL_MODE_STRICT });
cli.context.foo = require('./foo'); // injects it into the repl

Kemudian Anda cukup menjalankan skrip ini dan itu akan dimasukkan foosebagai variabel

jelas
sumber
1

Jawaban lama

type test.js|node -i

Akan membuka simpul REPL dan mengetikkan semua baris dari test.js ke dalam REPL, tetapi untuk beberapa alasan simpul akan berhenti setelah file berakhir

Masalah lainnya adalah, bahwa fungsi tidak akan diangkat.

Jawaban yang lebih baik

node -e require('repl').start({useGlobal:true}); -r ./test2.js

Kemudian semua global yang dinyatakan tanpa var di dalam test2.js akan tersedia di REPL

tidak yakin mengapa var a dalam lingkup global tidak akan tersedia

Yahudi
sumber
8
Silakan tambahkan beberapa penjelasan pada jawaban Anda
mechnicov