Come posso caricare il mio script nel REPL node.js?


137

Ho uno script foo.jsche contiene alcune funzioni con cui voglio giocare nel REPL.

C'è un modo per fare in modo che il nodo esegua il mio script e poi salti in un REPL con tutti i globali dichiarati, come posso fare con python -i foo.pyo ghci foo.hs?

Risposte:


179

Non c'è ancora nulla di integrato per fornire la funzionalità esatta che descrivi. Tuttavia, un'alternativa all'utilizzo requireper utilizzare il .loadcomando all'interno del REPL, come tale:

.load foo.js

Carica il file riga per riga proprio come se fosse stato digitato nel REPL. Diversamente da requireciò, inquina la cronologia REPL con i comandi caricati. Tuttavia, ha il vantaggio di essere ripetibile perché non è memorizzato nella cache require.

Quale è meglio per te dipenderà dal tuo caso d'uso.


Modifica: ha un'applicabilità limitata perché non funziona in modalità rigorosa, ma tre anni dopo ho imparato che se lo script non ha 'use strict', è possibile utilizzare evalper caricare lo script senza inquinare la cronologia REPL:

var fs = require('fs');
eval(fs.readFileSync('foo.js').toString())

Che cosa succede se desidero inserire il sostituto all'interno di un callback asincrono?
Chet

2
@Chet Scrivi una nuova domanda StackOverflow se la tua domanda non corrisponde a una esistente :-)
vossad01

@Chet puoi caricare un altro file con (async () => {altro codice}) (); e condividerà gli stessi globi.
Nurettin,

Suggerimento se sei su macOS (forse anche altri). È possibile digitare ".load" (notare lo spazio) nel REPL e trascinare / rilasciare il file nel Terminale dal Finder per aggiungere il percorso corretto al comando. Questo è utile se i file con cui stai lavorando sono di diversi livelli.
jamesnotjim,

35

uso sempre questo comando

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

funziona esattamente come in Python senza pacchetti.


1
qualcuno sa come farlo funzionare in Windows cmd? L'ho fatto funzionare in bash, ma non in Windows.
Sharpiro,

@Sharpiro: se installi Git, hai la possibilità di installare un mini-UNIX sul tuo PC Windows. Intendo la normale distribuzione di Git per Windows.
Juan Lanus,

L'unica cosa fastidiosa di questo è Node.js stamperà il prompt di sostituzione e quindi eseguirà lo script, quindi qualsiasi output verrà bloccato dopo il prompt. stackoverflow.com/a/45893494/3538165 non presenta questo problema, ma per quella soluzione le funzioni devono essere assegnate in modo esplicito alle variabili per finire nello spazio dei nomi di sostituzione, quindi neanche molto bene.
Radon Rosborough,

10

Ho creato Vorpal.js , che gestisce questo problema trasformando il tuo nodo in un'interfaccia della riga di comando interattiva. Supporta un'estensione REPL, che ti porta in una REPL nel contesto dell'app in esecuzione.

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

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

Quindi è possibile eseguire l'app e verrà rilasciata in una REPL.

$ node myapp.js repl
myapp> repl: 

8

Un altro modo è definire quelle funzioni come globali.

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

Quindi precaricare il file nella REPL come:

node -r ./file.js

Quindi è helloWorldpossibile accedere alla funzione direttamente nel REPL.


8

Ho creato replpad da quando mi sono stancato di ricaricare ripetutamente lo script.

Basta installarlo tramite: npm install -g replpad

Quindi usalo eseguendo: replpad

Se vuoi che guardi tutti i file nelle sottodirectory correnti e in tutte e li installi nella sostituzione quando cambiano fai: replpad .

Guarda i video sul sito per avere un'idea migliore di come funziona e conoscere alcune altre belle funzionalità che ha come queste:

  • accedere ai documenti del modulo principale nella sostituzione tramite la dox()funzione aggiunta a ogni funzione principale, ad esfs.readdir.dox()
  • accedere ai readme del modulo utente nella sostituzione tramite la dox()funzione che viene aggiunta a ogni modulo installato tramite npm, ad esmarked.dox()
  • accedi al codice sorgente evidenziato della funzione , informazioni su dove è stata definita la funzione (file, lino) e commenti funzione e / o jsdocs ove possibile tramite la srcproprietà che viene aggiunta a ogni funzione, ad es.express.logger.src
  • supporto per scriptie-talkie (vedi.talkcomando)
  • aggiunge comandi e scorciatoie da tastiera
  • collegamenti chiave vim
  • supporto per mappe chiave
  • corrispondenza di parens tramite plug-in token di corrispondenza
  • accoda il codice inserito in sostituirlo al file tramite scorciatoia da tastiera o .appendcomando

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


Ho dovuto CXX=clang++ npm install replpadaggirare l'erroreg++: error: unrecognized command line option '-stdlib=libc++'
ShadSterling

Ma poi quando lo # # Fatal error in ../deps/v8/src/api.cc, line 1248 # Check failed: !value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(). # Illegal instruction: 4
eseguo

5

Perché non caricare il file in un nodo interattivo sostitutivo?

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

Quindi è possibile aggiungere agli script package.json

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

testato usando il nodo v8.1.2


2
perché non solo node -i -r "./build/main/index.js"?
Z. Khullah,

4

Attualmente non puoi farlo direttamente, ma puoi farlo mylib = require('./foo.js')nel REPL. Ricorda che i metodi vengono esportati, non dichiarati come globali.


Trovo che sia preferibile farlo .load my_work.js, nonostante richiedano alcune exports.working_var = ...dichiarazioni aggiuntive , perché REPL barfa su alcuni tipi di javascript perfettamente validi, come i commenti multilinea (almeno con la mia readlineconfigurazione).
chbrown

4

replpad è interessante, ma per un modo semplice e veloce di caricare un file nel nodo, importare le sue variabili e avviare un sostituto, è possibile aggiungere il seguente codice alla fine del file .js

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

Ora, se il tuo file è src.js, l'esecuzione node src.jsavvia il nodo, carica il file, avvia una REPL e copia tutti gli oggetti dichiarati come vardi livello superiore e tutti i globi esportati. Le if (require.main === module)assicura che questo codice non verrà eseguito se src.jsè incluso attraverso un requirecomunicato. In effetti, è possibile aggiungere qualsiasi codice che si desidera essere escluso quando si esegue src.jsautonomamente per scopi di debug all'interno dell'istruzione if.


4

Ecco una versione della funzione bash della risposta di George :

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

Se lo metti nel tuo ~/.bash_profilepuoi usarlo come un alias, cioè:

noderepl foo.js

2
Lo sto usando da mesi ormai, e in una transizione verso un nuovo ambiente shell ho perso alcune delle mie impostazioni e ho dovuto rintracciarlo di nuovo. Quindi, dato che sono qui, ho pensato di ringraziarti per questa funzione davvero utile.
Xaekai,

3

Un altro suggerimento che non vedo qui: prova questo po 'di codice

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

Quindi puoi semplicemente eseguire questo script e includerà foocome variabile


1

Vecchia risposta

type test.js|node -i

Aprirà il nodo REPL e digiterà tutte le righe da test.js in REPL, ma per qualche ragione il nodo si chiuderà al termine del file

Un altro problema è che le funzioni non verranno sollevate.

Risposta migliore

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

Quindi tutti i globali dichiarati senza var all'interno di test2.js saranno disponibili nel REPL

non so perché var a nell'ambito globale non sarà disponibile


8
Per favore, aggiungi qualche spiegazione alla tua risposta
mechnicov
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.