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

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

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

65860 次浏览

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

仍然没有内置的功能来提供您所描述的确切功能。然而,在 REPL 中使用 require来使用 .load命令的一种替代方法,如下所示:

.load foo.js

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

哪种方式对您更好取决于您的用例。


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

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

我创建了 替换垫,因为我厌倦了反复重新加载脚本。

只需通过: npm install -g replpad安装即可

然后通过运行 replpad来使用它

如果您希望它监视当前目录和所有子目录中的所有文件,并在它们发生变化时将它们导入 repl,请执行以下操作: replpad .

查看网站上的视频,可以更好地了解它是如何工作的,并学习一些其他好的功能,比如:

  • 通过添加到每个核心函数(即 fs.readdir.dox())的 dox()函数访问 repl 中的 core 模块文档
  • Access user module 通过 dox()函数在 repl 中自述,dox()函数通过 npm 添加到安装的每个模块中, 即 marked.dox()
  • 访问函数的 突出显示的源代码,关于 定义函数的地方的信息(文件,行号)和函数 注释和/或 Jsdocs,如果可能的话,通过添加到每个函数中的 src属性,即 express.logger.src
  • Scriptie-talkie support (请参阅 .talk命令)
  • 添加命令和键盘快捷键
  • Vim 键绑定
  • 键映射支持键映射支持
  • 括号匹配 via match token plugin
  • 通过快捷键或 .append命令将在 repl 中输入的代码追加到文件

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

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的所有对象以及任何导出的全局对象。 如果通过 require语句包含 src.js,则 if (require.main === module)确保不执行此代码。事实上,在 if语句中为了调试目的而独立运行 src.js时,您可以添加任何希望被执行的代码。

我制作了 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:

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

#!/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作为一个变量

为什么不将文件加载到交互式节点回复中?

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进行测试

我总是用这个命令

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

在没有任何包的情况下,其工作方式与 Python 完全相同。

另一种方法是将这些函数定义为全局函数。

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

然后在 REPL 中预加载文件,如下所示:

node -r ./file.js

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

旧答案

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 不可用

还有一个 OfficeNode.jsREPL也支持异步方法

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({})

来源