¿Cómo cargo mi script en el REPL de node.js?

137

Tengo un script foo.jsque contiene algunas funciones con las que quiero jugar en REPL.

¿Hay alguna manera de que el nodo ejecute mi script y luego salte a un REPL con todos los globales declarados, como puedo con python -i foo.pyo ghci foo.hs?

hugomg
fuente

Respuestas:

179

Todavía no hay nada incorporado para proporcionar la funcionalidad exacta que describe. Sin embargo, una alternativa a usarlo requirepara usar el .loadcomando dentro de REPL, como tal:

.load foo.js

Carga el archivo en línea por línea como si lo hubiera escrito en REPL. A diferencia de requireesto contamina la historia REPL con los comandos que ha cargado. Sin embargo, tiene la ventaja de ser repetible porque no se almacena en caché como require.

Lo que sea mejor para usted dependerá de su caso de uso.


Editar: tiene una aplicabilidad limitada porque no funciona en modo estricto, pero tres años después supe que si su script no tiene 'use strict', puede usarlo evalpara cargar su script sin contaminar el historial REPL:

var fs = require('fs');
eval(fs.readFileSync('foo.js').toString())
vossad01
fuente
¿Qué sucede si deseo ingresar a la respuesta dentro de una devolución de llamada asíncrona?
Chet
2
@Chet Usted escribe una nueva pregunta de StackOverflow si su pregunta no coincide con una existente :-)
vossad01
@Chet puede .load otro archivo con (async () => {more code}) (); y compartirá los mismos globales.
nurettin
Consejo si estás en macOS (tal vez otros también). Puede escribir ".load" (observe el espacio) en el REPL y arrastre / suelte el archivo en la Terminal desde el Finder para agregar la ruta correcta a su comando. Esto es útil si los archivos con los que está trabajando están varios niveles abajo.
jamesnotjim
35

siempre uso este comando

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

funciona exactamente como en Python sin ningún paquete.

George Shalvashvili
fuente
1
¿Alguien sabe cómo hacer que esto funcione en Windows cmd? Lo tengo funcionando en bash, pero no en windows.
Sharpiro
@Sharpiro: Si instala Git, entonces tiene la opción de instalar un mini-UNIX en su PC con Windows. Me refiero a la distribución normal de Git para Windows.
Juan Lanus
Lo único que es molesto sobre esto es que Node.js imprimirá la solicitud de respuesta y luego ejecutará su script, por lo que cualquier salida se atascará después de la solicitud. stackoverflow.com/a/45893494/3538165 no tiene este problema, pero para esa solución, las funciones deben asignarse explícitamente a las variables para terminar en el espacio de nombres de respuesta, por lo que tampoco es muy bueno.
Radón Rosborough
10

Hice Vorpal.js , que maneja este problema al convertir su nodo en una CLI interactiva. Admite una extensión REPL, que lo coloca en un REPL dentro del contexto de su aplicación en ejecución.

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

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

Luego puede ejecutar la aplicación y se colocará en una REPL.

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

Otra forma es definir esas funciones como globales.

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

Luego precargue el archivo en REPL como:

node -r ./file.js

Entonces helloWorldse puede acceder a la función directamente en REPL.

Ashish Chaudhary
fuente
8

He creado replpad ya me cansé de volver a cargar el script de forma repetida.

Simplemente instálelo a través de: npm install -g replpad

Luego úselo ejecutando: replpad

Si desea ver todos los archivos en el actual y todos los subdirectorios y canalizarlos en la respuesta cuando cambian, haga lo siguiente: replpad .

Echa un vistazo a los videos en el sitio para tener una mejor idea de cómo funciona y conocer algunas otras características interesantes que tiene como estas:

  • acceder a los documentos del módulo principal en la respuesta a través de la dox()función que se agrega a cada función principal, es decirfs.readdir.dox()
  • acceda a los readme del módulo de usuario en la respuesta a través de la dox()función que se agrega a cada módulo instalado a través de npm, es decirmarked.dox()
  • acceder al código fuente resaltado de la función , información sobre dónde se definió la función (archivo, número de lino) y comentarios de la función y / o jsdocs cuando sea posible a través de la srcpropiedad que se agrega a cada función, es decirexpress.logger.src
  • Scriptie-talkie de apoyo (ver.talkcomandos)
  • agrega comandos y atajos de teclado
  • enlaces de teclas vim
  • soporte de mapa clave
  • Parens coincidentes a través del complemento token de coincidencia
  • agrega el código ingresado en la respuesta al archivo a través del atajo de teclado o .appendcomando

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

Thorsten Lorenz
fuente
Tuve que CXX=clang++ npm install replpadg++: error: unrecognized command line option '-stdlib=libc++'
solucionar
Pero luego cuando lo ejecuto falla# # Fatal error in ../deps/v8/src/api.cc, line 1248 # Check failed: !value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(). # Illegal instruction: 4
ShadSterling
5

¿Por qué no cargar el archivo en un nodo interactivo repl?

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

Luego puede agregar a los scripts package.json

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

probado usando el nodo v8.1.2

lfender6445
fuente
2
¿Por qué no solo node -i -r "./build/main/index.js"?
Z. Khullah
4

Actualmente no puede hacerlo directamente, pero puede hacerlo mylib = require('./foo.js')en REPL. Recuerde que los métodos se exportan, no se declaran como globales.

Ricardo Tomasi
fuente
Encuentro esto preferible a .load my_work.js, a pesar de requerir algunas exports.working_var = ...declaraciones adicionales , porque REPL no acepta algunos tipos de javascript perfectamente válidos, como comentarios de varias líneas (al menos con mi readlineconfiguración).
chbrown
4

replpad es genial, pero para una manera rápida y fácil de cargar un archivo en el nodo, importar sus variables e iniciar una respuesta, puede agregar el siguiente código al final de su archivo .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]);
    })();
}

Ahora, si su archivo está en src.jsejecución, node src.jsse iniciará el nodo, cargará el archivo, iniciará un REPL y copiará todos los objetos declarados como varen el nivel superior, así como cualquier global exportado. Esto if (require.main === module)asegura que este código no se ejecutará si src.jsse incluye a través de una requiredeclaración. De hecho, puede agregar cualquier código que desee que se ejecute cuando se ejecuta de forma src.jsindependiente con fines de depuración dentro de la ifdeclaración.

usuario1936097
fuente
4

Aquí hay una versión de la función bash de la respuesta de George :

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

Si pone esto en su ~/.bash_profilepuede usarlo como un alias, es decir:

noderepl foo.js
Eliot
fuente
2
He estado usando esto durante meses, y en una transición a un nuevo entorno de shell, perdí algunos de mis ajustes y tuve que rastrearlo nuevamente. Entonces, como estoy aquí, pensé que agradecería esta función realmente útil.
Xaekai
3

Otra sugerencia que no veo aquí: prueba este pequeño código

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

Luego, simplemente puede ejecutar este script e incluirá foocomo una variable

corvid
fuente
1

Vieja respuesta

type test.js|node -i

Abrirá el nodo REPL y escribirá todas las líneas de test.js en REPL, pero por alguna razón el nodo se cerrará cuando finalice el archivo

Otro problema es que las funciones no se izarán.

Mejor respuesta

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

Entonces, todos los globales declarados sin var dentro de test2.js estarán disponibles en el REPL

no estoy seguro de por qué var a en el ámbito global no estará disponible

judío
fuente
8
Por favor, añadir un poco de explanaton a su respuesta
mechnicov