Wie lade ich mein Skript in die REPL von node.js?

137

Ich habe ein Skript foo.js, das einige Funktionen enthält, mit denen ich in der REPL spielen möchte.

Gibt es eine Möglichkeit, dass Node mein Skript ausführt und dann mit allen deklarierten Globals in eine REPL springt, wie ich es mit python -i foo.pyoder kann ghci foo.hs?

Hugomg
quelle

Antworten:

179

Es ist immer noch nichts eingebaut, um die genaue Funktionalität bereitzustellen, die Sie beschreiben. Eine Alternative zur Verwendung require, um den .loadBefehl in der REPL zu verwenden, wie z.

.load foo.js

Es lädt die Datei zeilenweise so, als hätten Sie sie in die REPL eingegeben. Im Gegensatz requiredazu verschmutzt der REPL-Verlauf mit den von Ihnen geladenen Befehlen. Es hat jedoch den Vorteil, dass es wiederholbar ist, da es nicht wie zwischengespeichert ist require.

Was für Sie besser ist, hängt von Ihrem Anwendungsfall ab.


Edit: Es begrenzte Anwendbarkeit hat , weil es keine Arbeit im Strict - Modus der Fall ist, aber drei Jahre später habe ich gelernt , dass , wenn Ihr Skript nicht 'use strict', können Sie verwenden evaldas Skript zu laden , um ohne die REPL Geschichte zu verschmutzen:

var fs = require('fs');
eval(fs.readFileSync('foo.js').toString())
vossad01
quelle
Was ist, wenn ich innerhalb eines asynchronen Rückrufs in die Antwort einfügen möchte?
Chet
2
@Chet Sie schreiben eine neue StackOverflow-Frage, wenn Ihre Frage nicht mit einer vorhandenen übereinstimmt :-)
vossad01
@Chet können Sie eine andere Datei mit (async () => {more code}) () laden; und es wird die gleichen globalen teilen.
Nurettin
Tipp, wenn Sie mit macOS arbeiten (vielleicht auch mit anderen). Sie können ".load" (beachten Sie das Leerzeichen) in die REPL eingeben und die Datei aus dem Finder in das Terminal ziehen / ablegen, um den richtigen Pfad zu Ihrem Befehl hinzuzufügen. Dies ist praktisch, wenn die Dateien, mit denen Sie arbeiten, mehrere Ebenen tiefer liegen.
Jamesnotjim
35

Ich benutze immer diesen Befehl

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

funktioniert genau wie in Python ohne Pakete.

George Shalvashvili
quelle
1
Weiß jemand, wie man dies in Windows Cmd zum Laufen bringt? Ich habe es in Bash zum Laufen gebracht, aber nicht in Windows.
Sharpiro
@ Sharpiro: Wenn Sie Git installieren, haben Sie die Möglichkeit, ein Mini-UNIX auf Ihrem Windows-PC zu installieren. Ich meine Git's normale Distribution für Windows.
Juan Lanus
Das einzige, was daran nervt, ist, dass Node.js die Repl-Eingabeaufforderung druckt und dann Ihr Skript ausführt , sodass alle Ausgaben nach der Eingabeaufforderung hängen bleiben. stackoverflow.com/a/45893494/3538165 hat dieses Problem nicht, aber dafür müssen Lösungsfunktionen explizit Variablen zugewiesen werden, um im Repl-Namespace zu landen, also auch nicht sehr gut.
Radon Rosborough
10

Ich habe Vorpal.js erstellt , das dieses Problem löst , indem Ihr Knoten in eine interaktive CLI umgewandelt wird. Es unterstützt eine REPL-Erweiterung, mit der Sie im Kontext Ihrer laufenden App in eine REPL versetzt werden.

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

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

Dann können Sie die App ausführen und sie wird in eine REPL eingefügt.

$ node myapp.js repl
myapp> repl: 
drei
quelle
8

Eine andere Möglichkeit besteht darin, diese Funktionen als global zu definieren.

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

Laden Sie dann die Datei in der REPL wie folgt vor:

node -r ./file.js

Dann helloWorldkann direkt in der REPL auf die Funktion zugegriffen werden.

Ashish Chaudhary
quelle
8

Ich habe ein Replpad erstellt, da ich es satt hatte, das Skript wiederholt neu zu laden .

Einfach installieren über: npm install -g replpad

Verwenden Sie es dann, indem Sie Folgendes ausführen: replpad

Wenn Sie möchten, dass alle Dateien im aktuellen und in allen Unterverzeichnissen überwacht und bei Änderungen in die Repl-Datei übertragen werden, gehen Sie wie folgt vor: replpad .

