Como carrego meu script no node.js REPL?

137

Eu tenho um script foo.jsque contém algumas funções que eu quero jogar no REPL.

Existe uma maneira de o nó executar o meu script e depois saltar para um REPL com todas as globais declaradas, como eu posso com python -i foo.pyou ghci foo.hs?

hugomg
fonte

Respostas:

179

Ainda não há nada incorporado para fornecer a funcionalidade exata que você descreve. No entanto, uma alternativa para usá- requirelo para usar o .loadcomando no REPL, como:

.load foo.js

Carrega o arquivo linha por linha, como se você o tivesse digitado no REPL. Diferente requiredisso, polui o histórico do REPL com os comandos que você carregou. No entanto, tem a vantagem de ser repetível porque não é armazenado em cache comorequire .

O que é melhor para você dependerá do seu caso de uso.


Edit: Ele tem aplicabilidade limitada, porque ele não funciona no modo estrito, mas três anos depois eu aprendi que se o seu script não tem 'use strict', você pode usar evalpara carregar seu script sem poluir a história REPL:

var fs = require('fs');
eval(fs.readFileSync('foo.js').toString())
vossad01
fonte
E se eu quiser inserir o repl dentro de um retorno de chamada assíncrona?
Chet
2
@Chet Você escreve-se uma nova pergunta StackOverflow se a sua pergunta não corresponde uma já existente :-)
vossad01
@Chet, você pode carregar outro arquivo com (async () => {more code}) (); e compartilhará os mesmos globais.
Nurettin
Dica se você estiver no macOS (talvez outros também). Você pode digitar ".load" (observe o espaço) no REPL e arrastar / soltar o arquivo no Terminal no Finder para adicionar o caminho correto ao seu comando. Isso é útil se os arquivos com os quais você estiver trabalhando estiverem vários níveis abaixo.
Jamesnotjim
35

eu sempre uso esse comando

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

funciona exatamente como no Python sem nenhum pacote.

George Shalvashvili
fonte
1
alguém sabe como fazer isso funcionar no Windows cmd? Eu consegui trabalhar no bash, mas não no windows.
Sharpiro
@ Sharpiro: Se você instalar o Git, terá a opção de instalar um mini-UNIX no seu PC com Windows. Quero dizer a distribuição normal do Git para Windows.
Juan Lanus
A única coisa que é irritante sobre isso é Node.js irá imprimir o repl rápida e , em seguida, executar o script, portanto, qualquer saída fica preso após o prompt. O stackoverflow.com/a/45893494/3538165 não tem esse problema, mas para essa solução, as funções devem ser atribuídas explicitamente às variáveis ​​para terminar no espaço de nomes de substituição, portanto, também não é muito bom.
Radon Rosborough
10

Eu criei o Vorpal.js , que lida com esse problema, transformando o seu nó em uma CLI interativa. Ele suporta uma extensão REPL, que o leva a um REPL dentro do contexto do seu aplicativo em execução.

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

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

Em seguida, você pode executar o aplicativo e ele cairá em um REPL.

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

Outra maneira é definir essas funções como globais.

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

Em seguida, pré-carregue o arquivo no REPL como:

node -r ./file.js

Em seguida, a função helloWorldpode ser acessada diretamente no REPL.

Ashish Chaudhary
fonte
8

Criei o replpad desde que me cansei de recarregar o script repetidamente.

Basta instalá-lo via: npm install -g replpad

Em seguida, use-o executando: replpad

Se você deseja que ele assista todos os arquivos nos subdiretórios atual e todos e inclua-os na repl quando eles mudarem: replpad .

Confira os vídeos no site para ter uma idéia melhor de como funciona e aprenda sobre alguns outros recursos interessantes que possui:

  • acessar documentos do módulo principal na repl por meio da dox()função que é adicionada a todas as funções principais, ou seja,fs.readdir.dox()
  • acessar readmes do módulo do usuário na repl através dodox() função que é adicionada a todos os módulos instalados via npm, ou seja,marked.dox()
  • acessar o código-fonte destacado da função , informações sobre onde a função foi definida (arquivo, número da roupa) e comentários da função e / ou jsdocs, sempre que possível, através da srcpropriedade adicionada a cada função, por exemploexpress.logger.src
  • scriptie-talkie apoio (ver.talkcomando)
  • adiciona comandos e atalhos de teclado
  • ligações de teclas do vim
  • suporte de mapa chave
  • parens correspondentes via plugin de token de correspondência
  • acrescenta o código digitado em repl ao arquivo via atalho ou .appendcomando do teclado

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

Thorsten Lorenz
fonte
Eu tive que CXX=clang++ npm install replpadtrabalhar em torno o errog++: error: unrecognized command line option '-stdlib=libc++'
ShadSterling
Mas então, quando eu executá-lo falhar com# # Fatal error in ../deps/v8/src/api.cc, line 1248 # Check failed: !value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(). # Illegal instruction: 4
ShadSterling
5

Por que não carregar o arquivo em uma repl de nó interativo?

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

Em seguida, você pode adicionar aos scripts package.json

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

testado usando o nó v8.1.2

lfender6445
fonte
2
por que não apenas node -i -r "./build/main/index.js"?
Z. Khullah
4

Atualmente, você não pode fazer isso diretamente, mas mylib = require('./foo.js')no REPL. Lembre-se de que os métodos são exportados, não declarados como globais.

Ricardo Tomasi
fonte
Acho isso preferível .load my_work.js, apesar de exigir algumas exports.working_var = ...declarações adicionais , porque o REPL vomita em alguns tipos de javascript perfeitamente válidos, como comentários de várias linhas (pelo menos com a minha readlineconfiguração).
chbrown
4

replpad é legal, mas para uma maneira rápida e fácil de carregar um arquivo no nó, importar suas variáveis ​​e iniciar uma substituição, você pode adicionar o seguinte código ao final do seu arquivo .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]);
    })();
}

Agora, se o seu arquivo estiver src.js, a execução node src.jsiniciará o nó, carregará o arquivo, iniciará um REPL e copiará todos os objetos declarados varno nível superior, bem como quaisquer globais exportados. Os if (require.main === module)garante que este código não será executado se src.jsestá incluído através de um requirecomunicado. Na verdade, você pode adicionar qualquer código que você deseja que seja excedido quando estiver executando o src.jsautônomo para fins de depuração dentro da ifinstrução.

user1936097
fonte
4

Aqui está uma versão da função bash da resposta de George :

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

Se você colocar isso no seu, ~/.bash_profilepoderá usá-lo como um pseudônimo, ou seja:

noderepl foo.js
Eliot
fonte
2
Estou usando isso há meses e, em uma transição para um novo ambiente de shell, perdi algumas das minhas configurações e tive que rastrear isso novamente. Então, como estou aqui, pensei em agradecer por essa função realmente útil.
Xaekai 19/02/19
3

Outra sugestão que não vejo aqui: experimente este pouco de 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

Então você pode simplesmente executar este script e ele incluirá foocomo uma variável

Corvid
fonte
1

Resposta antiga

type test.js|node -i

Irá abrir o nó REPL e digitar todas as linhas de test.js no REPL, mas por alguma razão o nó será encerrado após o término do arquivo

Outro problema é que as funções não serão içadas.

Melhor resposta

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

Em seguida, todas as globais declaradas sem var no test2.js estarão disponíveis no REPL

não sei por que var a no escopo global não estará disponível

judeu
fonte
8
Por favor, adicione algumas explicações à sua resposta
mechnicov 25/03/19