如何将我的脚本加载到node.js REPL中?

时间:2011-12-08 01:38:38

标签: javascript node.js read-eval-print-loop

我有一个脚本foo.js,其中包含我想在REPL中使用的一些函数。

有没有办法让节点执行我的脚本,然后跳转到包含所有声明的全局变量的REPL,就像我可以使用python -i foo.pyghci foo.hs一样?

12 个答案:

答案 0 :(得分:152)

仍然没有任何内置功能可以提供您描述的确切功能。但是,可以使用require替代它来使用REPL中的.load command,例如:

.load foo.js

它逐行加载文件,就像您在REPL中键入它一样。与require不同,这会使用您加载的命令污染REPL历史记录。但是,它具有可重复性的优点,因为它不像require那样缓存。

哪个更适合您将取决于您的使用案例。


编辑它的适用性有限,因为它不能在严格模式下工作,但三年后我了解到如果你的脚本没有'use strict',你可以{{3没有污染REPL历史记录:

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

答案 1 :(得分:21)

我总是使用这个命令

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

与没有任何软件包的Python完全一样。

答案 2 :(得分:8)

我制作了Vorpal.js,它通过将您的节点添加到交互式CLI来处理此问题。它支持REPL扩展,在您运行的应用程序的上下文中将其转换为REPL。

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

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

然后您可以运行该应用程序,它将进入REPL。

$ node myapp.js repl
myapp> repl: 

答案 3 :(得分:7)

我创建replpad,因为我厌倦了重复重新加载脚本。

只需通过以下方式安装:npm install -g replpad

然后运行:replpad

使用它

如果您希望它在当前和所有子目录中观看所有文件,并在更改时将它们传递到repl中:replpad .

查看网站上的视频,以便更好地了解它的工作原理,并了解其中包含的其他一些不错的功能:

  • 通过添加到每个核心功能的dox()函数访问repl 中的核心模块文档,即fs.readdir.dox()
  • 通过添加到通过npm安装的每个模块的dox()函数访问repl中的用户模块自述文件, 即marked.dox()
  • 访问功能的突出显示的源代码其中定义了功能的信息(文件,编号)和功能 评论和/或 jsdocs 尽可能通过添加到每个功能的src属性,即express.logger.src
  • scriptie-talkie支持(请参阅.talk命令)
  • 添加命令和键盘快捷键
  • vim键绑定
  • 键映射支持
  • 匹配的匹配令牌插件
  • 通过键盘快捷键或.append命令
  • 将在repl中输入的代码追加回文件

答案 4 :(得分:7)

另一种方法是将这些功能定义为全局。

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

然后在REPL中预加载文件:

node -r ./file.js

然后可以直接在REPL中访问函数helloWorld

答案 5 :(得分:4)

目前你不能直接这样做,但你可以在REPL中mylib = require('./foo.js')。记住导出方法,而不是声明为全局变量。

答案 6 :(得分:4)

replpad很酷,但是为了快速简便地将文件加载到节点中,导入其变量并启动repl,您可以将以下代码添加到.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]);
    })();
}

现在,如果您的文件是src.js,则运行node src.js将启动节点,加载文件,启动REPL,并将所有声明为var的对象复制到顶层作为任何导出的全局变量。 if (require.main === module)确保在src.js语句中包含require时不会执行此代码。事实上,当您在src.js语句中运行if独立以进行调试时,您可以添加任何您想要执行的代码。

答案 7 :(得分:4)

为什么不将文件加载到交互式节点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

然后你可以添加到package.json脚本

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

使用节点v8.1.2进行测试

答案 8 :(得分:3)

另一个我没有在这里看到的建议:尝试这一点代码

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

然后你可以简单地运行这个脚本,它将包含foo作为变量

答案 9 :(得分:3)

这是一个bash函数版本 George's answer

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

如果你把它放在你的~/.bash_profile中,你可以像别名一样使用它,即:

noderepl foo.js

答案 10 :(得分:1)

旧答案

type test.js|node -i

将打开节点REPL并将test.js的所有行键入REPL,但是由于某种原因,节点将在文件结束后退出

另一个问题是,将不会提升功能。

更好的答案

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

然后在test2.js中声明为不带var的所有全局变量将在REPL中提供

不确定为什么全局范围内的var a不可用

答案 11 :(得分:0)

有一个官方的 Node.js REPL 也支持异步方法

console.js

const repl = require('repl')
const mongoose = require('mongoose')

const run = async () => {
    await mongoose.connect(process.env.DB_URL, {
        useNewUrlParser: true,
        useUnifiedTopology: true
    })

    const r = repl.start(`(${process.env.NODE_EN}) ⚡️ `)
    r.context.User = require('./src/models/user.model')
    r.context.mongoose = mongoose
    console.log(`Ready ?`);
}

run()

启动控制台:

NODE_OPTIONS=--experimental-repl-await node console.js

User 模型暴露在控制台

await User.find({})

source