Schauen Sie sich die Videos auf der Website an, um eine bessere Vorstellung davon zu bekommen, wie es funktioniert, und lernen Sie einige andere nette Funktionen kennen, die es wie diese hat:

  • Greifen Sie über die dox()Funktion, die jeder Kernfunktion hinzugefügt wird, auf die Dokumente des Kernmoduls in der Replfs.readdir.dox()
  • Greifen Sie über die dox()Funktion, die jedem über npm installierten Modul hinzugefügt wird, auf die Readmes des Benutzermoduls in der Antwort zumarked.dox()
  • Zugriff auf den hervorgehobenen Quellcode der Funktion , Informationen darüber, wo die Funktion definiert wurde (Datei, Leinenzahl) und Funktionskommentare und / oder jsdocs, sofern möglich, über die srcEigenschaft, die jeder Funktion hinzugefügt wird, d. hexpress.logger.src
  • Scriptie-Talkie- Unterstützung (siehe.talkBefehl)
  • Fügt Befehle und Tastaturkürzel hinzu
  • vim Schlüsselbindungen
  • Unterstützung für Schlüsselkarten
  • Parens Matching über Match Token Plugin
  • Hängt den in repl eingegebenen Code über eine Tastenkombination oder einen .appendBefehl wieder an die Datei an

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

Thorsten Lorenz
quelle
Ich musste CXX=clang++ npm install replpadden Fehler g++: error: unrecognized command line option '-stdlib=libc++'
umgehen
Aber wenn ich es dann # # Fatal error in ../deps/v8/src/api.cc, line 1248 # Check failed: !value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(). # Illegal instruction: 4
starte,
5

Warum nicht die Datei in eine interaktive Knotenreplikation laden?

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

Dann können Sie package.json-Skripte hinzufügen

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

getestet mit Knoten v8.1.2

lfender6445
quelle
2
warum nicht einfach node -i -r "./build/main/index.js"?
Z. Khullah
4

Derzeit können Sie das nicht direkt tun, aber Sie können mylib = require('./foo.js')in der REPL. Denken Sie daran, dass Methoden exportiert und nicht als global deklariert werden.

Ricardo Tomasi
quelle
Ich finde dies vorzuziehen .load my_work.js, obwohl einige zusätzliche exports.working_var = ...Deklarationen erforderlich sind , da die REPL einige Arten von perfekt gültigem Javascript wie mehrzeilige Kommentare (zumindest bei meiner readlineKonfiguration) blockiert .
Chbrown
4

replpad ist cool, aber für eine schnelle und einfache Möglichkeit, eine Datei in einen Knoten zu laden, ihre Variablen zu importieren und eine Replikation zu starten, können Sie den folgenden Code am Ende Ihrer .js-Datei hinzufügen

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]);
    })();
}

Wenn Ihre Datei nun ausgeführt wird src.js, node src.jswird der Knoten gestartet, die Datei geladen, eine REPL gestartet und alle als varoberste Ebene deklarierten Objekte sowie alle exportierten Globals kopiert. Die if (require.main === module)sorgt dafür , dass dieser Code nicht ausgeführt werden , wenn src.jsdurch eine inbegriffene requireErklärung. Tatsächlich können Sie jeden Code hinzufügen, der ausgeführt werden soll, wenn Sie src.jseigenständig zu Debugging-Zwecken innerhalb der ifAnweisung ausgeführt werden.

user1936097
quelle
4

Hier ist eine Bash-Funktionsversion von Georges Antwort :

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

Wenn Sie dies in Ihr ~/.bash_profileeingeben, können Sie es wie einen Alias ​​verwenden, dh:

noderepl foo.js
Eliot
quelle
2
Ich benutze dies seit Monaten und beim Übergang zu einer neuen Shell-Umgebung habe ich einige meiner Einstellungen verloren und musste dies wieder aufspüren. Da ich hier bin, dachte ich, ich würde mich bei Ihnen für diese wirklich nützliche Funktion bedanken.
Xaekai
3

Ein weiterer Vorschlag, den ich hier nicht sehe: Probieren Sie dieses kleine Stück Code aus

#!/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

Dann können Sie dieses Skript einfach ausführen und es wird fooals Variable enthalten

corvid
quelle
1

Alte Antwort

type test.js|node -i

Öffnet den Knoten REPL und gibt alle Zeilen von test.js in REPL ein. Aus irgendeinem Grund wird der Knoten jedoch nach dem Ende der Datei beendet

Ein weiteres Problem ist, dass Funktionen nicht gehisst werden.

Bessere Antwort

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

Dann sind alle in var2.2.s ohne var deklarierten Globals in der REPL verfügbar

Ich bin mir nicht sicher, warum var a im globalen Bereich nicht verfügbar ist

Jude
quelle
8
Bitte fügen Sie einige Erklärungen zu Ihrer Antwort hinzu
mechnicov