我有一个脚本foo.js
,其中包含我想在REPL中使用的一些函数。
有没有办法让节点执行我的脚本,然后跳转到包含所有声明的全局变量的REPL,就像我可以使用python -i foo.py
或ghci foo.hs
?
仍然没有任何内置功能可以提供您描述的确切功能。但是,使用require
替代它在REPL中使用.load
command,如下所示:
.load foo.js
它逐行加载文件,就像您在REPL中键入它一样。与require
不同,这会使用您加载的命令污染REPL历史记录。但是,它具有可重复性的优点,因为它不像require
那样缓存。
哪个更好,取决于您的使用案例。
编辑:它的适用性有限,因为它不能在严格模式下工作,但三年后我了解到,如果你的脚本没有'use strict'
,你可以在不污染REPL历史的情况下使用use eval
to load your script:
var fs = require('fs');
eval(fs.readFileSync('foo.js').toString())
这是George's answer的bash函数版本:
noderepl() {
FILE_CONTENTS="$(< $1 )"
node -i -e "$FILE_CONTENTS"
}
如果你把它放在你的~/.bash_profile
中,你可以像使用它一样使用它,即:
noderepl foo.js
老答案
type test.js|node -i
将打开节点REPL并输入从test.js到REPL的所有行,但由于某种原因,节点将在文件结束后退出
另一个问题是,功能不会被提升。
node -e require('repl').start({useGlobal:true}); -r ./test2.js
然后在REPL中可以使用在test2.js中声明没有var的所有全局变量
不确定为什么全局范围内的var a将不可用
我总是使用这个命令
node -i -e "$(< yourScript.js)"
与没有任何软件包的Python完全一样。
我创建了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:
我创建了replpad,因为我厌倦了重复重新加载脚本。
只需通过以下方式安装:npm install -g replpad
然后运行:replpad
使用它
如果你想让它观察当前和所有子目录中的所有文件,并在它们改变时将它们传递给repl:replpad .
查看网站上的视频,以更好地了解它的工作原理,并了解其中一些其他不错的功能:
dox()
函数访问repl中的核心模块文档,即fs.readdir.dox()
dox()
函数访问repl中的用户模块自述文件,该函数添加到通过npm安装的每个模块,即marked.dox()
src
属性,即express.logger.src
.talk
命令).append
命令将在repl中输入的代码追加回文件另一种方法是将这些功能定义为全局。
global.helloWorld = function() { console.log("Hello World"); }
然后在REPL中预加载文件:
node -r ./file.js
然后可以在REPL中直接访问函数helloWorld
。
目前你不能直接这样做,但你可以在REPL中使用mylib = require('./foo.js')
。记住导出方法,而不是声明为全局变量。
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
standalone以进行调试时,您可以添加任何您想要执行的代码。
为什么不将文件加载到交互式节点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进行测试
另一个我没有在这里看到的建议:尝试这一点代码
#!/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
作为变量