Comment charger mon script dans le REPL node.js?

137

J'ai un script foo.jsqui contient certaines fonctions avec lesquelles je veux jouer dans le REPL.

Existe-t-il un moyen pour que node exécute mon script, puis saute dans une REPL avec tous les globaux déclarés, comme je peux avec python -i foo.pyou ghci foo.hs?

hugomg
la source

Réponses:

179

Il n'y a toujours rien de intégré pour fournir la fonctionnalité exacte que vous décrivez. Cependant, une alternative à son utilisation requirepour utiliser la .loadcommande dans le REPL, comme ceci:

.load foo.js

Il charge le fichier ligne par ligne comme si vous l'aviez tapé dans la REPL. Contrairement à requirecela, pollue l'historique REPL avec les commandes que vous avez chargées. Cependant, il a l'avantage d'être répétable car il n'est pas mis en cache comme require.

Ce qui est le mieux pour vous dépendra de votre cas d'utilisation.


Edit: Il a une applicabilité limitée car il ne fonctionne pas en mode strict, mais trois ans plus tard, j'ai appris que si votre script ne l'a pas 'use strict', vous pouvez l' utiliser evalpour charger votre script sans polluer l'historique REPL:

var fs = require('fs');
eval(fs.readFileSync('foo.js').toString())
vossad01
la source
Que faire si je veux passer dans le repl à l'intérieur d'un rappel asynchrone?
Chet
2
@Chet Vous rédigez une nouvelle question StackOverflow si votre question ne correspond pas à une question existante :-)
vossad01
@Chet vous pouvez charger un autre fichier avec (async () => {plus de code}) (); et il partagera les mêmes globaux.
nurettin le
Astuce si vous êtes sur macOS (peut-être d'autres aussi). Vous pouvez taper ".load" (notez l'espace) dans le REPL et faire glisser / déposer le fichier dans le terminal à partir du Finder pour ajouter le chemin correct à votre commande. Ceci est pratique si les fichiers avec lesquels vous travaillez sont de plusieurs niveaux inférieurs.
jamesnotjim
35

j'utilise toujours cette commande

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

fonctionne exactement comme en Python sans aucun paquet.

George Shalvashvili
la source
1
est-ce que quelqu'un sait comment faire fonctionner cela dans Windows cmd? Je l'ai fait fonctionner dans bash, mais pas sous Windows.
Sharpiro
@Sharpiro: Si vous installez Git, vous avez la possibilité d'installer un mini-UNIX sur votre PC Windows. Je veux dire la distribution normale de Git pour Windows.
Juan Lanus
La seule chose qui est ennuyeuse à ce sujet est que Node.js imprimera l'invite repl et exécutera ensuite votre script, de sorte que toute sortie restera bloquée après l'invite. stackoverflow.com/a/45893494/3538165 n'a pas ce problème mais pour cette solution, les fonctions doivent être affectées explicitement aux variables pour se retrouver dans l'espace de noms repl, donc pas très bon non plus.
Radon Rosborough le
10

J'ai créé Vorpal.js , qui gère ce problème en transformant l'ajout de votre nœud en une CLI interactive. Il prend en charge une extension REPL, qui vous place dans une REPL dans le contexte de votre application en cours d'exécution.

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

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

Ensuite, vous pouvez exécuter l'application et elle tombera dans une REPL.

$ node myapp.js repl
myapp> repl: 
trois
la source
8

Une autre façon est de définir ces fonctions comme globales.

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

Ensuite, préchargez le fichier dans le REPL comme:

node -r ./file.js

Ensuite, la fonction helloWorldest accessible directement dans le REPL.

Ashish Chaudhary
la source
8

J'ai créé replpad car j'étais fatigué de recharger le script à plusieurs reprises.

Installez-le simplement via: npm install -g replpad

Ensuite, utilisez-le en exécutant: replpad

Si vous voulez qu'il surveille tous les fichiers dans le sous-répertoire courant et tous les sous-répertoires et les redirige vers le repl lorsqu'ils changent, faites: replpad .

Regardez les vidéos sur le site pour avoir une meilleure idée de son fonctionnement et découvrez quelques autres fonctionnalités intéressantes comme celles-ci:

  • accéder à la documentation du module principal dans le repl via la dox()fonction qui est ajoutée à chaque fonction principale, c'est-à-direfs.readdir.dox()
  • accéder aux readmes du module utilisateur dans le repl via la dox()fonction qui est ajoutée à chaque module installé via npm, iemarked.dox()
  • accéder au code source de la fonction en surbrillance , aux informations sur l' endroit où la fonction a été définie (fichier, numéro de ligne) et aux commentaires de fonction et / ou jsdocs lorsque cela est possible via la srcpropriété qui est ajoutée à chaque fonction, c'est-à-direexpress.logger.src
  • prise en charge de scriptie-talkie (voir.talkcommande)
  • ajoute des commandes et des raccourcis clavier
  • raccourcis clavier vim
  • support de carte clé
  • parens correspondant via le plugin de jeton de correspondance
  • ajoute le code entré dans repl au fichier via un raccourci clavier ou une .appendcommande

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

Thorsten Lorenz
la source
Je devais CXX=clang++ npm install replpadcontourner l'erreurg++: error: unrecognized command line option '-stdlib=libc++'
ShadSterling
Mais ensuite, quand je l'exécute, cela échoue avec# # Fatal error in ../deps/v8/src/api.cc, line 1248 # Check failed: !value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(). # Illegal instruction: 4
ShadSterling
5

Pourquoi ne pas charger le fichier dans un nœud interactif 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

Ensuite, vous pouvez ajouter des scripts package.json

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

testé avec le nœud v8.1.2

lfender6445
la source
2
pourquoi pas juste node -i -r "./build/main/index.js"?
Z. Khullah
4

Actuellement, vous ne pouvez pas le faire directement, mais vous pouvez le faire mylib = require('./foo.js')dans le REPL. N'oubliez pas que les méthodes sont exportées et non déclarées comme globales.

Ricardo Tomasi
la source
Je trouve cela préférable .load my_work.js, malgré la nécessité de quelques exports.working_var = ...déclarations supplémentaires , car le REPL barfs sur certains types de javascript parfaitement valides, comme les commentaires multilignes (au moins avec ma readlineconfiguration).
chbrown
4

replpad c'est cool, mais pour un moyen rapide et facile de charger un fichier dans un nœud, d'importer ses variables et de démarrer un repl, vous pouvez ajouter le code suivant à la fin de votre fichier .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]);
    })();
}

Maintenant, si votre fichier est src.js, l'exécution node src.jslancera le nœud, chargera le fichier, lancera une REPL et copiera tous les objets déclarés comme varau niveau supérieur ainsi que tous les globaux exportés. Le if (require.main === module)garantit que ce code ne sera pas exécuté s'il src.jsest inclus via une requireinstruction. En fait, vous pouvez ajouter n'importe quel code que vous souhaitez exécuter lorsque vous exécutez de manière src.jsautonome à des fins de débogage dans l' ifinstruction.

user1936097
la source
4

Voici une version de fonction bash de la réponse de George :

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

Si vous mettez ceci dans votre, ~/.bash_profilevous pouvez l'utiliser comme un alias, c'est-à-dire:

noderepl foo.js
Eliot
la source
2
Je l'utilise depuis des mois maintenant, et lors d'une transition vers un nouvel environnement shell, j'ai perdu certains de mes paramètres et j'ai dû le retrouver à nouveau. Donc depuis que je suis là, j'ai pensé vous remercier pour cette fonction vraiment utile.
Xaekai
3

Une autre suggestion que je ne vois pas ici: essayez ce petit bout de code

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

Ensuite, vous pouvez simplement exécuter ce script et il inclura foocomme variable

corvidé
la source
1

Ancienne réponse

type test.js|node -i

Ouvre le nœud REPL et saisit toutes les lignes de test.js dans REPL, mais pour une raison quelconque, le nœud se fermera après la fin du fichier

Un autre problème est que les fonctions ne seront pas hissées.

Meilleure réponse

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

Ensuite, tous les globaux déclarés sans var dans test2.js seront disponibles dans le REPL

Je ne sais pas pourquoi var a dans la portée globale ne sera pas disponible

Juif
la source
8
Veuillez ajouter quelques explications à votre réponse
mechnicov