简体   繁体   English

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

[英]How do I load my script into the node.js REPL?

I have a script foo.js that contains some functions I want to play with in the REPL.我有一个脚本foo.js ,其中包含我想在 REPL 中使用的一些函数。

Is there a way to have node execute my script and then jump into a REPL with all the declared globals, like I can with python -i foo.py or ghci foo.hs ?有没有办法让节点执行我的脚本,然后使用所有声明的全局变量跳转到 REPL,就像我可以使用python -i foo.pyghci foo.hs

There is still nothing built-in to provide the exact functionality you describe.仍然没有任何内置功能可以提供您描述的确切功能。 However, an alternative to using require it to use the.load command within the REPL, like such:但是,使用的替代方法require它在 REPL 中使用.load命令,例如:

.load foo.js

It loads the file in line by line just as if you had typed it in the REPL.它逐行加载文件,就像您在 REPL 中键入它一样。 Unlike require this pollutes the REPL history with the commands you loaded.require不同,这会使用您加载的命令污染 REPL 历史记录。 However, it has the advantage of being repeatable because it is not cached like require .但是,它具有可重复的优点,因为它不像require那样被缓存。

Which is better for you will depend on your use case.哪个更适合您将取决于您的用例。


Edit: It has limited applicability because it does not work in strict mode, but three years later I have learned that if your script does not have 'use strict' , you can use eval to load your script without polluting the REPL history:编辑:它的适用性有限,因为它不能在严格模式下工作,但三年后我了解到,如果您的脚本没有'use strict' ,您可以使用eval加载您的脚本而不会污染 REPL 历史记录:

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

i always use this command我总是使用这个命令

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

works exactly as in Python without any packages.与 Python 完全一样,没有任何包。

I made Vorpal.js , which handles this problem by turning your node add into an interactive CLI.我制作了Vorpal.js ,它通过将您的节点添加到交互式 CLI 来处理这个问题。 It supports a REPL extension, which drops you into a REPL within the context of your running app.它支持 REPL 扩展,可将您带入正在运行的应用程序上下文中的 REPL。

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

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

Then you can run the app and it will drop into a REPL.然后你可以运行应用程序,它会进入一个 REPL。

$ node myapp.js repl
myapp> repl: 

Another way is to define those functions as global.另一种方法是将这些函数定义为全局函数。

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

Then preload the file in the REPL as:然后将 REPL 中的文件预加载为:

node -r ./file.js

Then the function helloWorld can be accessed directly in the REPL.然后可以在 REPL 中直接访问helloWorld函数。

I created replpad since I got tired of reloading the script repeatedly.我创建了replpad,因为我厌倦了反复重新加载脚本。

Simply install it via: npm install -g replpad只需通过以下方式npm install -g replpadnpm install -g replpad

Then use it by running: replpad然后通过运行使用它: replpad

If you want it to watch all files in the current and all subdirectories and pipe them into the repl when they change do: replpad .如果您希望它查看当前和所有子目录中的所有文件,并在它们更改时将它们通过管道replpad .到 repl 中,请执行: replpad .

Check out the videos on the site to get a better idea of how it works and learn about some other nice features that it has like these:查看网站上的视频,以更好地了解它的工作原理,并了解它具有的其他一些不错的功能,例如:

  • access core module docs in the repl via the dox() function that is added to every core function, ie fs.readdir.dox()经由在repl访问核心模块文档dox()函数被添加到每一个核心功能,即fs.readdir.dox()
  • access user module readmes in the repl via the dox() function that is added to every module installed via npm, ie marked.dox()经由在repl访问用户模块自述dox()函数被添加到通过NPM安装在每个模块,即marked.dox()
  • access function's highlighted source code , info on where function was defined (file, linenumber) and function comments and/or jsdocs where possible via the src property that is added to every function, ie express.logger.src通过添加到每个函数的src属性(即express.logger.src )访问函数的突出显示的源代码、有关函数定义位置的信息(文件、行号)和函数注释和/或jsdocs(如果可能)
  • scriptie-talkie support (see .talk command) scriptie-talkie支持(请参阅.talk命令)
  • adds commands and keyboard shortcuts添加命令和键盘快捷键
  • vim key bindings vim 键绑定
  • key map support关键地图支持
  • parens matching via match token plugin通过匹配令牌插件匹配括号
  • appends code entered in repl back to file via keyboard shortcut or .append command通过键盘快捷键或.append命令将在 repl 中输入的代码附加回文件

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

Why not load the file into an interactive node repl?为什么不将文件加载到交互式节点 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

Then you can add to package.json scripts然后你可以添加到 package.json 脚本

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

tested using node v8.1.2使用节点 v8.1.2 测试

Here's a bash function version of George's answer :这是乔治回答的 bash 函数版本:

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

If you put this in your ~/.bash_profile you can use it like an alias, ie:如果你把它放在你的~/.bash_profile你可以像别名一样使用它,即:

noderepl foo.js

Currently you can't do that directly, but you can mylib = require('./foo.js') in the REPL.目前你不能直接这样做,但你可以在 REPL 中mylib = require('./foo.js') Remember methods are exported, not declared as globals.记住方法是导出的,而不是声明为全局变量。

replpad is cool, but for a quick and easy way to load a file into node, import its variables and start a repl, you can add the following code to the end of your .js file replpad很酷,但是为了快速简便地将文件加载到 node、导入其变量并启动 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]);
    })();
}

Now if your file is src.js , running node src.js will start node, load the file, start a REPL, and copy all the objects declared as var at the top level as well as any exported globals.现在,如果您的文件是src.js ,则运行node src.js将启动 node、加载文件、启动 REPL,并复制在顶层声明为var所有对象以及任何导出的全局变量。 The if (require.main === module) ensures that this code will not be executed if src.js is included through a require statement. if (require.main === module)确保在通过require语句包含src.js时不会执行此代码。 I fact, you can add any code you want to be excuted when you are running src.js standalone for debugging purposes inside the if statement.事实上,你可以在if语句中添加任何你想要在运行src.js时执行调试的代码。

Another suggestion that I do not see here: try this little bit of 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

Then you can simply run this script and it will include foo as a variable然后你可以简单地运行这个脚本,它会包含foo作为一个变量

Old answer旧答案

type test.js|node -i

Will open the node REPL and type in all lines from test.js into REPL, but for some reason node will quit after file ends将打开节点 REPL 并将 test.js 中的所有行输入到 REPL 中,但由于某种原因节点将在文件结束后退出

Another problem is, that functions will not be hoisted.另一个问题是,函数不会被提升。

Better answer更好的答案

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

Then all globals declared without var within test2.js will be available in the REPL然后所有在 test2.js 中没有 var 声明的全局变量将在 REPL 中可用

not sure why var a in global scope will not be available不确定为什么全局范围内的 var a 将不可用

There is an Official Node.js REPL that supports also async methods有一个官方的 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()

Start the console:启动控制台:

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

User model its exposed to console暴露给控制台的User模型

await User.find({})

source 来源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM